# Vue2.x 的指令

前言

用自定义指令可以对普通 DOM 元素进行底层操作,其生命周期:

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没 有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用
  • unbind:只调用一次,指令与元素解绑时调用

# 1.内置指令

# 1.1 v-modle

  • :value + @input 写法实现双向数据绑定
  • 组件封装时,可以扩展使用v-model
刷新
全屏/自适应
  • 修饰符

  • trim:去掉前后空格(文本粘贴到输入框中很多时候有这种问题)

刷新
全屏/自适应
<template>
  <!-- 修改符 .number数组 .trim空格 -->
  <input type="text" v-model.number.trim="val" />{{ typeof val }}
  <!-- 修饰符 键盘修饰符 鼠标修饰符 常用的.ctrl .esc .enter-->
  <input type="text" @keyup.esc="fn" />
  <input type="text" @keyup.f1="fn" />
  <!-- 同时 -->
  <input type="text" @keyup.ctrl.enter="fn" />
</template>
1
2
3
4
5
6
7
8
9

# 1.2 v-slot

# 1.3.v-once

Vue 提供了v-once指令用于只渲染元素和组件一次,一般可以用于存在大量静态数据组件的更新性能优化,注意是大量静态数据,因为少数情况下我们的页面渲染会因为一些静态数据而变慢。

<my-component v-once :data="msg"></my-component>
1

这时候因为组件绑定了 v-once,所以无论 msg 的值如何变化,组件内渲染的永远是其第一次获取到的初始值。因此我们在使用 v-once 的时候需要考虑该组件今后的更新情况,避免不必要的问题产生。

# 2.自定义指令

# 2.1 n 个字符

  • 1.默认使用函数形式的自定义指令和 v-model 实现此功能

    刷新
    全屏/自适应
  • 2.update+bind 形式的自定义指令和 v-model 实现此功能

export default (Vue, options = {}) => {
  Vue.directive("split", {
    update(el, bindings, vnode) {
      let ctx = vnode.context // 获取当前输入框所在的上下文
      ctx[bindings.expression] = el.value.slice(0, 3) // 去当前上下文中 获取 msg 把输入的内容 截取3个放到 msg中
    },
    // 只当用户绑定时生效
    bind(el, bindings, vnode) {
      let ctx = vnode.context // 获取当前输入框所在的上下文
      ctx[bindings.expression] = el.value.slice(0, 3) // 去当前上下文中 获取 msg 把输入的内容 截取3个放到 msg中
    },
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
刷新
全屏/自适应
  • 3.去掉 v-model 只用自定义指令实现此功能
刷新
全屏/自适应
  • 4.添加 focus 自定义指令
刷新
全屏/自适应

# 2.2 防抖

刷新
全屏/自适应

# 2.3 拖拽

刷新
全屏/自适应

# 2.4 水波纹

刷新
全屏/自适应

# 2.5 权限按钮

刷新
全屏/自适应

# 2.6 空白点击

查看详情
export default (Vue, options = {}) => {
  Vue.directive("split", {
    update(el, bindings, vnode) {
      let ctx = vnode.context; // 获取当前输入框所在的上下文
      ctx[bindings.expression] = el.value.slice(0, 3); // 去当前上下文中 获取 msg 把输入的内容 截取3个放到 msg中
    },
    // 只当用户绑定时生效
    bind(el, bindings, vnode) {
      let ctx = vnode.context; // 获取当前输入框所在的上下文
      ctx[bindings.expression] = el.value.slice(0, 3); // 去当前上下文中 获取 msg 把输入的内容 截取3个放到 msg中
    },
  });
};
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2.7 滚动加载

查看详情
export default (Vue, options = {}) => {
  Vue.directive("split", {
    update(el, bindings, vnode) {
      let ctx = vnode.context; // 获取当前输入框所在的上下文
      ctx[bindings.expression] = el.value.slice(0, 3); // 去当前上下文中 获取 msg 把输入的内容 截取3个放到 msg中
    },
    // 只当用户绑定时生效
    bind(el, bindings, vnode) {
      let ctx = vnode.context; // 获取当前输入框所在的上下文
      ctx[bindings.expression] = el.value.slice(0, 3); // 去当前上下文中 获取 msg 把输入的内容 截取3个放到 msg中
    },
  });
};
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2.8 懒加载

刷新
全屏/自适应

# 2.9 复制

刷新
全屏/自适应

# 2.10 全屏

:::

<template>
  <div v-screen.icon>全屏</div>
</template>
<script>
export default {}
</script>
1
2
3
4
5
6

:::

# 2.11 回到顶部

刷新
全屏/自适应

# 2.12 文字省略

刷新
全屏/自适应

# 2.13 水印文字

  • 通过传入的参数,创建 canvas 画布
  • 通过 dom 节点插入到父节点下
刷新
全屏/自适应

# 3.原理