VUE自定义指令实战

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>
相关推荐
孔令飞18 分钟前
Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中
前端
溪语流沙31 分钟前
【Web全栈进阶】PostgreSQL上手:Docker跑库 + 把早报站从SQLite迁过去
前端·docker·postgresql
IT_陈寒37 分钟前
SpringBoot自动配置的坑:你以为的捷径可能是弯路
前端·人工智能·后端
paopaokaka_luck37 分钟前
高校社团管理(AI辅助任务分配、协同过滤算法推荐、ECharts数据可视化、活动参与闭环、校园交流与反馈、器材借还管理)
java·前端·javascript·spring boot·数据分析·echarts
Dovis(誓平步青云)1 小时前
导览音频切换太快,旧讲解不能覆盖新展品
android·前端·javascript·ecmascript·音视频·宠物
福兮说12 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
郑州光合科技余经理12 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆66613 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
Dovis(誓平步青云)13 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
码艺-Alimjan14 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js