Vue.js——自定义指令

自定义指令

1、注册自定义指令

Vue.js提供了可以注册自定义指令的方法,通过不同的方法可以注册全局自定义指令和局部自定义指令。下面分别进行介绍。

1.1、全局自定义指令

通过应用程序实例的directive()方法可以注册一个全局自定义指令。该方法可以接收两个参数:指令ID和定义对象。指令ID是指令的唯一标识,定义对象是定义的指令的钩子函数。

例如,注册一个全局自定义指令,通过该指令实现页面加载后输入框获得焦点时选中输入框的全部内容。示例代码如下:

html 复制代码
<div id="app">
    请输入内容:<input v-select>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
            }
        }
    });

    vm.directive('select', {
        //当被绑定的元素挂载到DOM中时执行
        mounted: function(el) {
            //元素获得焦点时内容全部选中
            el.onfocus = ()=> {
                el.select();
            }
        }
    });
    vm.mount('#app');
</script>

上述代码中,select是自定义指令ID,不包括v-前缀,mounted是指令定义对象中的钩子函数。该钩子函数表示,当被绑定元素挂载到DOM中且元素获得焦点时,选中元素的全部内容。在注册全局指令后,在被绑定元素中应用该指令即可实现相应的功能。

1.2、局部自定义指令

通过组件实例中的directives选项可以注册一个局部自定义指令。例如,注册一个局部自定义指令,通过该指令实现为元素添加样式的功能。示例代码如下:

html 复制代码
<style>
    .demo{
        width: 300px;
        height: 100px;
        line-height: 100px;
        text-align: center;
        background-color: gray;
        font-size: 30px;
        color: white;
        border: 3px solid blue;
    }
</style>
<div id="app">
    <div v-add-style="demo">
        坚持不懈
    </div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                demo: 'demo'
            }
        },
        directives: {
            addStyle: {
                mounted: function(el, binding) {
                    el.className = binding.value;
                }
            }
        }
    }).mount('#app');
</script>

上述代码中,在注册自定义指令时采用了小驼峰命名的方式,将自定义指令ID定义为addStyle,而在元素中应用指令时的写法为v-add-style。在为自定义指令命名时建议采用小驼峰命名的方式。

2、钩子函数

在注册指令的时候,可以传入定义对象,对指令赋予一些特殊的功能。一个指令定义对象可以提供的钩子函数如表所示。

钩子函数 说明
beforeMount 在指令第一次绑定到元素并且在挂载到DOM之前调用时,用这个钩子函数可以定义一个在绑定时执行一次的初始化设置
mounted 在被绑定元素挂载到DOM时调用
beforeUpdate 在指令所在组件的VNode更新之前调用
updated 在指令所在组件的VNode及其子组件的VNode全部更新后调用
beforeUnmount 在绑定元素的父组件卸载之前调用
unmounted 只调用一次,在指令从元素上解绑且父组件已卸载时调用

这些钩子函数都是可选的。每个钩子函数都可以传入el、binding和vnode三个参数,beforeUpdate和updated钩子函数还可以传入oldVnode参数。这些参数的说明如下:

  • el:指令所绑定的元素,可以用来直接操作DOM。
  • binding:一个对象,包含的属性如表所示。
  • vnode:Vue编译生成的虚拟节点。
  • oldVnode:上一个虚拟节点,仅在beforeUpdate和updated钩子函数中可用。
属性 说明
instance 使用指令的组件的实例
value 指令的绑定值,例如: v-my-directive="10",value的值是10
oldValue 指令绑定的前一个值,仅在beforeUpdate和updated钩子函数中可用。无论值是否改变都可用
dir 注册指令时作为参数传递的对象
arg 传给指令的参数。例如:v-mydirective:tag,arg的值是"tag"
modifiers 一个包含修饰符的对象。例如:v-my-directibe.tag.bar,修饰符对象modifiers的值是{tag:true, bar:true}

通过下面这个示例,可以更直观地了解钩子函数的参数和相关属性的使用。代码如下:

html 复制代码
<div id="app">
    <div v-demo:flag.m.n="message"></div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                message: '天才出于勤奋'
            }
        },
    });
    vm.directive('demo', {
        mounted: function(el, binding, vnode) {
            el.innerHTML = `instance:\t${JSON.stringify(binding.instance)}<br>
                            value:\t${binding.value}<br>
                            argument:\t${binding.arg}<br>
                            modifiers:\t${JSON.stringify(binding.modifiers)}<br>
                            vnode.keys:\t${Object.keys(vnode).join('.')}`
        }
    }); 
    vm.mount('#app');
</script>

示例:设置图片宽度。

在页面中定义一张图片和一个文本框,在文本框中输入表示图片宽度的数字,实现为图片设置宽度的功能。代码如下:

html 复制代码
<div id="app">
    图片宽度:<input type="text" v-model="width">
    <p>
        <img src="images/1.jpg" v-set-width="width">
    </p>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                width: ''
            }
        },
        directives: {
            setWidth: {
                updated: function(el, binding) {
                    el.style.width = binding.value + 'px';
                }
            }
        }
    });
    vm.mount('#app');
</script>

有些时候,可能只需要使用mounted和updated钩子函数,这时可以直接传入一个函数代替定义对象。示例代码如下:

js 复制代码
 vm.directive('set-bgcolor', function (el, binding) {
	el.style.backgroundColor = binding.value;
})

示例:为文字设置样式。

在页面中定义两个下拉菜单和一行文字,通过第一个下拉菜单为文字设置大小,通过第二个下拉菜单为文字设置颜色,代码如下:

html 复制代码
<div id="app">
    文字大小:<select v-model="obj.size">
        <option value="">请选择</option>
        <option value="20px">20px</option>
        <option value="30px">30px</option>
        <option value="40px">40px</option>
    </select>
    文字颜色:<select v-model="obj.color">
        <option value="">请选择</option>
        <option value="red">红色</option>
        <option value="green">绿色</option>
        <option value="blue">蓝色</option>
    </select>
    <p v-font-style="obj">宝剑锋从磨砺出,梅花香自苦寒来。</p>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                obj: {
                    size: '',
                    color: ''
                }
            }
        },
        directives: {
            fontStyle: function(el, binding) {
                el.style.fontSize = binding.value.size;
                el.style.color = binding.value.color;
            }
        }
    });
    vm.mount('#app');
</script>

3、绑定值的类型

自定义指令的绑定值可以是data中的属性,还可以是任意合法的JavaScript表达式,如数值、字符串、对象字面量等。

3.1、绑定数值

自定义指令的绑定值可以是一个数值。例如,注册一个自定义指令,通过该指令设置定位元素的顶部位置,将该指令的绑定值设置为一个数值,该数值即为被绑定元素的顶部位置。示例代码如下:

html 复制代码
<div id="app">
    <span v-set-position="100">
        Hello World
    </span>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
            }
        },
        directives: {
            setPosition: function(el, binding) {
                el.style.position = 'fixed';
                el.style.top = binding.value + 'px';
            }
        }
    });
    vm.mount('#app');
</script>

3.2、绑定字符串

自定义指令的绑定值可以是一个字符串。将绑定值设置为字符串需要使用单引号。例如,注册一个自定义指令,通过该指令设置文字的粗细为粗体,将该指令的绑定值设置为字符串'bold',该字符串即为被绑定元素设置的样式。示例代码如下:

html 复制代码
<div id="app">
    <p v-set-style="'bold'">
        Hello World
    </p>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
            }
        },
        directives: {
            setStyle: function(el, binding) {
                el.style.fontWeight = binding.value;
            }
        }
    });
    vm.mount('#app');
</script>

3.3、绑定对象字面量

自定义指令的绑定值可以是一个JavaScript对象字面量。如果指令需要多个值,就可以使用这种形式。注意,此时对象字面量不需要使用单引号引起来。例如,注册一个自定义指令,通过该指令设置文本的大小、颜色和粗细,将该指令的绑定值设置为对象字面量。示例代码如下:

html 复制代码
<div id="app">
    <p v-set-style="{size: 20, color: 'blue', weight: 'bold'}">
        Hello World
    </p>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
            }
        },
        directives: {
            setStyle: function(el, binding) {
                el.style.fontSize = binding.value.size + 'px';
                el.style.color = binding.value.color;
                el.style.fontWeight = binding.value;
            }
        }
    });
    vm.mount('#app');
</script>
相关推荐
小芝麻咿呀2 小时前
vue--面试题第一部分
前端·javascript·vue.js
早起傻一天~G2 小时前
vue2+element-UI表格封装
javascript·vue.js·ui
这儿有一堆花3 小时前
深入解析 Video.js:现代 Web 视频播放的工程实践
前端·javascript·音视频
烤麻辣烫3 小时前
JS基础
开发语言·前端·javascript·学习
IT_陈寒4 小时前
Vue的响应式把我坑惨了,原来问题出在这
前端·人工智能·后端
2603_953527994 小时前
WordPress Finale Lite 插件高危漏洞检测与利用工具 (CVE-2024-30485)
前端·python·安全·web3·xss
2601_949818094 小时前
头歌答案--爬虫实战
java·前端·爬虫
猫猫不是喵喵.5 小时前
layui表单项次大数据量导入并提交
前端·javascript·layui