Vue2中的一些小知识点
Vue2文件结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ├── node_modules ├── public │ ├── favicon.ico:页签图标 │ └── index.html:主页面 ├── src │ ├── assets:存放静态资源 │ │ └── logo.png │ ├── component:存放组件 │ │ └── HelloWorld.vue │ ├── App.vue:汇总所有组件 │ └── main.js:入口文件 ├── .gitignore:git版本管制忽略的配置 ├── babel.config.js:babel的配置文件 ├── package.json:应用包配置文件 ├── REMDME.md:应用描述文件 └── package-lock.json:包版本控制文件
|
1.render函数
在Vue.js中, render 函数主要有以下作用:
- 编程式创建虚拟DOM - 相比模板语法,render函数给予开发者完全的JavaScript编程能力
- 更灵活的动态渲染 - 特别适合需要根据运行时条件动态生成大量内容的场景
- 模板编译替代方案 - 当不使用.vue单文件组件时,可直接用render函数替代模板编译
适用场景:
- 需要根据动态参数创建复杂组件结构时
- 需要实现高级抽象组件时
- 需要直接操作虚拟DOM时
- 需要配合JSX语法开发时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| // 以下两种写法等效 <script> import HelloWorld from './components/HelloWorld.vue'
export default { name: 'App', components: { HelloWorld }, render(h) { return h('div', { attrs: { id: 'app' } }, [ h('img', { attrs: { alt: 'Vue logo', src: require('./assets/logo.png') } }), h(HelloWorld, { props: { msg: 'Welcome to Your Vue.js App' } }) ]) } } </script>
<style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> /***************************************************************/ <template> <div id="app"> <img alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App"/> </div> </template>
<script> import HelloWorld from './components/HelloWorld.vue'
export default { name: 'App', components: { HelloWorld } } </script>
<style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
|
2.ref 属性
被用来给元素或子组件注册引用信息(id的替代者)
应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
使用方式:
打标识:<h1 ref="xxx">......</h1> 或 <School ref="xxx"></School>
获取:this.$refs.xxx
获取到的值:<h1 ref="xxx">......</h1>获取到的是元素标签,<School ref="xxx"></School>获取倒票的是子组件实例对象 VueComponent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <template> <div> <h1 ref="component">{{ msg }}</h1> <Student ref="stu"></Student> <School ref="sch"></School> <button @click="showDOM">点我输出上方DOM元素</button> </div> </template>
<script> //导入组件 import Student from "./components/Student" import School from "./components/School"
export default { name: "App", //汇总所有的组件 components: { School ,Student }, data() { return { msg: "Hello Vue!", }; }, methods: { showDOM() { console.log("h1 msg",this.$refs.component) console.log("sch",this.$refs.sch) console.log("stu",this.$refs.stu) } } }
</script>
|

3.配置 props
功能:让组件接收外部传过来的数据
- 传递数据
<Demo name="xxx"/>
- 接收数据:
第一种方式(只接收)
props:['name']
第二种方式(限制类型):
props:{
name:Number
}
第三种方式(限制类型、限制必要性、指定默认值):
props:{
name:{
type:String, //类型
required:true, //必要性
default:'老王' //默认值
}
}
备注:props是只读的,Vue底层会检测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请赋值props的内容到data中一份,然后去修改data中的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| <template> <div> <Student :name="studentName" :gender="studentGender" :age="studentAge"/> <hr> <Student ref="fillStudentDataFromRef" /> <hr> <Student name="学生" gender="男" :age="19"/> <hr> </div> </template> <script> //导入组件 import Student from "./components/StudentProps" export default { name: "App", //汇总所有的组件 components: { Student }, data() { return { studentName: '', studentGender: '', studentAge: 0 }; }, created() { // 填充数据 this.fillStudentData() }, mounted() { this.fillStudentDataFromRef() }, methods: { fillStudentData() { // 随机生成学生信息 建议 this.studentName = '学生' + Math.floor(Math.random() * 100) this.studentGender = Math.random() < 0.5 ? '男' : '女' this.studentAge = 19 }, fillStudentDataFromRef() { // 填充数据 不建议 // Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. // Instead, use a data or computed property based on the prop's value. this.$refs.fillStudentDataFromRef.setStudentData({ name: '学生' + Math.floor(Math.random() * 100), gender: Math.random() < 0.5 ? '男' : '女', age: 19 })
} } } </script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| <template> <!-- 组件的交互--> <div> <h1>{{ msg }}</h1> <h2>学生姓名: {{ name }}</h2> <h2>学生性别: {{ gender }}</h2> <h2>学生年龄: {{ age + 1 }}</h2> </div> </template>
<script> //组件交互的代码 //export default school分别暴露 export default { name: 'Student', //开发者工具最终呈现的名字为School data() { return { msg: '学生信息',
} }, // props:['name','gender','age'], props: { name: { type: String, required: true, validator: (value) => value.length >= 2 // 添加姓名长度验证 }, gender: { type: String, required: true, validator: (value) => ['男', '女'].includes(value) // 性别枚举验证 }, age: { type: Number, required: true, validator: (value) => value > 0 && value < 150 // 年龄范围验证 } }, methods: { setStudentData(data) { // 通过方法接收父组件数据 if (typeof data === 'object') { this.name = data.name this.gender = data.gender this.age = data.age } } } }; </script>
|
4. mixin(混入)
功能:可以把多个组件公用的配置提取成一个混入对象
使用方式:
第一步定义混合,例如:
1 2 3 4 5
| { data(){......}, methods:{......} ...... }
|
第二部使用混入 ,例如:
1 2
| (1).全局混入:Vue.mixin(xxx) (2).局部混入:mixins:['xxx']
|
注意:不同组件中的mixin是相互独立的!
4.1 局部混入
App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <template> <div> <Student /> <hr> <School /> </div> </template>
<script> //导入组件 import Student from "./components/Student" import School from "./components/School"
export default { name: "App", //汇总所有的组件 components: { Student, School } } </script>
|
Student.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <template> <div @click="showInfo"> <h2>学生姓名:{{ name }}</h2> <h2>学生年龄:{{ age }}</h2> </div> </template>
<script>
import { infoMixin } from "@/info_mixin";
export default { name: 'Student', data(){ return { name:'panyue', age:21 } }, mixins:[infoMixin], }; </script>
|
School.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <template> <div @click="showInfo" class="demo"> <h2>学校名称:{{ name }}</h2> <h2>学校地址:{{ address }}</h2> </div> </template>
<style> .demo{ background: skyblue; } </style>
<script> import { infoMixin } from '@/info_mixin'; export default { name: 'School', data(){ return { name:'武汉科技大学', address: '武汉' } }, mixins: [infoMixin] }; </script>
|
infomixin.js
1 2 3 4 5 6 7
| export const infoMixin = { methods: { showInfo(){ alert(this.name); } } }
|

4.2 全局引入
App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <template> <div> <Student /> <hr> <School /> </div> </template> <script> //导入组件 import Student from "./components/Student" import School from "./components/School" export default { name: "App", //汇总所有的组件 components: { Student, School } } </script>
|
Student.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <template> <div @click="showInfo"> <h2>学生姓名:{{ name }}</h2> <h2>学生年龄:{{ age }}</h2> </div> </template>
<script>
export default { name: 'Student', data(){ return { name:'panyue', age:21 } }, }; </script>
|
School.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <template> <div @click="showInfo" class="demo"> <h2>学校名称:{{ name }}</h2> <h2>学校地址:{{ address }}</h2> </div> </template>
<style> .demo{ background: skyblue; } </style>
<script> export default { name: 'School', data(){ return { name:'武汉科技大学', address: '武汉' } }, }; </script>
|
infomixin.js
1 2 3 4 5 6 7
| export const infoMixin = { methods: { showInfo(){ alert(this.name); } } }
|
main.js
1 2 3 4 5 6 7 8
| import Vue from 'vue' import App from './App.vue' import {infoMixin} from './info_mixin' Vue.config.productionTip = false Vue.mixin(infoMixin) new Vue({ render: h => h(App), }).$mount('#app')
|

4. 3 mixin的优缺点
从上面的例子看来,使用mixin的好处多多,但是凡是都有两面性,这里总结几点优缺点供大家参考:
4.3.1 优点
- 提高代码复用性
- 无需传递状态
- 维护方便,只需要修改一个地方即可
4.3.2 缺点
- 命名冲突
- 滥用的话后期很难维护
- 不好追溯源,排查问题稍显麻烦
- 不能轻易的重复代码
代码地址:https://github.com/Jacobshash/vue_test/tree/master/src_mixin
5.Scoped样式
作用:让样式在局部生效,防止冲突。
写法:<style scoped>
1 2 3 4 5
| <style scoped> .sscope{ background: orangered; } </style>
|
代码地址:https://github.com/Jacobshash/vue_test/tree/master/src_scoped
6.插件
功能:用于增强Vue
本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
定义插件:
`export const myPlugins = {`
`install(Vue,a,b) {`
`}`
}
使用插件:Vue.use(myPlugins )
6.1 定义并使用插件
my_plugins.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import { infoMixin } from './info_mixin.js'
export const myPlugins = { install(Vue,a,b) {
Vue.filter('mySlice', function (value) { return value.slice(0, 4); })
Vue.directive('fbind', { bind(element, binding) { element.value = binding.value; }, inserted(element) { element.focus(); }, update(element, binding) { element.value = binding.value; } })
Vue.mixin(infoMixin)
Vue.prototype.myPlugins = function (x, y) { alert('myPlugins'+ x+ y+a+b); } } }
|
main.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import Vue from 'vue' import App from './App.vue'
import { myPlugins } from './my_plugins'
Vue.config.productionTip = false
Vue.use(myPlugins,"a","b")
new Vue({ render: h => h(App), }).$mount('#app')
|
代码地址:https://github.com/Jacobshash/vue_test/tree/master/src_plugin
7.插槽
8.自定义指令
9.路由管理
10.状态管理