, ,

常用Hooks

Vue3 把基于函数、可复用的逻辑片段统称为 组合式函数(Composables),日常大家口语都叫 hook…

Vue3 把基于函数、可复用的逻辑片段统称为 组合式函数(Composables),日常大家口语都叫 hook,用法和 React Hook 思路类似,但 API、规则完全是 Vue 体系。

  1. Vue3 内置 Hook Vue 官方提供的原生 API:ref / reactive / computed / watch / onMounted / useRoute 等,是组合式 API 基础。
  2. 自定义 Hook(组合式函数)重复逻辑(窗口监听、请求、表单、权限、滚动条、本地存储等)抽成独立函数,多组件复用。

规范约定:Vue 自定义 Hook 函数名建议以 use 开头(和 React 习惯一致,团队统一规范)。

Vue3 内置常用 Hook

1. 基础响应式

1.1 ref 基本类型响应(字符串 / 数字 / 布尔)

<template>
  <div>{{ count }}</div>
  <button @click="count++">+1</button>
</template>

<script setup>
// 导入内置 API
import { ref } from 'vue'

// 创建响应式变量
const count = ref(0)
// JS 中取值/赋值要加 .value
console.log(count.value)
</script>

1.2 reactive 对象 / 数组响应

import { reactive } from 'vue'

const user = reactive({
  name: '张三',
  age: 18
})
// 直接修改属性,不用 .value
user.name = '李四'

1.3 computed 计算属性(派生数据)

import { ref, computed } from 'vue'

const count = ref(0)
// 只读计算属性
const doubleCount = computed(() => count.value * 2)

2. 监听类 Hook

2.1 watch 监听数据变化

import { ref, watch } from 'vue'

const name = ref('')

// 监听 name
watch(name, (newVal, oldVal) => {
  console.log('新值:', newVal)
}, { immediate: true }) // immediate 立即执行一次

2.2 watchEffect 自动收集依赖

不用指定监听谁,内部用到的响应式变了就执行:

watchEffect(() => {
  console.log(name.value)
})

3. 生命周期 Hook(Vue3 组合式写法)

对应 Vue2 的生命周期,全部是函数形式:

import { 
  onMounted,    // 挂载完成
  onUpdated,    // 更新完成
  onUnmounted   // 卸载销毁
} from 'vue'

// 组件挂载后执行(替代 mounted)
onMounted(() => {
  console.log('组件已渲染到页面')
})

// 组件销毁前执行(清理定时器、监听、事件)
onUnmounted(() => {
  console.log('组件销毁')
})

4. 路由 / 状态库常用(搭配生态)

Vue Router 4 Hook

import { useRoute, useRouter } from 'vue-router'

const route = useRoute()   // 获取当前路由信息、参数
const router = useRouter() // 编程式跳转

console.log(route.path)
router.push('/login')

Pinia 状态库 Hook

import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
console.log(userStore.token)

自定义 Hook(核心:逻辑复用)

规则

  1. 函数名 useXXX 开头;
  2. 内部可以使用所有 Vue 内置 API;
  3. 把需要复用的逻辑抽进去,返回变量 / 方法给组件使用;
  4. 一个 Hook 只做一件事(单一原则)。

1. 新建 Hook 文件 hooks/useWindowWidth.js

// 自定义 Hook:获取并监听浏览器窗口宽度
import { ref, onMounted, onUnmounted } from 'vue'

export function useWindowWidth() {
  // 响应式变量保存窗口宽度
  const windowWidth = ref(window.innerWidth)

  // 更新宽度
  const updateWidth = () => {
    windowWidth.value = window.innerWidth
  }

  // 挂载时监听 resize
  onMounted(() => {
    window.addEventListener('resize', updateWidth)
  })

  // 销毁时移除监听(防止内存泄漏)
  onUnmounted(() => {
    window.removeEventListener('resize', updateWidth)
  })

  // 对外暴露变量
  return { windowWidth }
}

封装「本地存储 localStorage」Hook

hooks/useLocalStorage.js

import { ref, watch } from 'vue'

export function useLocalStorage(key, defaultValue) {
  // 读取本地值
  const stored = localStorage.getItem(key)
  const data = ref(stored ? JSON.parse(stored) : defaultValue)

  // 变化自动同步到 localStorage
  watch(
    data,
    (val) => {
      localStorage.setItem(key, JSON.stringify(val))
    },
    { deep: true }
  )

  return data
}

组件使用

<script setup>
import { useLocalStorage } from '@/hooks/useLocalStorage'

// 读写自动同步 localStorage
const token = useLocalStorage('token', '')
</script>

<template>
  <div>Token:{{ token }}</div>
  <button @click="token = '123456'">修改Token</button>
</template>

实战 3:封装「请求 Loading + 接口」Hook(业务最常用)

// hooks/useRequest.js
import { ref } from 'vue'

export function useRequest(apiFn) {
  const loading = ref(false)
  const data = ref(null)
  const error = ref(null)

  // 执行请求方法
  const run = async (...args) => {
    loading.value = true
    error.value = null
    try {
      const res = await apiFn(...args)
      data.value = res
    } catch (err) {
      error.value = err
    } finally {
      loading.value = false
    }
  }

  return { loading, data, error, run }
}

使用

<script setup>
import { useRequest } from '@/hooks/useRequest'
import { getUserInfo } from '@/api/user'

const { loading, data, run } = useRequest(getUserInfo)

// 调用接口
run()
</script>

<template>
  <div v-if="loading">加载中...</div>
  <div v-else>{{ data?.name }}</div>
</template>

Vue Hook 和 React Hook 对比

  1. 调用时机
    • Vue:可在 setup / 自定义函数任意位置调用,不限制顺序
    • React:必须在顶层,不能在条件、循环里调用,顺序不能变
  2. 响应式
    • Vue:ref/reactive 原生响应,自动依赖收集
    • React:靠 useState/useEffect 手动监听
  3. 生命周期
    • Vue:onMounted 等独立函数,可写多个
    • React:统一在 useEffect 模拟

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor