封装vue指令

指令的定义一定要放到 new Vue({}) 代码之前,否则报错并且无效;
在注册指令的时候,不需要加上v- 这个前缀;
在dom元素上使用的时候,必须加上v- 前缀;


自定义指令钩子函数

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

bind:只调用一次,指令第一次绑定到元素时调用,在这里可以进行一次初始化设置;

inserted:被绑定元素插入父节点时调用;

update:在 bind 之后立即以初始值为参数第一次调用,之后每当绑定值变化时调用,参数为新值与旧值;

componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用;

unbind:只调用一次,指令与元素解绑时调用;

钩子函数的参数

el:指令所绑定的元素,可以用来直接操作 DOM ;
binding:一个对象,包含以下属性:
  name:指令名,不包括 v- 前缀;
  value:指令的绑定值,例如:v-my="2" 中,绑定值为 2;
  oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用;
  expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1";
  arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo";
  modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true };
  vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情;
  oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用;
Vue.directive('focus',{
  bind:function(){
    //这个指令的逻辑
    //可以利用this.el来获取到当前指令所在的元素对象
    this.el.style.color = 'red';
  }
});
////定义一个带有参数的自定义指令
    Vue.directive('color',{
        params:['colorname'],
        bind:function(){
            //1.0 获取到colorname的值
            var cname = this.params.colorname;

            //2.0 获取到el以后给其赋予一个样式
            this.el.style.color = cname;
        }
    });

    使用:
    <input type="text" v-model="productid"  v-color colorname="blue" > -----其实就是this.el.style.color = cname=colorname= “blue”,

定义组件内自定义指令

<template>
  <div class="hello">
      <div v-test='name'></div>
  </div>
</template>
<script>
export default {
  data () {
    return {
     name:'我是名字',
    }
  },
  directives:{
      test:{
        inserted: function (el, binding) {// 指令的定义
           / /el为绑定元素,可以对其进行dom操作
           console.log(binding) //一个对象,包含很多属性属性
        },
        bind: function (el, binding, vnode) {
            el.innerHTML =binding.value
          }
      }
  },
  created:function(){
  },
  mounted:function(){ 
  },
  methods:{
  }
}
</script>

定义全局自定义指令

<div id="box">
    hello<span v-red> welcome</span>
</div>
<script type="text/javascript">
    Vue.directive('red',{
        inserted:function(el){
            el.style.background = 'red';
        }
    });
    var vm = new Vue({
        data:{
        
        },
    }).$mount('#box'); 
</script>

实例

在图片未完成加载前,用随机的背景色占位,图片加载完成后才直接渲染出来。

<div id="app" >
  <div v-img='val.url'  v-for="val in list"></div>
</div>
<script type="text/javascript" src='https://i0.jrjimg.cn/zqt-red-1000/focus/focus2017YMZ/teamFrighting/js/vue.min.js'></script>

<script type="text/javascript">
  Vue.directive('img', {
    inserted:function (el, binding) {
      var color = Math.floor(Math.random()*1000000);
      el.style.backgroundColor = "#" + color; 

      var img = new Image();
      img.src = binding.value;
      img.onload = function(){
        el.style.backgroundImage = 'url('+ binding.value +')'
      }
    }
  });
  new Vue({
    el: '#app',
    data: {
      list:[
        {
          url:'http://i0.jrjimg.cn/zqt-red-1000/focus/focus2017YMZ/Billboard/img/tan04.jpg'
        },
        {
          url:'http://i0.jrjimg.cn/zqt-red-1000/focus/focus2017YMZ/Billboard/img/tan03.jpg'
        },
        {
          url:'http://i0.jrjimg.cn/zqt-red-1000/focus/focus2017YMZ/Billboard/img/tan04.jpg'
        }
      ]
    }
  });
</script>

原文:https://www.jianshu.com/p/dfdfb9e2b501

猜你喜欢

转载自www.cnblogs.com/xjy20170907/p/12667906.html