自定义指令

2020-04-12  本文已影响0人  在幽幽暗暗反反复复中追问

使用组件库的时候,有的 props 属性直接传属性名称就可以达到效果,一直以为是用指令写的,最近测试了一下,发现其实针对类型为 Booleanprops 属性,传 props 属性名就已经表示将这个属性设为 true,其他类型的 props 属性这样传会报错的。

正文

可以通过属性名 directives 编写全局 / 组件指令
和组件、页面一样,指令也有钩子函数
bind 只调用一次,指令第一次绑定到元素上时调用。用于初始化
inserted 元素插入父节点时调用
update 组件 VNode 更新时调用,此时子 VNode 不一定更新完
componentUpdated 组件 VNode 和子 VNode 都更新完后调用
unbind 只调用一次,指令和绑定元素解绑时调用

钩子函数中有以下几个参数
el 绑定指令的 dom 元素
binding 指令的详细信息 name, value, oldValue, expression, modifier, arg...

其中 modifier 是指令修饰符,例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
arg 指令参数,非常灵活,动态指令中常常用到,例如 v-my-directive:[position]="30" 传递位置参数 left right... 表示要偏离 30px 的方向

vnode 当前虚拟节点
oldVnode 上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用

Vue 自定义指令

使用场景:搜索结果高亮搜索关键词

// 使用方法 v-emphasize="searchKey"
directives: {
  emphasize: {
    inserted (el, binding) {
      // 搜索关键词通过 value 传递
      const { value } = binding
      if (value) {
        // 根据 关键词 分割
        let list = el.innerText.split(value)
        if (list.length === 0) {
          return
        }
        let res = document.createElement('span')
        while (list.length > 1) {
          // 构造高亮 span
          const span = document.createElement('span')
          span.setAttribute('style', 'color: red')
          span.textContent = value
          // 添加 非高亮 和 高亮部分
          res.appendChild(document.createTextNode(list.shift()))
          res.appendChild(span)
        }
        // 处理 list 的最后一个元素
        res.appendChild(document.createTextNode(list.shift()))
        // el.firstChild.remove()
        // el.append(res)
        // 移除 span 原来的 子元素
        // 添加 构造的元素
        el.firstChild.replaceWith(...res.childNodes)
      }
    },
  },
},

因为会对 dom 进行操作,所以一定不要直接在这个 dom 上面绑定其他的操作,建议在外面包一层 div 来绑定事件处理和样式

上一篇 下一篇

猜你喜欢

热点阅读