一、前言
上篇懂了"为什么",本篇开始"动手"。选两个最简单的下手:useTitle(响应式改网页标题)和 useToggle(布尔开关)。麻雀虽小五脏俱全——返回值怎么设计、初始值怎么兜底、怎么命名,组合式函数的全部基础规范都在这两个十行函数里。
二、useTitle:让网页标题变成响应式数据
目标 API:const title = useTitle(),改 title.value 页面标签实时变。
先想清楚实现三步:读当前标题作初始值 → 数据变时写回 document.title → 返回数据。
// src/composables/useTitle.js
import { ref, watch } from 'vue'
export function useTitle(newTitle) {
// 初始值:传了就用传的,没传就读当前标题
const title = ref(newTitle ?? document.title)
// 数据变 → 写回浏览器标签
watch(title, (val) => {
document.title = val
}, { immediate: true }) // immediate:进来先同步一次
return title
}
<!– 使用 –>
<template>
<p>页面标签实时变化:</p>
<button @click="title = `(${count} 条未读)我的应用`">模拟新消息</button>
<button @click="title = '我的应用'">清除未读</button>
<p>{{ count }} 条未读</p>
</template>
<script setup>
import { ref } from 'vue'
import { useTitle } from '@/composables/useTitle'
const count = ref(3)
const title = useTitle('我的应用')
</script>
设计复盘(每个细节都有讲究):
【截图位置:点击按钮后浏览器标签页标题变化的效果】
三、useToggle:布尔开关 + 任意两值切换
目标 API:const [state, toggle] = useToggle()——数组解构的返回形式(和 012 篇 toRefs 的对象形式并列,两种都要会)。
// src/composables/useToggle.js
import { ref } from 'vue'
export function useToggle(init = false) {
const state = ref(init)
/**
* 切换状态
* @param {boolean} [value] 可选:直接指定目标值
*/
function toggle(value) {
// 传了值就用传的,没传就取反
state.value = value ?? !state.value
}
return [state, toggle]
}
<template>
<!– 场景 1:开关弹窗 –>
<button @click="toggle()">弹窗开关:{{ open ? '开' : '关' }}</button>
<!– 场景 2:明文/密文切换,直接指定值 –>
<input :type="showPwd ? 'text' : 'password'" v-model="pwd" />
<button @click="toggle(true)">显示明文</button>
<button @click="toggle(false)">隐藏</button>
</template>
<script setup>
import { useToggle } from '@/composables/useToggle'
const [open, toggle] = useToggle() // 弹窗开关
const [showPwd, setPwdVisible] = useToggle(false) // 密码可见性
const pwd = ref('')
</script>
设计复盘:
对象形式返回(项目里统一风格时用):
// 同一逻辑的另一种返回形态
return { state, toggle }
// 使用:const { state, toggle } = useToggle()
数组形式适合"元素少且位置固定";对象形式适合成员多、要按名取用的场景。VueUse 两种混用(简单函数用数组,复杂的用对象),你的项目定死一种即可。
四、进阶:把两个函数组合起来
组合式函数的精髓是可以互相组合。写一个 useDisclosure(弹窗控制器),内部用 useToggle:
// src/composables/useDisclosure.js
import { useToggle } from './useToggle'
/**
* 弹窗/抽屉控制器
* @returns {{ isOpen: import('vue').Ref<boolean>, open: Function, close: Function, toggle: Function }}
*/
export function useDisclosure(init = false) {
const [isOpen, rawToggle] = useToggle(init)
return {
isOpen,
open: () => rawToggle(true),
close: () => rawToggle(false),
toggle: () => rawToggle()
}
}
<template>
<button @click="open">打开确认弹窗</button>
<div v-if="isOpen" class="mask" @click.self="close">
<div class="box">
确定要删除吗?
<button @click="close">取消</button>
<button @click="onConfirm">确定</button>
</div>
</div>
</template>
<script setup>
import { useDisclosure } from '@/composables/useDisclosure'
const { isOpen, open, close } = useDisclosure()
function onConfirm() {
console.log('执行删除')
close()
}
</script>
<style scoped>
.mask { position: fixed; inset: 0; background: rgba(0,0,0,.5);
display: flex; align-items: center; justify-content: center; }
.box { background: #fff; padding: 20px; border-radius: 8px; }
</style>
open / close / toggle 语义分明的弹窗控制器,一个项目里每个弹窗都用它——这就是 031 篇 Teleport 弹窗的官方搭档。函数调用函数,能力不断叠加,这就是"组合式"三个字的含义。
【截图位置:弹窗打开、点遮罩关闭的运行效果】
五、踩坑记录
六、今日小结
- useTitle:ref + watch(immediate) 三件套,返回活 ref 是铁律
- useToggle:[state, toggle] 数组返回便于重命名;value ?? !value 兼容定点设置
- 返回形态二选一:数组(小而固定)/ 对象(成员多),项目内统一
- useDisclosure 示范函数组合函数——"组合式"的真正含义
下篇预告
继续造下一组:useMouse / useWindowSize——第一次在组合式函数里操作 window 事件监听,生命周期清理的模板写法会固化成肌肉记忆。下一篇 037。
网硕互联帮助中心






评论前必须登录!
注册