Vue2--自定义指令

209 阅读2分钟

局部自定义指令

自定义指令--函数式写法

1、需求一:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍

2、实现:下面用函数式写法写一个自定义指令,函数式写法比较简单,但无法完成一些细节。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>自定义指令</title>
		<script type="text/javascript" src="./vue.js"></script>
		<script>Vue.config.productionTip=false </script>
	</head>
	<body>
		<!--准备好一个容器-->
		<div id="root">
			<h2>当前的n值是:<span v-text="n"></span> </h2>
			<h2>放大10倍的n值是:<span v-big="n"></span> </h2>
			<button @click="n++">点我n+1</button>
		</div>
	</body>
	
	<script type="text/javascript">
		const vm = new Vue({
			el:'#root',
			data:{
				n:1,
			},
			directives:{
				//big函数何时会被调用?1、指令与元素成功绑定时(一上来)。2、指令所在的模板被重新解析时(在这个例子中,无论我们修改的是name还是n都会调用big函数)。
				big(element,binding){ //big有两个参数,element代表span标签,binding代表绑定信息
					console.log('big')
					element.innerText = binding.value * 10
				},
			}
		})
	</script>
</html>

效果:

image.png

自定义指令--对象式

1、需求二:定义一个v-fbind指令,和v-bind指令功能类似,但可以让其所绑定的input元素默认获取焦点

2、实现:

先使用函数式尝试实现:

	<body>
		<!--准备好一个容器-->
		<div id="root">
			<h2>当前的n值是:<span v-text="n"></span> </h2>
			<h2>放大10倍的n值是:<span v-big="n"></span> </h2>
			<button @click="n++">点我n+1</button>
      <hr />
			<input type="text" v-fbind:value="n" />
		</div>
	</body>
	
	<script type="text/javascript">
		const vm = new Vue({
			el:'#root',
			data:{
				n:1,
			},
			directives:{
				//big函数何时会被调用?1、指令与元素成功绑定时(一上来)。2、指令所在的模板被重新解析时(在这个例子中,无论我们修改的是name还是n都会调用big函数)。
				big(element,binding){ //big有两个参数,element代表span标签,binding代表绑定信息
					console.log('big')
					element.innerText = binding.value * 10
				},
        fbind(element,binding){
          element.value = binding.value
          element.focus()
        }
			}
		})
	</script>

效果一:发现并没有聚焦

image.png

出错原因:fbind在指令与元素绑定成功时被调用,此时fbind并没有被放入页面,所以调用focus()函数没有效果;但如果点击输入框,vue发现输入框内容发生改变了然后重新解析模板就能聚焦了。

解决方法:在fbind放入页面时调用focus()方法

	<body>
		<!--准备好一个容器-->
		<div id="root">
			<h2>当前的n值是:<span v-text="n"></span> </h2>
			<h2>放大10倍的n值是:<span v-big="n"></span> </h2>
			<button @click="n++">点我n+1</button>
			<hr />
			<input type="text" v-fbind:value="n" />
		</div>
	</body>
	
	<script type="text/javascript">
		// 需求一:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍
		// 需求二:定义一个v-fbind指令,和v-bind指令功能类似,但可以让其所绑定的input元素默认获取焦点
		const vm = new Vue({
			el:'#root',
			data:{
				n:1,
			},
			directives:{
				//big函数何时会被调用?1、指令与元素成功绑定时(一上来)。2、指令所在的模板被重新解析时(在这个例子中,无论我们修改的是name还是n都会调用big函数)。
				big(element,binding){ //big有两个参数,element代表span标签,binding代表绑定信息
					console.log('big')
					element.innerText = binding.value * 10
				},
				fbind:{
					//指令所在元素成功绑定时(一上来)
					bind(element,binding){
						element.value = binding.value
					},
					//指令所在元素被插入页面时
					inserted(element,binding){
						element.focus()
					},
					//指令所在的模板被重新解析时
					update(element,binding){
						element.value = binding.value
					}
				}
			}
		})
	</script>

全局自定义指令

能在所有Vue中使用 案例:

	<body>
		<!--准备好一个容器-->
		<div id="root">
			<h2>当前的n值是:<span v-text="n"></span> </h2>
			<h2>放大10倍的n值是:<span v-big="n"></span> </h2>
			<button @click="n++">点我n+1</button>
			<hr />
			<input type="text" v-fbind:value="n" /> <br />
		</div>
    <div id="root2">
      <input type="text" v-fbind:value="sum" />
    </div>
	</body>
	
	<script type="text/javascript">
    // 全局自定义指令,注意,这里是directive,不加s
		Vue.directive('fbind',{
					//指令所在元素成功绑定时(一上来)
					bind(element,binding){
						element.value = binding.value
					},
					//指令所在元素被插入页面时
					inserted(element,binding){
						element.focus()
					},
					//指令所在的模板被重新解析时
					update(element,binding){
						element.value = binding.value
					}
		})
    const vm = new Vue({
			el:'#root',
			data:{
				n:1,
        sum:10,
			},
			directives:{
				//big函数何时会被调用?1、指令与元素成功绑定时(一上来)。2、指令所在的模板被重新解析时(在这个例子中,无论我们修改的是name还是n都会调用big函数)。
				big(element,binding){ //big有两个参数,element代表span标签,binding代表绑定信息
					console.log('big')
					element.innerText = binding.value * 10
				},
				
			}
		})
    new Vue({
      el:'#root2',
      data:{
        sum:10
      }
    })
	</script>

自定义指令注意事项

1、推荐写法: 如果指令有多个单词构成:

  • 在html中:

<span v-big-number="n">

  • 在script中:
'big-number':function(element,binding){
    功能xxx
}

2、注意:自定义指令中的this时window对象,不是Vue对象。

小结

1、定义语法:

(1)局部指令:

new Vue({
    directives:{指令名:配置对象}
})

new Vue({
    directives:{指令名:回调函数}
})

(2)全局指令:

Vue.directive(指令名,配置对象)

Vue.directive(指令名,回调函数)

2、配置对象中常用的3个回调:

(1)bind:指令与元素绑定时调用;

(2)inserted:指令所在元素被插入页面时调用;

(3)update:指令所在模板结构被重新解析时调用;

3、备注:

(1)指令定义时不加v-,但使用时需要加v-

(2)指令名如果时多个单词,要使用kebab-case命名方式,不要用camelCase命名。