vue3.2 setup 之局部自定义指令

在vue3.x中,注册局部自定义的指令是在setup方法外面,directives下面便可自定义指令,那在vue3.2中的<script setup>标签该如何自定义指令呢?

先回顾全局自定义指令

vue2 全局自定义指令

在vue2中,全局自定义指令通过 directive 挂载到 Vue 对象上,使用Vue.directive('name',opt)。

Vue.directive('focus',{
 inserted:(el)=>{
  el.focus()
 }
})

inserted 是钩子函数,在绑定元素插入父节点时执行。

vue3 全局自定义指令

在 vue3 中,vue 实例通过createApp 创建,所以全局自定义指令的挂载方式也改变了, directive 被挂载到 app上。

//全局自定义指令
app.directive('focus',{
 mounted(el){
  el.focus()
 }
})

//组件使用
<input type="text" v-focus />

再回顾局部自定义指令

在组件内部,使用 directives 引入的叫做局部自定义指令。

<script>
//局部自定义指令
const defineDir = {
 focus:{
  mounted(el){
   el.focus()
  }
 }
}
export default {
 directives:defineDir,
 setup(){}
}
</script>

其实,在vue3.2中,自定义指令变得更加的简单,直接上例子。

<template> 
  <input v-focus />
</template>

<script setup>
// 注册一个局部的自定义指令,需要以小写v开头
const vFocus = {
  mounted(el) {
    // 获取input,并调用其focus()方法
    el.focus()
  }
</script>

看到了吗,重点是:注册一个局部的自定义指令,需要以小写v开头

这里做最简单示例,实战中举一反三灵活应用到项目中才是真理。

看完,你的项目需求可能会更复杂,所以系统掌握vue3中指令基础知识才是重点。

自定义指令中的生命周期钩子函数

一个指令定义对象可以提供如下几个钩子函数(都是可选的,根据需要引入)

  • created :绑定元素属性或事件监听器被应用之前调用。该指令需要附加需要在普通的 v-on 事件监听器前调用的事件监听器时,这很有用。
  • beforeMounted :当指令第一次绑定到元素并且在挂载父组件之前执行。
  • mounted :绑定元素的父组件被挂载之后调用。
  • beforeUpdate :在更新包含组件的 VNode 之前调用。
  • updated :在包含组件的 VNode 及其子组件的 VNode 更新后调用。
  • beforeUnmounted :在卸载绑定元素的父组件之前调用
  • unmounted :当指令与元素解除绑定且父组件已卸载时,只调用一次。

eg:测试指令内生命周期函数执行

<template>
 <div>
  <input type="text" v-focus  v-if="show"><br>
  <button @click="changStatus">{{show?'隐藏':'显示'}}</button>
 </div>
</template>

//局部自定义指令
const autoFocus = {
 focus:{
  created(){
   console.log('created');
  },
  beforeMount(){
   console.log('beforeMount');
  },
  mounted(el){
   console.log('mounted');
  },
  beforeUpdated(){
   console.log('beforeUpdated')
  },
  updated(){
   console.log('updated');
  },
  beforeUnmount(){
   console.log('beforeUnmount');
  },
  unmounted(){
   console.log('unmounted');
  }
 },
}
import { ref } from 'vue'
export default {
 directives:autoFocus,
 setup(){
  const show = ref(true)
  return {
   show,
   changStatus(){
    show.value = !show.value
   }
  }
 }
}

通过点击按钮,我们发现创建 input 元素的时候,会触发 created、beforeMount 和 mounted 三个钩子函数。

隐藏 input 元素的时候,会触发 beforeUnmount 和 unmounted 。

然而我们添加的 beforeUpdate 和 updated 函数并没有执行。

此时我们把 input 元素上的 v-if 修改成 v-show 就会执行上述两个方法了,具体的执行情况自行验证下。

从 vue2 升级到 vue3 ,自定义指令的生命周期钩子函数发生了改变,具体变化如下:

  • bind 函数被替换成了beforeMounted。
  • update 被移除。
  • componentUpdated 被替换成了updated。
  • unbind 被替换成了 unmounted。
  • inserted 被移除。

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

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

  • el:指令所绑定的元素,可以直接操作DOM。
  • binding:是一个对象,包含该指令的所有信息。

binding 包含的属性具体的分别为:

  • arg 自定义指令的参数名。
  • value 自定义指令绑定的值。
  • oldValue 指令绑定的前一个值。
  • dir 被执行的钩子函数
  • modifiers:一个包含修饰符的对象。
<template>
 <div>
  <div v-fixed >定位</div>
 </div>
</template>

<script>
//自定义指令动态参数
const autoFocus = {
 fixed:{
  beforeMount(el,binding){
   console.log('el',el)
   console.log('binding',binding)
  }
 }
}
export default {
 directives:autoFocus,
 setup(){
 }
}
</script>

自定义指令参数

自定义指令的也可以带参数,参数可以是动态的,参数可以根据组件实例数据进行实时更新。

eg:自定义指令动态参数

<template>
 <div>
  <div v-fixed:pos="posData" style="width:100px;height:100px;background:grey">定位</div>
 </div>
</template>

<script>
//自定义指令动态参数
const autoFocus = {
 fixed:{
  beforeMount(el,binding){
   el.style.position = "fixed"
   el.style.left = binding.value.left+'px'
   el.style.top = binding.value.top + 'px'
  }
 }
}
export default {
 directives:autoFocus,
 setup(){
  const posData = {
   left:20,
   top:200
  }
  return {
   posData,
  }
 }
}
</script>

什么时候需要自定义指令?

  • 需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
  • 需要将某些功能在指定DOM元素上使用,但对于需要操作大量DOM元素或者大变动时候,推荐使用组件,而不是指令。

参考资料:传送门

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,776评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,527评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,361评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,430评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,511评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,544评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,561评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,315评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,763评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,070评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,235评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,911评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,554评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,173评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,424评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,106评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,103评论 2 352

推荐阅读更多精彩内容