前端基础之《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>
相关推荐
程序猿阿伟1 小时前
《首屏加载优化手册:Vue3+Element Plus项目提速的技术细节》
前端·javascript·vue.js
fruge3 小时前
Vue Pinia 状态管理实战指南
前端·vue.js·ubuntu
sean3 小时前
开发一个自己的 claude code
前端·后端·ai编程
用户21411832636023 小时前
dify案例分享-用 Dify 一键生成教学动画 HTML!AI 助力,3 分钟搞定专业级课件
前端
学会煎墙5 小时前
使用uniapp——实现微信小程序的拖拽排序(vue3+ts)
微信小程序·uni-app·vue·ts
太过平凡的小蚂蚁5 小时前
Kotlin 协程中常见的异步返回与控制方式(速览)
开发语言·前端·kotlin
咖啡の猫6 小时前
Vue初始化脚手架
前端·javascript·vue.js
晨枫阳6 小时前
uniapp兼容问题处理总结
前端·vue.js·uni-app
liusheng7 小时前
腾讯地图 SDK 接入到 uniapp 的多端解决方案
前端·uni-app
拉不动的猪8 小时前
如何处理管理系统中(Vue PC + uni-app 移动端):业务逻辑复用基本方案
前端·javascript·架构