Vue.directive自定义指令

3,031 阅读4分钟

什么是指令

指令 (Directives) 是带有 v- 前缀的特殊特性。指令特性的值预期是单个 JavaScript 表达式 (v-for 例外)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。

简单的讲就是: 指令是可以写在DOM元素的小命令,以v-为前缀,vue就能识别这是一个指令并保持语法的一致性。如果需要对HTML进行底层操作的话,这种方式是非常有用的。

Vue中常用指令

  • v-if
  • v-else
  • v-else-if
  • v-show
  • v-on
  • v-bind
  • v-for
  • v-model

如何使用指令

参数

v-example:arg="value"可以传参数(arg)

<a v-bind:href="url">...</a>
修饰符

v-example:arg.modifier="value"使用修饰符(modifier)

<form v-on:submit.prevent="onSubmit"></form>
缩写

Vue.js 为 v-bind 和 v-on 这两个最常用的指令,提供了特定简写

<!-- 完整语法 -->
<a v-bind:href="url">...</a>

<!-- 缩写 -->
<a :href="url">...</a>

了解自定义指令

除了核心功能默认内置的指令 ,Vue 也允许注册自定义指令

1.创建一个全局的自定义指令
Vue.directive('xiaopang', function (el, binding, vnode) {
    el.style = 'color:' + binding.value
})
2.使用自定义指令
<p v-xiaopang="color">这是个自定义的指令</p>
3.钩子函数的参数 (即 el、binding、vnode 和 oldVnode)
  • el:指令所绑定的元素,可以用来直接操作DOM。
  • binding:一个对象,包含指令的很多信息。
  • vnode:Vue编译生成的虚拟节点。
  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

除了el之外,其它参数都应该是只读的,切勿进行修改。

4.binding参数
  • name:指令名,不包括 v- 前缀
  • value:指令的绑定值
  • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用
  • expression:字符串形式的指令表达式
  • arg:传给指令的参数,可选。
  • modifiers:一个包含修饰符的对象
  • rawName:指令名及参数,包括 v- 前缀和参数
<p id="app" v-xiaopang:fontsize.foo.bar="{fontsize: '50', color: 'red'}">{{ num }}</p>
Vue.directive('xiaopang',function(el, binding, vnode){
    console.log("name:", binding.name)
    console.log("value:", binding.value)
    console.log("expression:", binding.expression)
    console.log("arg:", binding.arg)
    console.log("modifiers:", binding.modifiers)
    console.log("rawName:", binding.rawName)
    el.style.fontSize = binding.value.fontsize + 'px';
    el.style.color = binding.value.color;
})

var app = new Vue({
    el: '#app',
    data: {
        num: 10,
        color: 'green'
    },   
})
name: "xiaopang"
value: {color:"red",fontsize:"50"}
expression: "{fontsize: '50', color: 'red'}"
arg: "fontsize"
modifiers: {bar:true,foo:true}
rawName: "v-xiaopang:fontsize.foo.bar"
5. 自定义指令提供的生命周期(又叫钩子函数)
  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind:只调用一次,指令与元素解绑时调用。

五个钩子函数中bindupdate是最有用的

创建一个自定义指令

了解了自定义指令概念后,直接上代码:

Vue.directive('xiaopang',{
    bind: function (el, binding){//被绑定 
        el.style.color = “green”
    },
    inserted: function () {//绑定到节点
    },
    update: function () {//组件更新
    },
    componentUpdated: function () {//组件更新完成
    },
    unbind: function () {//解绑
    }
})

var app = new Vue({
    el: '#app',
    data: {
        num: 10
    },   
})

相对应的HTML就是:

 <p v-xiaopang>{{ num }}</p>

这样就可以了,但是还不够灵活。如果能接受参数以便后续更新它的表现或者进行复用的话就会更加灵活。

Vue.directive('xiaopang',{
    bind: function (el, binding){//被绑定 
        el.style.color = binding.value
    }
})

var app = new Vue({
    el: '#app',
    data: {
        num: 10,
        color: 'green'
    },   
})
 <p v-xiaopang="color">{{ num }}</p>

假设我们想要区分是字体颜色还是背景色,可以通过传递一个参数来实现:

Vue.directive('xiaopang',{
    bind: function (el, binding){//被绑定 
    const s = (binding.arg == 'color' ? 'color' : 'background');
        el.style[s] = binding.value
    }
})

var app = new Vue({
    el: '#app',
    data: {
        num: 10,
        color: 'green'   
    },   
})
 <p v-xiaopang:color="color">{{ num }}</p>

也可以使用多个值,像自带指令一样用:

 <p v-xiaopang="{fontsize: '50', color: 'red'}">{{ num }}</p>

然后这两个值将会在指令上同时生效:

Vue.directive('xiaopang',{
    bind: function (el, binding){//被绑定 
        el.style.fontSize = binding.value.fontsize + 'px'
        el.style.color = binding.value.color
    }
})

var app = new Vue({
    el: '#app',
    data: {
        num: 10,
    },   
})

以上都是很简单的代码来实现效果,在实际的开发中,你可以创建更高级灵活的自定义指令。