前端基础之《Vue(11)—自定义指令》

一、自定义指令

1、自己封装指令

什么是指令?指令本质上就是DOM功能的一种抽象封装。

如果有一些DOM功能经常用,但是Vue没有提供相关指令,建议自己封装。

2、自定义全局指令

使用Vue.directive('指令名', function() {})定义全局指令。

3、自定义局部指令

使用directives: {}定义局部指令,只能在当前组件中使用。

(1)使用function写法

javascript 复制代码
directives: {
    // function写法
    'color': function(el, binding, vnode) {
        console.log('---el', el) // 指令所对应的DOM节点
        console.log('---binding', binding) // 绑定的值/表达式
        console.log('---vnode', vnode) // 当前的虚拟DOM
        el.style.color = binding.value
    }
}

接收3个参数:

el:指令所对应的DOM节点

binding:绑定的值/表达式

vnode:当前的虚拟DOM

(2)使用对象写法

javascript 复制代码
directives: {
    // function写法
    'color': function(el, binding, vnode) {
        console.log('---el', el) // 指令所对应的DOM节点
        console.log('---binding', binding) // 绑定的值/表达式
        console.log('---vnode', vnode) // 当前的虚拟DOM
        el.style.color = binding.value
    },
    // 对象写法
    'color2': {
        bind(el, binding) { // 绑定cc变量的时候
            el.style.color = binding.value
        },
        update(el, binding) { // 修改cc变量的时候
            el.style.color = binding.value
        }
    }
}

还有其它的钩子。

注:function写法,等价于bind + update这两个。

二、例子代码

自己封装一个指令v-form,类似于v-model指令实现双向绑定。

必须要用虚拟DOM的上下文实现。

html 复制代码
<html>
<head>
    <title>自定义指令</title>
    <style>
        
    </style>
</head>
<body>
    <div id="app">
        <h1 v-color='"red"'>测试</h1>
        <h1 v-color='"blue"'>测试</h1>
        <h1 v-color2="cc">测试</h1>
        <input type="text" v-form.lazy="name" />
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>

    <script>
        Vue.directive ('form', {
            bind(el, binding, vnode) {
                console.log('---el', el)
                console.log('---binding', binding)
                console.log('---vnode', vnode)

                // 解构赋值
                const { lazy } = binding.modifiers

                // v-bind:value
                // 指令在绑值的时候,改上下文中的值
                el.value = vnode.context[binding.expression]
                // v-on:input
                // 实现双向绑定
                el.addEventListener(lazy?'blur':'input', function(ev){
                    console.log('---事件', ev.target.value)
                    vnode.context[binding.expression] = ev.target.value
                })
            },
            update(el, binding, vnode) {
                // 实现双向绑定
                el.value = vnode.context[binding.expression]
            }
        })

        const app = new Vue({
            data() {
                return {
                    cc: "green",
                    name: '张三'
                }
            },
            directives: {
                // function写法
                'color': function(el, binding, vnode) {
                    //console.log('---el', el) // 指令所对应的DOM节点
                    //console.log('---binding', binding) // 绑定的值/表达式
                    //console.log('---vnode', vnode) // 当前的虚拟DOM
                    el.style.color = binding.value
                },
                // 对象写法
                'color2': {
                    bind(el, binding) { // 绑定cc变量的时候
                        el.style.color = binding.value
                    },
                    update(el, binding) { // 修改cc变量的时候
                        el.style.color = binding.value
                    }
                }
            }
        })
        app.$mount('#app')

    </script>

</body>
</html>
相关推荐
匆叔19 小时前
JavaScript 性能优化实战技术
前端·javascript
子兮曰19 小时前
🚀前端环境变量配置:10个让你少加班的实战技巧
前端·node.js·前端工程化
用户516816614584119 小时前
Uncaught ReferenceError: __VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not defined
前端·vue.js
huabuyu19 小时前
构建极致流畅的亿级数据列表
前端
小枫学幽默19 小时前
2GB文件传一半就失败?前端大神教你实现大文件秒传+断点续传
前端
熊猫片沃子19 小时前
Vue 条件与循环渲染:v-if/v-else 与 v-for 的语法简介
前端·vue.js
ai产品老杨19 小时前
打破技术壁垒,推动餐饮食安标准化进程的明厨亮灶开源了
前端·javascript·算法·开源·音视频
文心快码BaiduComate19 小时前
来WAVE SUMMIT,文心快码升级亮点抢先看!
前端·后端·程序员
布列瑟农的星空19 小时前
html中获取容器部署的环境变量
运维·前端·后端
工会代表19 小时前
nginx配置,将前端项目配置到子路径下踩过的坑。
前端·nginx