vue:vue中的directives指令

261 阅读2分钟

directives

vue官方文档 有一些内置指令:v-if, v-for, v-show, v-html等等

1. 指令的作用

  1. 主要用于DOM操作
  • vue实例/组件用于数据绑定、事件监听、dom更新
  • vue指令主要目的是原生dom操作
  1. 减少重复
  • 如果某个dom操作经常使用,可以封装为指令
  • 如果某个dom操作比较复杂,也可以封装为指令
  1. 位置 写在main.js里, new Vue()之前。

2. 指令用法

  • 自己造一个指令,v-x,要求点击出现x。
  • 可以造全局指令,也可以局部指令。

全局指令

语法:

Vue.directive('dirName',directiveOptions)
//main.js里
Vue.directive("x",{
    inserted: function (el){
        el.addEventListener("click",()=>{
            console.log("x")
        })
    }
})

// 在需要应用的地方

<img src="xxx" v-x>

局部指令

语法

new Vue({
  directives:{
    dirName:{
      directiveOptions
        
    }
  }
});
//在组件vue的export default里面写,再需要的地方加上V-X
export default{
    name:xxx,
    directives:{
        "x": {
            inserted(el){
                el.addEventListener('click', ()=>{console.log('xx'})
            }
        }
    }
}
// 只能在该实例里用v-x

3. directiveOptions

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

  • bind(el,binding,vnode,oldVnode):只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。类似于created

  • inserted(el,binding,vnode,oldVnode):被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。类似于mounted.

  • update(el,binding,vnode,oldVnode):所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。类似于updated.

  • componentUpdated(el,binding,vnode,oldVnode):指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind(el,binding,vnode,oldVnode):只调用一次,指令与元素解绑时调用。类似于destoryed. c7ELSf.png

这是一个使用了这些 property 的自定义钩子样例:
<div id="hook-arguments-example" v-demo:foo.a.b="message"></div>
Vue.directive('demo', {
  bind: function (el, binding, vnode) {
    var s = JSON.stringify
    el.innerHTML =
      'name: '       + s(binding.name) + '<br>' +
      'value: '      + s(binding.value) + '<br>' +
      'expression: ' + s(binding.expression) + '<br>' +
      'argument: '   + s(binding.arg) + '<br>' +
      'modifiers: '  + s(binding.modifiers) + '<br>' +
      'vnode keys: ' + Object.keys(vnode).join(', ')
  }
})

new Vue({
  el: '#hook-arguments-example',
  data: {
    message: 'hello!'
  }
})

c7V11K.png

参数定义

4. 自定义一个on指令

new Vue({
  directives: {
    on2: {
      // bind 可以改为 inserted
      bind(el, info) {
        el.addEventListener(info.arg, info.value);
        // Vue 自带的 v-on 并不是这样实现的,它更复杂,用了事件委托
      },
      unbind(el, info) {
        el.removeEventListener(info.arg, info.value);
      }
    }
  },
  template: `
    <button v-on2:click="hi">点我</button>
  `,
  methods: {
    hi() {
      console.log("hi");
    }
  }
}).$mount("#app");

5. 写一个自定义指令 v-y,做到点击元素就打印 'y'

codesandbox.io/s/delicate-… main.js

import Vue from "vue";
import App from "./App.vue";

Vue.config.productionTip = false;

Vue.directive("y", {
  inserted: function(el) {
    el.addEventListener("click", () => {
      console.log("y");
    });
  }
});

new Vue({
  render: h => h(App)
}).$mount("#app");

app.vue

<template>
  <div id="app">
    <button v-y>输出y</button>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld";

export default {
  name: "App",
  components: {
    HelloWorld
  }
};
</script>