1. 背景
自定义的指令都是基于vue脚手架来实现的
2. 原理解释
全局注册和局部注册
直接调用了Vue提供的directive方法来注册全局的自定义指令,该方法接收两个参数:指令名称
, 包含指令钩子函数的对象
。
指令注册完毕后,我们就可以在项目中任意组件中的元素上使用"v-指令名称"的形式使用指令了。
javascript
// src/main.js
import Vue from "vue";
import App from "./App.vue";
Vue.config.productionTip = false;
Vue.directive("resize", {
bind() {},
inserted() {},
update() {},
componentUpdated() {},
unbind() {},
});
new Vue({
render: (h) => h(App),
}).$mount("#app");
全局注册指令使用的是directive,局部注册指令使用的是directives,很好理解,局部指令一次性注意注册很多个,全局指令依次只能注册一个
组件的生命周期
指令绑定到元素时(bind)、元素插入时(inserted)、组件更新时(update)、组件更新后(componentUpdated)、指令与元素解绑时(unbind)
钩子中的参数
el:
指令所绑定的元素,可以用来直接操作 DOM。
binding:
一个对象,包含以下属性:
name
:指令名,不包括v-
前缀。value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为2
。oldValue
:指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式。例如v-my-directive="1 + 1"
中,表达式为"1 + 1"
。arg
:传给指令的参数,可选。例如v-my-directive:foo
中,参数为"foo"
。modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为{ foo: true, bar: true }
。
vnode:
Vue 编译生成的虚拟节点。
oldVnode:
上一个虚拟节点,仅在
update
和componentUpdated
钩子中可用。
具体的demo
javascript
<div style="height: 300px; width: 80%; background: blue" v-resize:[args]="value"></div>
directives: {
resize: {
bind(el, binding) {
console.log("bind");
console.log("值", binding.value);
console.log("参数", binding.arg);
},
inserted(el, binding, vnode) {
console.log("inserted");
console.log(el, binding);
let that = vnode.context;
console.log("that: ", that);
// 监听浏览器的resize事件
window.addEventListener("resize", () => {
that.innerHeight = window.innerHeight;
that.innerWidth = window.innerWidth;
});
},
update() {
console.log("VNode更新了");
},
componentUpdated() {
console.log("componentUpdated");
},
unbind() {
console.log("unbind");
window.removeEventListener("resize");
},
},
},
也可以简写
javascript
resize(el, binding) {
console.log("我是简写的自定义指令", binding.value);
},
上段代码的意思就是把bind和update钩子函数合二为一了,通常我们想要这两个钩子函数做同样的事的时候使用。
3. 参考blog
zhuanlan.zhihu.com/p/484670867
4.扩展
window.addEventListener
xml
<script>
// 页面加载完毕加载
window.addEventListener('load', function () {
})
// 只需要加载成功元素就可以
window.addEventListener('DOMContentLoaded', function () {
})
// 只要窗口大小发生像素变化就会触发
window.addEventListener('resize', function () {
// 当前窗口宽度
console.log(window.innerWidth);
})
</script>