Vue.js 3 - Composition API使用详解10(封装Hook函数实现代码逻辑复用)
作者:hangge | 2026-05-08 08:38
之前我演示了如何使用 Mixin 混入实现 Options API 中代码的逻辑封装和复用(点击查看),但这种方式存在来源不清晰、命名冲突风险高、逻辑耦合严重以及难以追踪数据来源等问题,在组件复杂度提升后,代码的可维护性和可读性都会明显下降。
而在 Composition API 中,我们可以将同一个关注点的逻辑代码封装到一个函数中,该函数通常约定以 use 为前缀命名,比如 useCounter。以 use 开头的函数,我们称之为自定义 Hook 函数,它通过返回响应式数据和操作方法,将状态与行为显式暴露给使用者,逻辑来源清晰、组合方式灵活,并且天然支持数据响应式与生命周期管理。
十、通过 Hook 函数实现代码逻辑的封装和复用
1,计数器样例
(1)首先我们创建一个 useCounter.js 文件,将计数器的代码逻辑封装到一个 useCounte 函数中。
import { ref, computed } from "vue";
export default function useCounter() {
const counter = ref(100);
const doubleCounter = computed(() => counter.value * 2);
const increment = () => counter.value++;
const decrement = () => counter.value--;
return {
counter,
doubleCounter,
increment,
decrement,
};
}
(2)然后我们的组件中就可以导入 useCounter 自定义 Hook 函数,并在 setup 中调用该函数,这样便可以获取到返回的响应式数据和事件函数,并返回给模板使用。
<template>
<div>
<div>当前计数: {{ counter }}</div>
<div>当前计数*2: {{ doubleCounter }}</div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>
</template>
<script>
import useCounter from './useCounter'
export default {
setup() {
// 计数器的代码逻辑抽取到useCounter hook 中了
const { counter, doubleCounter, increment, decrement } = useCounter()
return { counter, doubleCounter, increment, decrement }
}
}
</script>
(3)运行效果如下图所示:

2,修改网页标题样例
(1)首先我们创建一个 useTitle.js 文件,将修改网页标题的代码逻辑封装到一个匿名函数中。
import { ref, watch } from 'vue';
// 使用匿名函数,并该函数需接收一个参数
export default function(title = "默认的title") {
const titleRef = ref(title);
// 侦听titleRef变化,一旦被修改就更新
watch(titleRef, (newValue) => {
document.title = newValue
}, {
immediate: true // 侦听的回调函数先执行一次
})
return titleRef
}
(2)然后在我们的组件中导入自定义 Hook 函数 useTitle,然后在 setup 函数中调用 useTitle 函数, 将页面标题初始化为“航歌”。之后,经过 3 秒钟的等待,页面标题就会被改为 hangge.com。
<template>
<div>
</div>
</template>
<script>
import useTitle from './useTitle'
export default {
setup() {
// 修改网页的标题
const titleRef = useTitle("航歌");
setTimeout(() => {
// 3秒后将标题由航歌改为hangge.com
titleRef.value = "hanggge.com"
}, 3000);
return {}
}
}
</script>
(3)在浏览器中可看到页面标题在 3 秒后由“航歌”变为“hanggge.com”。

3,监听页面滚动位置样例
(1)首先我们创建一个 useScrollPosition.js 文件,将监听页面滚动位置的代码逻辑封装到一个 useScrollPosition 函数中。
import { ref } from 'vue';
// 自定义 useScrollPosition Hook函数
export default function useScrollPosition() {
const scrollX = ref(0);
const scrollY = ref(0);
document.addEventListener("scroll", () => {
scrollX.value = window.scrollX;
scrollY.value = window.scrollY;
});
return {scrollX, scrollY} // 返回响应式数据
}
(2)导入 useScrollPosition 函数,接着在 setup 中调用 useScrollPosition 函数, 获取到当前滚动的值。如果滚动页面了,那么 useScrollPosition 函数会监听到并修改 scrolIX 和 scrollY 响应式变量的值,同时更新页面。
<template>
<div>
<!-- 显示页面滚动位置 -->
<p style="width: 3000px;height: 5000px;">
width:3000px height:5000px的,模拟页面滚动
</p>
<div style="position: fixed;top:20px;right:20px">
<div class="scroll-x">scrollX: {{ scrollX }}</div>
<div class="scroll-y">scrollY: {{ scrollY }}</div>
</div>
</div>
</template>
<script>
import useScrollPosition from './useScrollPosition'
export default {
setup() {
// 监听页面滚动位置
const { scrollX, scrollY } = useScrollPosition();
return { scrollX, scrollY }
}
}
</script>
(3)浏览器中滚动网页时,页面右上角的 scrollX 和 scrollY 能显示当前滚动的位置。

全部评论(0)