vue自定义指令-使用

193 阅读1分钟

1.定义

v-model 和 v-show 都是指令,vue推荐是使用数据驱动的方式改变dom,但在特殊场景,我们需要操作dom, 自定义指令就是一种有效的补充和扩展,不仅可用于定义任何的DOM操作,并且是可复用的。

2.声明范围

2.1全局

Vue.directive('focus',{
    inserted(el){
        el.focus()
    }
})

2.2局部

new Vue({
    el:"#app"
    directives:{
        focus:{
            inserted(el){
                el.focus()
            }
        }
    }
})

3.指令的生命周期与参数传递

<!DOCTYPE html>
<html  >
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
    <title>自定义指令</title>
</head>
<body>
   
    <div id="app">
        {{ message }}  
        <input v-if="isShow" v-focus:foo.a.b="focusVal" v-model="message"> 
         <!--<input v-if="isShow" v-focus="focusObjVal" v-model="message">-->
        <button type="button" @click="changeClick">改变内容</button> 
        <button type="button" @click="deleteClick">删除组件</button> 
      </div>
      
      <script type="text/javascript">
      var app = new Vue({ 
          el: '#app',
          data: {
              message: 'Hello Vue!',   
              focusVal: '1111',   //可以是个方法或者对象
              focusObjVal: { name : "张三", age : 18},   
              isShow: true
          },
          methods:{
            changeClick(){  
                this.message = "点击了"
            },
            deleteClick(){  
                this.isShow = false
            }
          },
          directives: {
            focus: {
                // 只调用一次,指令第一次绑定到元素时调用
                bind(el,binding,vnode,oldVnode){ 
                    console.log("name",binding.name) 
                    console.log("arg",binding.arg)
                    console.log("expression",binding.expression) //表达式
                    console.log("value",binding.value) //对应解析的内容
                    console.log("modifiers",binding.modifiers)   //这里是修饰符{a:true,b:true} 用于特殊逻辑判断,可以参考vue的click里的.stop .prevent
                },
                // 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)
                inserted: function (el,binding) {
                     console.log("inserted")
                     el.focus()
                },
                //被绑定元素所在的模板更新时调用,而不论绑定值是否变化。只有内容发生变化才触发。
                update(el,binding){ 
                    console.log("update") 
                    console.log("modifiers",binding.modifiers)  
                }, 
                //被绑定元素所在模板完成一次更新周期时调用。一般在update之后都会触发。
                componentUpdated(el,binding){ 
                    console.log("componentUpdated")
                },
                //只调用一次, 指令与元素解绑时调用。
                unbind(el,binding){ 
                    console.log("unbind")
                }
            }
        }
      });
      </script>
  
</body>
</html>

4.指令与外部数据交互

通过指定对象,把外部方法与指令内的方法进行绑定,使得指令内可以直接调用外部的方法,并且可以带入参数。

<!DOCTYPE html>
<html  >
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
    <title>自定义指令</title>
</head>
<body> 
        <div id="app">
        <div v-drag="{setVal:setValFn,showVal:showValFn,data: outData}">自定义指令</div>
        </div> 
      
      <script>
           var app = new Vue({
               el:"#app" ,

        data(){
            return {
                outData: 1,
                a: 2,
                b: 3
            } 
        },
        methods: {
            setValFn(val1,val2) {
                this.a = val1;
                this.b = val2;
            }, 
            showValFn() { 
                console.log("this.a",this.a)
                console.log("this.b",this.b)
            }
        },
        directives: {
          drag: {
            bind(el,binding) {
                var value1 = 11;
                var value2 = 22;
                binding.value.setVal(value1, value2); // 外部的data会接收到内部的value1和value2,执行方法setValFn();
                binding.value.showVal();
                console.log(binding.value.data) // 会得到外部传入的 outData : 1
            }
          }
        }
      })
      </script>
</body>
</html>