本章介绍:directive、mixin、extend、provide&inject这5个Vue的进阶构造属性。javascript
什么是指令?html
其实以前咱们就已经学习了指令,如:v-if
、v-for
,相似这些以 v- 开头的就是指令,而v-if
、v-for
这些属于内置指令,除此以外咱们还能够自定义指令。vue
全局自定义指令java
全局自定义指令:在全局做用域下自定义指令,同时这个指令也可以用于全局,即任何组件都可以使用这个全局指令。如要声明多个全局指令,屡次调用Vue.directive
node
// 声明全局指令,注意在全局做用域下
Vue.directive('x',directiveOptions)
// 使用全局指令,在任何组件中均可以使用 v-x
<myComponent v-x ></myComponent>
复制代码
局部自定义指令express
局部自定义指令:在某个组件Vue对象下进行声明,只能在该Vue组件的实例中使用。注意局部声明时的 directives。数组
// 声明局部指令
<script>
export default {
...
directives:{
"x":directiveOptions,
"y":directiveOptions
}
}
</script>
// 只能在该组件中使用局部指令
<template>
<div v-x v-y></div>
</template>
复制代码
directiveOptionside
在上面的声明中,咱们只是演示了指令的声明,并无研究如何赋予指令功能,而指令的功能是经过directiveOptions中的5个钩子函数来实现的。函数
v-
前缀v-on:click='sayhi'
,这个sayhi就是指令绑定值。update
和 componentUpdated
钩子中可用。不管值是否改变均可用。v-on:click='sayhi'
,这里'sayhi'
就是指令表达式。v-on:click='sayhi'
,这个click
就是传给指令的参数。v-my-directive.foo.bar
中,修饰符对象为 { foo: true, bar: true }
。使用directiveOptions完整声明一个指令学习
下面咱们经过一个小例子,来简单实现Vue内置指令v-on
的绑定事件的功能。
new Vue({
directives: {
"myOn": {
inserted: (el, info) => {
el.addEventListener(info.arg, info.value)
}
}
}
})
复制代码
指令的做用以及使用场景
Vue组件/实例的主要用于数据绑定、事件监听、DOM更新,而指令的做用主要是完成原生DOM操做。
当咱们须要重复屡次相同的原生DOM操做,或者是进行一些比较复杂的原生DOM操做时,能够借助指令来完成。
什么是mixins?
简单来讲就是“复制”。有时候咱们须要使用屡次相同的组件,这些组件的代码几乎同样,为了节省代码量,咱们能够将这些相同的部分提取出来,而后经过mixin组合到各自组件中。mixins中的操做会合并到其余Vue实例中后,看成一个总体运行:好比:mixin中没有某个变量,可是其它Vue实例中有,这种状况下并不会报错,因是先合并了才运行。
mixins的意义
mixins能够减小data、methods、钩子的重复使用。
mixins的使用
// 相同部分提取 log.js
export default {
data(){
return {
a:'a'
}
},
methods:{
hw:function(){ console.log('helloWorld') }
},
created:function(){
console.log('created')
}
}
复制代码
// 在组件中使用提取的部分 myComponent.vue
import log from './log.js'
export default {
// 这里是个数组,说明能够使用多个mixins
mixins:[log],
data(){
return {
b:'b'
}
}
}
// 此时,这组件就能够使用mixins中的 a数据 ,hw方法 ,created ,以及自身的 b数据
复制代码
mixins是智能合并的
相同data当前实例优先级更高,而相同的钩子函数则会把两边的操做都合并起来。
全局mixin
Vue.mixin({mixin对象})
复制代码
注意:全局mixin声明时没有s(mixin)。使用全局mixin后,全部的组件包括App.vue都会默认合并这个全局mixin,因此不建议使用全局mixin。
extends的做用
extends的做用和mixins同样,可是形式不一样。
extends的使用
1.局部extends的使用
// 声明扩展内容
const myVue = {}
// 使用
export default {
// 注意这里不是数组
extends:myVue,
data(){ return {} }
}
复制代码
全局extends的使用
// 全局声明
const myVue = Vue.extend({扩展内容})
// 继承式声明Vue实例
new myVue({vueOptions})
复制代码
extends与extends&mixins
extends声明的扩展内容还可以使用extends和mixins。
import log from './log.js' // mixin
const com1 = {}
const com2 = {
extends:com1,
mixins:[log]
}
复制代码
什么是provide和inject?
上级组件能够经过provide传递data与method,而下级组件能够经过inject获取上级组件传递的data与method。
provide和inject可以大范围传递data和methods
provide和inject的使用方法
// 上级组件
export default {
data(){
return { n:'n'}
},
methods:{
add(){
console.log('add')
}
},
provide(){
return {
n:this.n,
add:this.add
}
}
}
// 下级组件
// 咱们就能够在下级组件中,使用n与add
export default {
inject:['n','add']
}
复制代码
provide和inject使用细节
传递的data时,父组件把自身data的地址复制了一份传递了,子组件可以获取data的值,但若是想在子组件中修改父组件的某些data(简单类型如Number、String)是不容许的,由于咱们修改的只是复制的变量的值。可是咱们能够经过在子组件中调用父组件传递过里啊的method来修改父组件的data,由于传递过来的method内部关联的是父组件的data。
可是若是父组件provide的data是一个对象,因为上级组件复制的是一个地址,因此子组件访问的也是同一个对象,那么在子组件中是可以修改这个对象,进而影响到父组件的。不推荐传递一个provide一个对象,由于若是都使用这个方法,那么在组件较多的状况下很难肯定那个对象当前是出于什么状态。