前天大潘更新了12个常见的指令语法,如果这12个指令在开发中都不能满足你的要求,那么就来自己定义一个指令语法吧!
一. 局部自定义指令
1. 函数式
定义自定义指令用directives:{}
配置项,这里的配置项里面自定义的指令有两种形式:①函数形式 ②对象形式,这里我们先看函数形式,对象形式在 2.对象式 里面讲。
先来用函数式实现一个功能:用自定义指令实现,把data中的n放大十倍后放到标签里面:
(1)首先先来看一下怎么自定义一个指令:
代码语言:javascript复制const vm = new Vue({
el: '#root',
data: {},
directives: {
自定义指令名() {}, //这里用到了js的定义函数的简写
},
});
(2)再来看一下自定义的指令可以传入什么参数:
代码语言:javascript复制<body>
<div id="root">
<h1>当前的n值是:<span v-text="n"></span></h1>
<h1>放大10之后的n值是:<span v-big="n"></span></h1>
<button @click="n ">点我n加1</button>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: '#root',
data: {
n: 1,
},
directives: {
big(element, binding) {
console.log(element, binding);
},
},
});
</script>
</body>
打印element和binding:
打印结果
结论:element:被操作的真实DOM元素;binding:自定义指令和真实DOM元素的一个绑定,其中有一个很重要的属性:value
(3) 实现功能:
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<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" />
<title>自定义指令_函数式</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>当前的n值是:<span v-text="n"></span></h1>
<h1>放大10之后的n值是:<span v-big="n"></span></h1>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: '#root',
data: {
n: 1,
},
directives: {
big(element, binding) {
element.innerHTML = binding.value * 10; //拿到n的值乘以10交给绑定元素的html
},
},
});
</script>
</body>
</html>
页面显示
注意:
1. 自定义的指令操作的是真实的DOM;
2. 自定义指令不是靠返回值来实现功能的,要和计算属性做区分;
3. 自定义指令被调用的时间:①指令和元素第一次成果绑定的瞬间,②data中的值改变,模板重新渲染的时候(和methods类似) ,总之就是模板(M)渲染的时候就会调用。
2. 对象式
假如现在我们要实现一个功能:页面渲染时,让页面里的input框自动获取焦点
(1)尝试用自定义指令的函数式形式实现(剧透:实现不了):
代码语言:javascript复制<body>
<div id="root">
<h1>当前的n值是:<span v-text="n"></span></h1>
<h1>放大10倍之后的n值是:<span v-big="n"></span></h1>
<input type="text" :value="n" v-fbind:value="n" /><br /><br />
<button @click="n ">点我n加一</button>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: '#root',
data: {
n: 1,
},
directives: {
big(element, binding) {
element.innerHTML = binding.value * 10;
},
fbind(element, binding) {
element.focus();
},
},
});
</script>
</body>
结果:页面初始化的时候input框并没有获取焦点,而当点击按钮n加1的时候,input框才获取焦点
页面显示
原因:函数式自定义指令的调用时间只有当模板(V)渲染的时候才会调用,但是当指令与元素绑定的时候,页面上并没有加载元素(函数形式的自定义指令并没有inserted),故页面初始化的时候input并框没有获取焦点。但是修改n,模板重新渲染的时候,函数式自定义指令就被调用了,input即获得了焦点。
(2)故用函数式自定义指令实现不了这个功能,下面介绍对象式自定义指令实现该功能:
首先对象式自定义指令的形式及调用时机是:
代码语言:javascript复制自定义指令名: {
bind() {}, //指令与元素成功绑定时调用(一上来就调用)
inserted() {}, //指令所在元素被插入到页面的时候调用
update() {}, //指令所在模板被重新解析时调用
},
实现:
代码语言:javascript复制<body>
<div id="root">
<input type="text" :value="n" v-fbind="n" /><br /><br />
<button @click="n ">点我n加一</button>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: '#root',
data: {
n: 1,
},
directives: {
fbind: {
bind() {},
inserted(element, binding) {
element.focus();
},
update(element, binding) {
element.focus();
},
},
},
});
</script>
</body>
此处有焦点哦(截图的时候没截到焦点)
函数式自定义指令相当于只包含bind函数和update函数的对象式之定义指令。
注意: 对象中的键值对的键都是带引号的字符串, 这里的自定义指令的名字不带引号是因为这是一种简写形式,一般形式是:'自定义指令名字':function(){}
或者'自定义指令名字(){'bind':function(){},'inserted':function(){},'update'(){}}'
(当自定义的指令名字中出现“-”就不能再用简写形式,此时要给名字加上引号。)
二. 全局自定义指令:
看看对象式和函数式全局指令写法的区别
当指令比较复杂,需要有多个单词组成的时候,自定义指令的名字怎么命名(此时自定义指令定义的时候要加上引号:'fbind-number'):
自定义指令的命名规则
自定义指令总结:
一、定义语法:
(1) 局部指令:
new Vue({
directives:{'指令名':配置对象} 或 directives{'指令名':回调函数}
})
(2) 全局指令:
Vue.directive(''指令名',配置对象)
或Vue.directive('指令名',回调函数)
二、配置对象中常用的3个回调:
(1) bind:指令与元素成功绑定时调用。
(2) inserted:指令所在元素被插入页面时调用。
(3) update:指令所在模板结构被重新解析时调用。
三、备注:
1.指令定义时不加v-,但使用时要加v-;
2.指令名如果是多个单词,要使用kebab-case命名方式(此时在命名的时候要加上单引号: 'kebab-case'),不要用camelCase命名。
点击下方这个小框框关注公众号,点击阅读原文调转到12个常见的指令语法,转载请注明出处哦,谢谢!