Vue自定义指令

一、认识自定义指令

目录

一、认识自定义指令

方式一、使用默认实现方式,使用 ref 实现,并抽取到 hooks,方便调用。

 方式二、自定义一个 v-focus 的局部指令

 方式三:自定义一个 v-focus 的全局指令

  • 某些情况,你需要对 DOM 元素进行底层操作,此时会用到自定义指令
  • 自定义指令分为两种:
    • 自定义局部指令
      • 组件中通过 directives 选项,只能在当前组件中使用;
    • 自定义全局指令
      • app 的 directive方法,可以在任意组件中被使用
  • 比如做一个简单的案例:当某个元素挂载完成后可以自定获取焦点
    • 实现方式一:使用默认实现方式
    • 实现方式二:自定义一个 v-focus 的局部指令
    • 实现方式三:自定义一个 v-focus 的全局指令

方式一、使用默认实现方式,使用 ref 实现,并抽取到 hooks,方便调用。

<!-- App.vue -->
<template>
  <div class="app">
    <input type="text" ref="inputRef" />
  </div>
</template>

<script setup>

// 1.方法一:定义 ref 绑定到 input 中,调用 focus()
import useInput from './hooks/useInput'
const { inputRef } = useInput()

</script>

<style scoped lang="less"></style>

 新建 hooks/useInput.js

import { ref, onMounted } from 'vue'

export default function useInput() {
  const inputRef = ref()
  onMounted(() => {
    inputRef.value?.focus()
  })
  return { inputRef }
}

 方式二、自定义一个 v-focus 的局部指令

缺点:只能在局部使用,不能复用。

注意:需要定义一个标识符 v 开头

<!-- App.vue -->

<template>
  <div class="app">
    <!-- 方式二、自定义指令 -->
    <input type="text" v-focus />
  </div>
</template>

<!-- <script>
export default {
  directives: {
    focus: {
      // focus: {} 这个对象里放的是生命周期的函数(自定义指令),会把元素 el 传过来
      mounted(el) {
        // 当v-focus应用到 input上,input被挂载到DOM上后,就会回调 mounted 生命周期函数
        console.log('v-focus 应用到元素被挂载了', el)
        el?.focus()
      }
    }
  }
}
</script> -->
<script setup>
// 2.方式二:自定义指令(局部指令)
// 注意:定一个标识符,v开头
const vFocus = {
  mounted(el) {
    // 当v-focus应用到 input上,input被挂载到DOM上后,就会回调 mounted 生命周期函数,
    console.log('v-focus 应用到元素被挂载了', el)
    el?.focus()
  }
}
</script>

<style scoped lang="less"></style>

 方式三:自定义一个 v-focus 的全局指令

  •  为方便复用,写在 main.js 里
import { createApp } from 'vue'
import App from './01_自定义指令/App.vue'

const app = createApp(App)
// 自定义全局指令,需要定义个名称
app.directive('focus', {
  mounted(el) {
    // 当v-focus应用到 input上,input被挂载到DOM上后,就会回调 mounted 生命周期函数,
    console.log('v-focus 应用到元素被挂载了', el)
    el?.focus()
  }
})
app.mount('#app')
  • 但是有时候自定义指令会有很多,所以可以单独抽取出来,新建文件夹 directives

1. 先抽取到 focus.js 里

export default function directiveFocus(app) {
  // 自定义全局指令,需要定义个名称
  app.directive('focus', {
    mounted(el) {
      // 当v-focus应用到 input上,input被挂载到DOM上后,就会回调 mounted 生命周期函数,
      console.log('v-focus 应用到元素被挂载了', el)
      el?.focus()
    }
  })
}

 2.新建一个index.js

  • 在这里导出所有的自定义指令,方便直接在mian.js中使用
import directiveFocus from './focus'

export default function useDirectives(app) {
  directiveFocus(app)
}

 3.main.js

import { createApp } from 'vue'
import App from './01_自定义指令/App.vue'
import useDirectives from './01_自定义指令/directives/index'

const app = createApp(App)
// 自定义指令
useDirectives(app)
app.mount('#app')

二、生命周期-自定义指令的生命周期 

一个指令定义到对象,vue提供了如下的几个钩子函数:

  • created:在绑定元素的 attribute 或事件监听器被应用之前调用;
  • beforeMount:当指令第一次绑定到元素并且在挂载父组件之前调用;
  • mounted:在绑定元素的父组件被挂载后调用;
  • beforeUpdate:在更新包含组件的 VNode 之前调用;
  • updated:在包含组件的 VNode 及其子组件的 VNode 更新后调用;
  • beforeUnmount:在卸载绑定元素的父组件之前调用;
  • unmounted: 当指令与元素解除绑定并且父组件已卸载时,只调用一次;
<template>
  <div class="app">
    <div class="title" v-if="showTitle" v-why>当前计数{{ counter }}</div>
    <button @click="counter++">+1</button>
    <button @click="showTitle = false">隐藏</button>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'

const counter = ref(0)
const showTitle = ref(true)
const vWhy = {
  created() {
    console.log('created -- 绑定前')
  },
  beforeMount() {
    console.log('beforeMount -- 挂载前')
  },
  mounted() {
    console.log('mounted -- 挂载后')
  },
  beforeUpdate() {
    console.log('beforeUpdate -- 更新前')
  },
  updated() {
    console.log('updated -- 更新后')
  },
  beforeUnmount() {
    console.log('beforeUnmount---卸载前')
  },
  unmounted() {
    console.log('unmounted')
  }
}
</script>

<style scoped></style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值