Vue自定义指令

568 阅读2分钟

Vue允许注册自定义指令,当对普通DOM元素进行底层操作这个时候就会用到自定义指令.

初识 input自动获得焦点

1.注册一个全局的指令

<input type="text" v-model="num" v-focus>
Vue.directive('focus', {
    // 当被绑定的元素插入到DOM中时
    inserted: function (el) {
        // 聚焦元素
        el.focus();
    }
})

2.注册一个局部组件

 // 注册局部组件
<input type="text" v-model="num" v-focus>
directives: {
    focus: {
        // 被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)
        inserted: function (el) {
            console.log(el, 'inserted')
            //设置获取焦点
            el.focus();
        },
    }
}

钩子函数

// html页面
<input type="text" v-model="num" v-focus:foo.x="message" v-if="num<20">
// Vue数据
data: {
    num: 1,
    message: 'hello!',
}
// 注册局部组件
directives: {
    focus: {
        // 只调用一次,指令第一次绑定到元素时调用,在这里可以进行一次性的初始化设置.
        bind: function (el, vnode) {
            console.log(el, 'bind');
        },
        // 被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)
        inserted: function (el) {
            console.log(el, 'inserted')
            //设置获取焦点
            el.focus();
        },
        // 所有组件的VNode更新时调用,但是可能发生在其子VNode更新之前,指令的值可能发生了改变,也可能没有,但是你可以通过比较更新前后的值来忽略不必要的模板更新
        update: function (el, binding, vnode, oldVnode) {
            console.log('update start');
            console.log(binding, 'binding', new Date().toLocaleString());
            // <input type="text" v-model="num" v-focus:foo.x="message" v-if="num<20">
            // data: {
            //     num: 1,
            //     message: 'hello!'
            // },
            //binding:一个对象,包含以下property
            //      name:指令名 不包括v-前缀 focus
            //      value:指令的绑定值  hello!
            //      oldValue:指令绑定的前一个值,仅在update和componentUpdate钩子中可用,无论值是否改变都可用
            //      expression字符串形式的指令表达式,例如 v-focus:foo.x="message"中,表达式为 message
            //      arg:传给指令的参数,可选,例如v-focus:foo.x="message" 中,参数为 foo
            //      modifiers:一个包含修饰符的对象,例如:v-focus:foo.x="message"中,修饰符对象为{x:true}

        },
        // 指令所有组件的VNode及其子 VNode全部更新后调用
        componentUpdated: function (el) {
            console.log('update end');
            console.log(el, 'componentUpdated');
        },
        // 只调用一次,指令与元素解绑时调用 由于设置v-if<20 所以当输入大于19的数字就会执行这个钩子函数
        unbind: function (el) {
            console.log(el, 'unbind');
        }
    },
}

动态指令参数

// html
<div v-fixed:[position]="px" class="odiv"></div>
// vue数据
data: {
    position: 'right',
    px: 300
},
// vue自定义函数部分
// 动态指令参数 设置固定定位 距右300px
fixed: {
    bind: function (el, binding, vnode) {
        el.style.position = 'fixed'
        el.style[binding.arg] = binding.value + 'px'
    }
}