Vue中的全局共享与独立实例
2024年11月10日...大约 2 分钟
Hook
在 Vue 3 中,Hooks 是一种复用逻辑的方式,它允许你以更灵活的方式组织和复用功能,而不需要依赖传统的 mixins 。
Hooks 的设计灵感来自于 React 的 Hook 系统,但在 Vue 中更加自然地与 Composition API 集成。
通过使用 Hooks,你可以轻松地提取出可复用的逻辑,并在多个组件中共享这些逻辑,而不会造成代码污染或复杂化。
Hooks 是函数,通常不依赖 Vue 组件实例,可以在任何地方调用。通过 Hook 可以将逻辑封装到函数中,不仅可以复用,还能在不同的组件中共享。
例如一些常见的 Hooks
- 状态管理 Hooks:管理组件的状态,例如
useCounter
、useToggle
。 - 数据获取 Hooks:封装 API 调用逻辑,例如
useFetch
、useApi
。 - 事件处理 Hooks:处理事件监听,例如
useEventListener
。 - 生命周期 Hooks:封装与生命周期相关的逻辑,例如
useMounted
、useUnmounted
。 - 工具类 Hooks:提供工具函数,例如
useDebounce
、useThrottle
。
例如:一个简单的状态管理 Hook
// hooks/useCounter.js
import { ref } from "vue"
export function useCounter() {
const count = ref(0)
const increment = () => {
count.value++
}
const decrement = () => {
count.value--
}
return {
count,
increment,
decrement,
}
}
<template>
<div>
<p>当前计数:{{ count }}</p>
<button @click="increment">增加</button>
<button @click="decrement">减少</button>
</div>
</template>
<script setup>
import { useCounter } from "@/hooks/useCounter"
const { count, increment, decrement } = useCounter()
</script>
例如:一个事件处理 Hook
// hooks/useWindowSize.js
import { ref, onMounted, onUnmounted } from "vue"
export function useWindowSize() {
const width = ref(window.innerWidth)
const height = ref(window.innerHeight)
const onResize = () => {
width.value = window.innerWidth
height.value = window.innerHeight
}
onMounted(() => window.addEventListener("resize", onResize))
onUnmounted(() => window.removeEventListener("resize", onResize))
return { width, height }
}
<template>
<div>
<p>宽度:{{ width }}px</p>
<p>高度:{{ height }}px</p>
</div>
</template>
<script setup>
import { useWindowSize } from "@/hooks/useWindowSize"
const { width, height } = useWindowSize()
</script>
通常我们将 Hooks 放入
src/hooks/
├── useCounter.js
├── useFetch.js
├── useWindowSize.js
全局共享 Hook
即 Hook 内部的 ref
是在函数外部定义的
// useElec.js
import { ref } from "vue"
const elecInfo = ref(null) // 定义在函数外部,全局共享
const isLoadingElecInfo = ref(false)
export function useElec() {
return { elecInfo, isLoadingElecInfo }
}
这时所有使用 useElec()
的组件都会共享同一个 ref
对象。
在不同组件中引用 elecInfo
时,修改任意一个组件中的 elecInfo
,其他组件中的值也会同步变化。
独立实例 Hook
即 Hook 内部的 ref
是在函数内部定义的。
// useElec.js
import { ref } from "vue"
export function useElec() {
const elecInfo = ref(null) // 定义在函数内部,组件独立
const isLoadingElecInfo = ref(false)
return { elecInfo, isLoadingElecInfo }
}
每次调用 useElec()
时都会创建新的 ref
对象,因此各组件将拥有独立的 elecInfo
实例。
不同组件中引用 elecInfo
时,彼此之间不会相互影响,因为每次调用 useElec()
都会生成一个新的 ref
对象。