首页
直播
壁纸
友链
搜索
1
微信小程序支付全链路实战:JSAPI 下单、调起支付、回调验签与退款
266 阅读
2
微信小程序云开发实战:云函数、云数据库与云存储的正确使用姿势
256 阅读
3
微信小程序自定义 tabBar 实战:custom-tab-bar 从适配到深色模式
255 阅读
4
微信小程序 Skyline 渲染引擎实战:worklet 动画从原理到落地
253 阅读
5
微信小程序分包进阶:独立分包、预下载与分包异步化实战
246 阅读
服务器运维
后端技术
前端技术
梯子
数据库
小程序
登录
搜索
标签搜索
fastadmin
Redis
微信小程序
前端开发
RabbitMQ
Go
服务器
codex
buildadmin
小程序
mysql
Nginx
Docker
Vue3
Node.js
MySQL优化
Linux
TypeScript
JWT
PHP
沿途的风景
累计撰写
74
篇文章
累计收到
0
条评论
首页
栏目
服务器运维
后端技术
前端技术
梯子
数据库
小程序
页面
直播
壁纸
友链
搜索到
11
篇与
» Vue3
的结果
2026-03-05
Vue3 Composition API 深度解析:从 ref 到自定义 Hook
前言Vue3 的 Composition API 是对 Options API 的范式升级。它解决了大型组件中逻辑复用和组织的问题,让代码更灵活、更可维护。一、响应式基础1.1 ref vs reactiveimport { ref, reactive, toRefs } from "vue"; // ref:适用于基本类型 const count = ref(0); count.value++; // reactive:适用于对象 const state = reactive({ name: "张三", age: 25, }); // reactive 的陷阱:解构会失去响应性 const { name } = state; // name 不再是响应式 // 解决方案:toRefs const { name: reactiveName } = toRefs(state);1.2 computedimport { ref, computed } from "vue"; const firstName = ref("张"); const lastName = ref("三"); // 只读计算属性 const fullName = computed(() => `${firstName.value}${lastName.value}`); // 可写计算属性 const fullNameWritable = computed({ get() { return `${firstName.value}${lastName.value}`; }, set(newValue: string) { firstName.value = newValue[0]; lastName.value = newValue.slice(1); }, });二、watch 和 watchEffect2.1 watchimport { ref, watch } from "vue"; const keyword = ref(""); // 监听单个 ref watch(keyword, (newVal, oldVal) => { console.log(`关键词从 ${oldVal} 变为 ${newVal}`); }); // 监听多个源 watch([keyword, category], ([newKeyword, newCategory]) => { search(newKeyword, newCategory); }); // 深度监听对象 watch( () => state, (newState) => { saveToStorage(newState); }, { deep: true } );2.2 watchEffectimport { ref, watchEffect } from "vue"; const userId = ref(1); // 自动追踪依赖,立即执行 watchEffect(() => { fetchUser(userId.value); // userId 变化时自动重新执行 });三、自定义 Hook(组合式函数)3.1 useMousePosition// composables/useMousePosition.ts import { ref, onMounted, onUnmounted } from "vue"; export function useMousePosition() { const x = ref(0); const y = ref(0); function update(e: MouseEvent) { x.value = e.pageX; y.value = e.pageY; } onMounted(() => { window.addEventListener("mousemove", update); }); onUnmounted(() => { window.removeEventListener("mousemove", update); }); return { x, y }; }使用:<script setup lang="ts"> import { useMousePosition } from "@/composables/useMousePosition"; const { x, y } = useMousePosition(); </script> <template> <p>鼠标位置: {{ x }}, {{ y }}</p> </template>3.2 useFetch// composables/useFetch.ts import { ref, watchEffect } from "vue"; export function useFetch<T>(url: () => string) { const data = ref<T | null>(null); const error = ref<string | null>(null); const loading = ref(false); watchEffect(async () => { loading.value = true; error.value = null; try { const res = await fetch(url()); if (!res.ok) throw new Error(`HTTP ${res.status}`); data.value = await res.json() as T; } catch (e) { error.value = (e as Error).message; } finally { loading.value = false; } }); return { data, error, loading }; }四、生命周期钩子import { onMounted, onUpdated, onUnmounted, onBeforeMount, onBeforeUpdate, onBeforeUnmount } from "vue"; onBeforeMount(() => { /* 组件挂载前 */ }); onMounted(() => { /* DOM 已挂载 */ }); onBeforeUpdate(() => { /* 响应式数据变更,DOM 更新前 */ }); onUpdated(() => { /* DOM 更新后 */ }); onBeforeUnmount(() => { /* 组件卸载前 */ }); onUnmounted(() => { /* 组件已卸载 */ });五、总结Composition API 的核心优势在于逻辑复用和代码组织。通过自定义 Hook,可以将组件逻辑提取为可复用的函数,告别 Options API 时代 mixin 的命名冲突和数据来源不透明问题。建议在项目中优先使用 <script setup> 语法,配合 TypeScript 获得最佳开发体验。
2026年03月05日
16 阅读
0 评论
0 点赞
1
2
3
0:00