vue的自定义指令解析

概念

    指令只是一种可以附加到DOM元素的微命令(tiny commands)。它们通常以 “v-” 作为前缀,以方便 Vue 知道你在使用一种特殊的标记,从而确保语法的一致性。 如果你需要对 HTML 元素的低级别 ( low-level ) 访问来控制一些行为,它们通常很有用

钩子函数

  • bind
        只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
  • inserted
        被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
  • update
        所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
  • componentUpdated
        指令所在组件的 VNode 及其子 VNode 全部更新后调用
  • unbind
        只调用一次,指令与元素解绑时调用
<body>
<div id="app">
    <input type="text" v-test>
</div>
<script src="vue.js"></script>
<script>
	// 注册全局自定义指令
	Vue.directive('test', {
		// 第一个钩子函数  bind 指令第一次绑定到元素上
        bind: function(el, binding) {
          console.log('bind')      // bind
        },
        // 第二个钩子函数  inserted 指令所在的元素插入到父节点
        inserted: function(el, binding) {
          console.log('inserted')    // inserted
        },
        // 第三个钩子函数 update 数据发生变化 
        update: function(el, binding) {
          console.log('update')
        },
        // 第四个钩子函数 componentUpdated 更新完毕
        componentUpdated: function(el, binding) {
          console.log('componentUpdated')
        },
        // 第五个钩子函数 unbind 解绑
        unbind: function(el, binding) {
          console.log('unbind')
        }
	})

	new Vue({
        el: '#app'
	})
</script>
</body>

参数

  1. el
      指令所绑定的元素,可以用来直接操作 DOM

  2. binding
      一个对象,包含以下属性:

      name: 指令名,不包括 v- 前缀

      value: 指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 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 }

   3. vnode
      Vue 编译生成的虚拟节点

  4. oldVnode
      上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用

注意

  • 除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行
  • 建议在给指令的命名时采用小驼峰式的命名方式,比如changeBackgroundColor,在使用的时候采用烤串式写法 v-change-background-color
<body>
<div id="app">
	<div class="txt" v-test:aaa.trim="100+2"></div>
</div>	
	
<script src="vue.js"></script>
<script>
	Vue.directive('test', {
		inserted: function(el, binding) {
			el.innerText  = binding.value
			
			console.log(el)                   // 绑定的元素: <div class="txt"></div>
	        console.log(binding.name)         // 指令名字: test
	        console.log(binding.value)        // 值: 102
	        console.log(binding.expression)   // 表达式: 100+2
	        console.log(binding.arg)          // 指令参数: aaa
	        console.log(binding.modifiers)    // 指令修饰符: {trim: true}
		}
	})
	new Vue({
		el: '#app'
	})
</script>
</body>

局部自定义指令

<body>
<div id="app">
	<div class="box">
		<input type="text" v-focus>
	</div>
</div>	
	
<script src="vue.js"></script>
<script>
	new Vue({
		el: '#app',
		data: {},
		directives: {
			focus: {
				// 当被绑定的元素插入到 DOM 中时……
				inserted: function(el, binding) {
					el.focus()       // 聚焦元素
				}
			}
		}
	})
</script>
</body>

全局自定义指令

<body>
<div id="app">
	<div class="box">
		<input type="text" v-focus>
	</div>
</div>	
	
<script src="vue.js"></script>
<script>
	Vue.directive('focus', {
  		// 当被绑定的元素插入到 DOM 中时……
  		inserted: function (el, binding) {
    		el.focus()    // 聚焦元素
  		}
	})
	
	new Vue({
		el: '#app'
	})
</script>
</body>

函数简写

  1. 值为对象字面量
<body>
<div id="app">
	<div class="txt" v-textcolor="{color: 'red'}">我的颜色是自定义指令更改的</div>
</div>	
	
<script src="vue.js"></script>
<script>
	Vue.directive('textcolor', function(el, binding) {
		el.style.color = binding.value.color
	})
	
	new Vue({
		el: '#app'
	})
</script>
</body>
  1. 值为表达式
<body>
<div id="app">
	<div class="txt" v-expresstion="100+2"></div>
	<div class="txt" v-isshow="false">我是隐藏的盒子</div>
	<div class="txt" v-addtext="text"></div>
</div>	
	
<script src="vue.js"></script>
<script>
	Vue.directive('expresstion', function(el, binding) {
		el.innerText = binding.value
	})
	
	Vue.directive('isshow', function(el, binding) {
		el.style.display = binding.value ? 'block':'none'
	})
	
	Vue.directive('addtext', function(el, binding) {
		el.innerText = binding.value
	})
	
	new Vue({
		el: '#app',
		data: {
			text: '哈哈,我是指令添加的'
		}
	})
</script>
</body>

小例子

<body>
<div id="app">
	<!-- 背景颜色 红色 字体颜色  黄色   v-color:fcolor="fColor" -->
    <input type="text" v-color:bgcolor="bgColor"  v-color:fcolor="fColor">
</div>
<script src="vue.js"></script>
<script>
	/**
	 * 自定义指令 
	 * 名称 : v-color
	 * 参数 : bgcolor(背景颜色)    fcolor(字体颜色)
	 */
	
	Vue.directive('color', {
		inserted(el, binding) {
		    // 背景颜色
		    if (binding.arg === 'bgcolor') {
		       el.style.background = binding.value
		    }
		    // 字体颜色
		    if ( binding.arg === 'fcolor') {
		    	el.style.color = binding.value
		    }
		}
	})

	new Vue({
        el: '#app',
        data: {
        	bgColor: 'red',
        	fColor: 'yellow'
        }
	})
</script>
</body>
  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半度℃温热

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值