Vue 3 自定义核心用法(自定义指令、自定义组件、自定义HOOK)

6 阅读2分钟

你想了解的是 Vue3 中自定义指令、自定义组件、自定义 hooks 这三大核心自定义功能,我给你整理了最常用、能直接用的完整写法。


一、自定义指令(操作原生 DOM)

用于对普通 DOM 元素进行底层操作,比如自动聚焦、防抖、样式修改等。

1. 全局自定义指令(main.js)

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

// 示例:自动聚焦指令 v-focus
app.directive('focus', {
  // 元素挂载时触发
  mounted(el) {
    el.focus() // 操作原生 DOM
  }
})

// 示例:颜色指令 v-color="red"
app.directive('color', {
  mounted(el, binding) {
    el.style.color = binding.value // 获取指令传值
  }
})

app.mount('#app')

2. 局部自定义指令(组件内)

<script setup>
// v-focus
const vFocus = {
  mounted: (el) => el.focus()
}
</script>

<template>
  <input v-focus />
  <div v-color="'blue'">我是蓝色文字</div>
</template>

二、自定义组件(封装复用 UI)

Vue 最基础的自定义功能,把页面拆成独立组件。

1. 定义组件 MyButton.vue

<template>
  <button class="my-btn" @click="$emit('click', $event)">
    <slot /> // 插槽
  </button>
</template>

<script setup>
// 接收父组件参数
const props = defineProps({
  type: { type: String, default: 'primary' }
})
// 抛出事件
const emit = defineEmits(['click'])
</script>

<style scoped>
.my-btn { padding: 6px 12px; border-radius: 4px; }
</style>

2. 使用组件

<script setup>
import MyButton from './MyButton.vue'
</script>

<template>
  <MyButton @click="handleClick">自定义按钮</MyButton>
</template>

三、自定义 Hooks(复用逻辑,Vue3 组合式 API 核心)

类似 Vue2 的 mixin,但更干净、无副作用,用于复用业务逻辑

示例 1:useMouse 鼠标位置追踪

新建 hooks/useMouse.js

import { ref, onMounted, onUnmounted } from 'vue'

export function useMouse() {
  const x = ref(0)
  const y = ref(0)

  const update = (e) => {
    x.value = e.pageX
    y.value = e.pageY
  }

  onMounted(() => window.addEventListener('mousemove', update))
  onUnmounted(() => window.removeEventListener('mousemove', update))

  return { x, y }
}

使用 Hook

<script setup>
import { useMouse } from './hooks/useMouse'
const { x, y } = useMouse()
</script>

<template>鼠标位置:{{ x }}, {{ y }}</template>

示例 2:useCounter 计数器 Hook

import { ref } from 'vue'
export function useCounter(init = 0) {
  const count = ref(init)
  const inc = () => count.value++
  const dec = () => count.value--
  return { count, inc, dec }
}

四、额外常用:自定义插件

用于全局注册组件/指令/方法。

plugins/myPlugin.js

export default {
  install(app, options) {
    // 全局方法
    app.config.globalProperties.$myLog = (msg) => console.log('[LOG]', msg)
    
    // 全局组件
    // app.component('MyComponent', ...)
  }
}

main.js 引入

import myPlugin from './plugins/myPlugin'
app.use(myPlugin)

组件内使用

<script setup>
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
proxy.$myLog('hello')
</script>

总结

  • 自定义指令:操作原生 DOM → v-xxx
  • 自定义组件:封装 UI → 复用页面模块
  • 自定义 Hooks:复用逻辑 → 组合式 API 最佳实践
  • 自定义插件:全局注册功能 → 批量安装组件/指令