vue官方有提供给我们自定义像v-model
和 v-show这样的指令,来看看怎么定义
话不多说我们事先用vue官方脚手架创建一个项目
比如我们要定义一个鼠标移入就把当前dom原生透明度显示为0,鼠标移开的时候为1,达到鼠标移入显示,鼠标移开隐藏的效果
function on(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
}
function off(element, event, handler) {
if (element && event) {
element.removeEventListener(event, handler, false);
}
}
// v-visibility自定义指令,默认导出
export default {
// 初始化设置,只调用一次,指令第一次绑定到元素时调用
bind(el, binding, vnode) {
console.log("bind:", el, binding, vnode);
el.style.opacity = 0;
},
// 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
inserted(el, binding, vnode) {
console.log("inserted:", el, binding, vnode);
on(el, "mouseover", () => (el.style.opacity = 1));
on(el, "mouseout", () => (el.style.opacity = 0));
},
// 只调用一次,指令与元素解绑时调用,也就是说组件卸载的时候调用。
unbind(el, binding, vnode) {
console.log("unbind:", el, binding, vnode);
off(el, "mouseover", () => (el.style.opacity = 1));
off(el, "mouseout", () => (el.style.opacity = 0));
},
};
里面像这些bind、inserted、update、componentUpdated、unbind这些钩子都有官方说明,update、componentUpdated我这里暂时先不用到
至于这些钩子的参数el、binding、vnode都有说明
那么我们在全局里面注册就可以使用
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store';
import visibility from './utils/visibility'//导入刚刚封装的自定义指令函数
Vue.config.productionTip = false;
Vue.directive('visibility',visibility);//全局注册指令v-visibility
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
那么我们就可以在组件里面去使用了
<template>
<img v-visibility:aa.bar="msg" src="../assets/logo.png" alt="">
</template>
<script>
export default {
data: () => {
return {
msg: "hhhhh",
};
},
};
</script>
也有局部注册自定义指令方式
<template>
<img v-visibility:aa.bar="msg" src="../assets/logo.png" alt="">
</template>
<script>
import visibility from '../utils/visibility';
export default {
directives:{//局部注册指令
visibility
},
data: () => {
return {
msg: "hhhhh",
};
},
};
</script>
value:对应的是传入的值,例如v-visibility:aa.bar="msg",msg变量对应的值
arg:对应的是指令传入的参数,例如 v-visibility:aa,aa就是传入的参数
modifiers:对应的是指令传入的修饰符对应的对象,例如 v-visibility:aa.bar,bar就是传入的修饰符
自定义指令的参数也可以是动态传入的参数如这样:
<img v-visibility:[params].bar="msg" src="../assets/logo.png" alt="">
<template>
<img v-visibility:[params].bar="msg" src="../assets/logo.png" alt="">
</template>
<script>
import visibility from '../utils/visibility';
export default {
directives:{
visibility
},
data: () => {
return {
msg: "hhhhh",
params:'哈哈'
};
},
};
</script>
假如不想关心那么复杂的周期钩子,也可以用最简便的方式如下:( 前提是bind
和 update
时触发相同行为)
function visibility(el, binding, vnode) {
on(el, "mouseover", () => (el.style.opacity = 1));
on(el, "mouseout", () => (el.style.opacity = 0));
}
修改后的自定义指令函数如下:
function on(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
}
function off(element, event, handler) {
if (element && event) {
element.removeEventListener(event, handler, false);
}
}
// v-visibility自定义指令
export function visibility(el, binding, vnode) {
on(el, "mouseover", () => (el.style.opacity = 1));
on(el, "mouseout", () => (el.style.opacity = 0));
}