前端基础之《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>
相关推荐
曼巴UE51 天前
UE FString, FName ,FText 三者转换,再次学习,官方文档理解
服务器·前端·javascript
行走的陀螺仪1 天前
高级前端 Input 公共组件设计方案(Vue3 + TypeScript)
前端·javascript·typescript·vue·组件设计方案
一颗不甘坠落的流星1 天前
【Antd】基于 Upload 组件,导入Json文件并转换为Json数据
前端·javascript·json
LYFlied1 天前
Vue2 与 Vue3 虚拟DOM更新原理深度解析
前端·javascript·vue.js·虚拟dom
Lucky_Turtle1 天前
【Node】npm install报错npm error Cannot read properties of null (reading ‘matches‘)
前端·npm·node.js
小飞侠在吗1 天前
vue shallowRef 与 shallowReacitive
前端·javascript·vue.js
惜分飞1 天前
sql server 事务日志备份异常恢复案例---惜分飞
前端·数据库·php
GISer_Jing1 天前
WebGL实例化渲染:性能提升策略
前端·javascript·webgl
烟锁池塘柳01 天前
【技术栈-前端】告别“转圈圈”:详解前端性能优化之“乐观 UI” (Optimistic UI)
前端·ui