vue自定义指令你需要了解这些

322 阅读2分钟
<div id="app">
    <div>
        <input type="text" v-slice="name" v-model="name">
        {{name}}
    </div>
</div>
<script>
    Vue.directive('slice', (el, bindings, vnode) => {
        let res = bindings.value.slice(0, 5);
        vnode.context.$data.name = res;
    })
    let vm = new Vue({
        el: '#app',
        data: {
            name: "ss",
        }
    });
</script>

通过vue构造函数提供的directive,第一个参数是指令的名称, 比如我们写一个限制字符个数的, 我们用limit

不需要加上v-,会自动加上。

第二个参数 可以是一个对象, 或者函数,函数的参数如下 :

el:指令所在的dom元素

bindings:

vnode: 虚拟节点

实际使用中,如果给修饰符会出现在bindings中,有一个modifiers,如果传参数会出现在bindings中的arg中

v-slice:9.number

下面是对象的写法

<body>
    <div id="app">
        <div>
            <input type="text" v-slice:9.number="name">
            {{name}}
        </div>
    </div>
    <script>
        Vue.directive('slice', {
            bind(el, bindings, vnode) { //绑定的时候执行
                //获取修饰符
                const numberFlag = bindings.modifiers;
                //获取截取字符串的长度参数
                const length = bindings.arg;
                //获取上下文对象
                const context = vnode.context;
                //初始化数据
                let initVal = context[bindings.expression].slice(0, length);
                if (numberFlag) {
                    initVal = initVal.replace(/\D/g, '')
                }
                //input输入框的值
                el.value = initVal;
                //上下文对象name的值
                context[bindings.expression] = initVal;
                //输入事件
                el.oninput = e => {
                    //接收用户输入的值
                    let value = e.target.value;
                    if (numberFlag) {
                        value = value.replace(/\D/g, '');
                    }
                    //修改name的值
                    context[bindings.expression] = value;
                    //修改输入框的值
                    e.target.value = value.slice(0, length);
                }
            },
            update(el, bindings, vnode) {  //更新的时候执行
                //获取上下文对象
                const context = vnode.context;
                //数据更新的时候
                if(bindings.modifiers) {
                    el.value = context[bindings.expression].slice(0, bindings.arg).replace(/\D/g, '');;
                } else {
                    el.value = context[bindings.expression].slice(0, bindings.arg);
                }
            },
            inserted(el) {  //插入页面的时候执行
                el.focus(); //光标聚焦
            }
        })
        let vm = new Vue({
            el: '#app',
            data: {
                name: "sadfa2sdfadsfdsa3fadf",
            }
        });
    </script>
</body>

其实函数的写法就是对象写法bind+update的结合,上面去掉了函数写法中使用的v-model,通过bind中的事件处理。

🚬每天分享一点点, 欢迎大家讨论, 共同学习, 有不对的地方,欢迎指出🚬