前端基础之《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>
相关推荐
子兮曰12 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰12 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万12 小时前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝12 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋13 小时前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁14 小时前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王952715 小时前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大15 小时前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师16 小时前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学16 小时前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端