Vue自定义指令

前面的话

  除了默认设置的核心指令( v-modelv-show ),Vue 也允许注册自定义指令。在Vue里,代码复用的主要形式和抽象是组件。然而,有的情况下,仍然需要对纯 DOM 元素进行底层操作,这时候就会用到自定义指令。本文将详细介绍Vue自定义指令

 

指令注册

  以一个input元素自动获得焦点为例,当页面加载时,使用autofocus可以让元素将获得焦点 。但是autofocus在移动版Safari上不工作。现在注册一个使元素自动获取焦点的指令

  指令注册类似于组件注册,包括全局指令和局部指令两种

【全局指令】

  使用Vue.diretive()来全局注册指令

// 注册一个全局自定义指令 v-focus
Vue.directive('focus', {
  // 当绑定元素插入到 DOM 中。
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

【局部指令】

  也可以注册局部指令,组件或Vue构造函数中接受一个 directives 的选项

复制代码
var vm = new Vue({
  el: '#example',
  directives:{
    focus:{
      inserted: function (el) {
        el.focus()
      }      
    }
  }

})
复制代码

  然后可以在模板中任何元素上使用新的 v-focus 属性

<div id="example">
  <input v-focus>
</div>
复制代码
<script>
// 注册一个全局自定义指令 v-focus
Vue.directive('focus', {
  // 当绑定元素插入到 DOM 中。
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})
var vm = new Vue({
  el: '#example',

})
</script>
复制代码

 

钩子函数

  指令定义函数提供了几个钩子函数(可选) 

【bind】

  只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作

【inserted】

  被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)

【update】

  所在组件的 VNode 更新时调用,但是可能发生在其孩子的 VNode 更新之前。指令的值可能发生了改变也可能没有。但是可以通过比较更新前后的值来忽略不必要的模板更新

【componentUpdated】

  所在组件的 VNode 及其孩子的 VNode 全部更新时调用

【unbind】

  只调用一次, 指令与元素解绑时调用

 

钩子函数参数

  钩子函数被赋予了以下参数

【el】

  指令所绑定的元素,可以用来直接操作 DOM

【binding】

  一个对象,包含以下属性:

name: 指令名,不包括 v- 前缀。
value: 指令的绑定值, 例如: v-my-directive="1 + 1", value 的值是 2。
oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression: 绑定值的字符串形式。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"。
arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 "foo"。
modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。

【vnode】

  Vue 编译生成的虚拟节点

【oldVnode】

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

  [注意]除了 el 之外,其它参数都是只读的,尽量不要修改他们。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行

  下面是一个使用了这些参数的自定义钩子样例

<div id="example" v-demo:foo.a.b="message"></div>
复制代码
<script>
Vue.directive('demo', {
  bind: function (el, binding, vnode) {
    var s = JSON.stringify
    el.innerHTML =
      'name: '       + s(binding.name) + '<br>' +
      'value: '      + s(binding.value) + '<br>' +
      'expression: ' + s(binding.expression) + '<br>' +
      'argument: '   + s(binding.arg) + '<br>' +
      'modifiers: '  + s(binding.modifiers) + '<br>' +
      'vnode keys: ' + Object.keys(vnode).join(', ')
  }
})
new Vue({
  el: '#example',
  data: {
    message: 'hello!'
  }
})
</script>
复制代码

【函数简写】

   大多数情况下,可能想在bindupdate钩子上做重复动作,并且不想关心其它的钩子函数。可以这样写:

Vue.directive('color-swatch', function (el, binding) {
  el.style.backgroundColor = binding.value
})

【对象字面量】

  如果指令需要多个值,可以传入一个JS对象字面量。指令函数能够接受所有合法类型的JS表达式

<div v-demo="{ color: 'white', text: 'hello!' }"></div>
Vue.directive('demo', function (el, binding) {
  console.log(binding.value.color) // => "white"
  console.log(binding.value.text)  // => "hello!"
})

 

posted @   小火柴的蓝色理想  阅读(6199)  评论(2编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
历史上的今天:
2016-08-16 深入理解定时器系列第二篇——被誉为神器的requestAnimationFrame
点击右上角即可分享
微信分享提示
显示目录
目录
[1]指令注册[2]钩子函数[3]钩子函数参数