[DAY19] 跟 Vue.js 认识的30天 - Vue 自定义指令(`directive`)

在粗浅的看过这一章时,觉得 Vue 真的有好多功能啊,目前的我似乎还是没办法很熟用 Vue 的每项语法,只希望未来在遇到各种问题时,我能有印象可以使用哪种语法。

自定义指令写法

自定义指令分成2种写法,分别是全局注册及区域注册:

  • 全局注册

    Vue.directive('directiveName',{
      bind(el, binding, vnode) {
        // 指令第一次绑定到元素时调用,只调用一次。
      },
      inserted(el, binding, vnode) {
        // 被绑定元素插入父元素时调用
      },
      update(el, binding, vnode, oldVnode) {
        // 模组内的元素变动时调用
      },
      componentUpdated(el, binding, vnode, oldVnode){
        // 更新后调用。
      },
      unbind(el, binding, vnode){
        // 指令解除绑定
      }
    })
    
  • 区域注册

    directives:{
      directiveName:{
        bind(el, binding, vnode) {
          // 指令第一次绑定到元素时调用,只调用一次。
        },
        inserted(el, binding, vnode) {
          // 被绑定元素插入父元素时调用
        },
        update(el, binding, vnode, oldVnode) {
          // 模组内的元素变动时调用
        },
        componentUpdated(el, binding, vnode, oldVnode){
          // 更新后调用。
        },
        unbind(el, binding, vnode){
          // 指令解除绑定
        }
      }
    }
    

自定义指令的钩子函数及其参数

https://ithelp.ithome.com.tw/upload/images/20210212/20127553KJMeY634Jb.png

https://ithelp.ithome.com.tw/upload/images/20210212/20127553xNYBHuAkaV.png

上面2张图是从 Vue 文件中撷取出来的,但光看说明还是不清楚里面的配置,所以就让我们来实际操作试试。

钩子函数

<button @click.prevent="counts++">新增P tag</button>
<p v-for="count of counts" :key='count' v-border-color:top="Math.random().toString(10).substr(2,6)">我会变成随机颜色</p>
<script>
Vue.directive("border-color", {
  bind(el, binding, vnode) {
    console.log("bind");
    console.log("el: ", el);
    console.log("binding: ", binding);
    console.log("vnode: ", vnode);
    el.style.color = `#${binding.value}`;
  },
  inserted(el, binding, vnode) {
    console.log("inserted");
    console.log("el: ", el);
    console.log("binding: ", binding);
    console.log("vnode: ", vnode);
  },
  update(el, binding, vnode, oldVnode) {
    console.log("update");
    console.log("el: ", el);
    console.log("binding: ", binding);
    console.log("vnode: ", vnode);
    console.log("oldVnode: ", oldVnode);
  },
  componentUpdated(el, binding, vnode, oldVnode) {
    console.log("componentUpdated");
    console.log("el: ", el);
    console.log("binding: ", binding);
    console.log("vnode: ", vnode);
    console.log("oldVnode: ", oldVnode);
  },
  unbind(el, binding, vnode) {
    console.log("unbind");
    console.log("el: ", el);
    console.log("binding: ", binding);
    console.log("vnode: ", vnode);
  }
});
</script>

画面刚载入时,会执行 bind()inserted()

https://ithelp.ithome.com.tw/upload/images/20210212/20127553NP3KQUeS7W.png

当点击了新增 P tag 的按钮时,会先执行原本的第一个 P 标签的 update()componentUpdated() ,之後执行新增的那个 P 标签的 bind()inserted()

https://ithelp.ithome.com.tw/upload/images/20210212/20127553PjHjJEIkOy.png

也就是说会先执行完原本标签的 update()componentUpdated() (不论原本标签有几个会都执行),才去执行新增标签的 bind()inserted()

钩子函数中的参数

  • el : 绑定该自定义指令的元素,可透过 el 直接操作该 DOM 元素。

  • binding : 拥有许多属性,可以供使用。如下图。

https://ithelp.ithome.com.tw/upload/images/20210212/20127553XRQAWb45Hc.png

  • vnodeoldVnode : 感觉不是很常会用到的东西,之後再找时间了解。

在 Vue 文件中重点提示了:

除了 el ,其余的参数中的属性只能读取不能修改,如有需要在不同函数中共享一些数据的话,可以在 HTML 中透过 dataset (data-*)来设定。

动态绑定参数

<button @click.prevent="changeDirection">改变方向</button>
<p v-border-color:[direction]="Math.random().toString(10).substr(2,6)">我会变成随机颜色</p>
<script>
const vm = new Vue({
  el: "#vm",
  data: {
    directions:['top','right','bottom','left'],
    direction:`top`
  },
  methods: {
    changeDirection() {
      this.direction =this.directions[Math.floor(Math.random()*4)]
    }
  }
});
</script>

透过 v-directiveName:[dynamicArgumentName] ,可以为该元素的自定义指令加上动态参数(可跟着模组资料进行更新)。

提醒一下,如果仅仅是变换绑定的参数,也会为该元素触发 update()componentUpdated() 喔!

自定义指令值

特别把这个写出来是因为刚开始练习时,一直无法正常运作,後来才发现这个值的使用方法跟 v-bind 的用法是相同的,值可以物件、阵列、数字、字串等等,但也因此如果这个值是单纯字串的话,那麽就一定要加上 '' ,让 Vue 知道这是字串,否则 Vue 会认为这是模组资料(data)的内容。

Demo:DAY19 | 跟 Vue.js 认识的30天 - Vue 模组自定义指令(directive)

参考资料

Vue.js - 自定义指令


<<:  力撑香港的Protonvpn有中资背景吗?

>>:  [DAY20]跟 Vue.js 认识的30天 - Vue 插件(Plugin)

那些被忽略但很好用的 Web API / FullScreen

一起来延伸视野,迎接更大的画面吧! 今天要介绍的 FullScreen API 会被忽略的原因可能...

Day16# Channel

今天要介绍的是 channel,那麽我们就进入正题吧 ─=≡Σ(((っ゚∀゚)っ channel 昨...

马可夫模型

马可夫模型 (Markov Model) 会用来表达状态以及转移机率及它们的随机过程使用的模型,或许...

Day 18 - 取得所有Contract程序范例

使用Shioaji API,第一次接触的人最常遇到的问题就是要如何抓所有的股票资料 在Day 03 ...

[Day12] 为了摆脱菜鸟C#後端 -到底什麽是Delegate?Func<T, TResult>?

测试打了"OrderCreate"(建立订单)服务後, 昨天我们尝试(使用AES...