🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
上个月,我们重构一个老项目,发现一个“祖传组件”:
- 父组件传 props 给子组件
- 子组件再传给孙子
- 孙子改了个状态,通过 $emit 一层层往上抛
- 中央恣意一层改名,整条链就断了……
同事苦笑:“这哪是组件通讯,这是传话游戏。”
实在,Vue 3 早就提供了更优雅、更坚固的通讯方案。
本日我就用 4 种场景 + 对应解法,帮你彻底告别“props drilling”和“emit 地狱”。
先看一张决定图(发起收藏)
注意:不是全部通讯都要用 Pinia! 小范围状态用轻量方案更干净。
姿势 1:父子通讯 —— 老诚实实用 props/emit(但要规范)
这是最底子的,但许多人写得乱:
反面课本:- [/code]准确做法:单一职责 + 语义化定名
- [code]
复制代码本领:用 v-model 代替自界说 update-xxx,模板更轻便:
- [/code][size=5]姿势 2:祖孙通讯 —— 用 provide / inject 跳过中央层[/size]
- 当你须要从 App.vue 直接传数据到深度嵌套的 Button 组件,别再层层传 props!
- [code]// App.vue
- import { provide, ref } from 'vue';
- const theme = ref<'light' | 'dark'>('light');
- provide('THEME', theme); // 提供响应式数据
复制代码- <template>
- <button :>Click me</button>
- </template>
复制代码 关键点:
- 如果 provide 的是 ref 或 reactive,inject 拿到的就是相应式的
- 可以共同 TypeScript 界说 InjectionKey,克制字符串邪术值
- // types.ts
- import { InjectionKey, Ref } from 'vue';
- export const THEME_KEY: InjectionKey<Ref<'light' | 'dark'>> = Symbol('theme');
复制代码 姿势 3:恣意组件通讯 —— 用 Composable 封装共享状态(90% 的人不知道!)
这是 Vue 3 最被低估的本事!
想象:两个不相干的弹窗,须要共享“是否正在提交”状态。
错误做法:把状态提到父组件,或滥用 Pinia
准确做法:写一个 useSubmitState composable:- // composables/useSubmitState.ts
- import { ref } from 'vue';
- const isSubmitting = ref(false);
- export function useSubmitState() {
- const start = () => isSubmitting.value = true;
- const end = () => isSubmitting.value = false;
- return { isSubmitting, start, end };
- }
复制代码 然后在恣意组件中利用: 上风:
- 零依赖(不消 Pinia)
- 天然相应式
- 可测试、可复用
- 作用域清晰(只在须要的组件引入)
姿势 4:全局状态 —— 交给 Pinia,别本身造轮子
当状态涉及:
这时间就该用 Pinia(Vuex 的继任者,Vue 官方保举):- // stores/user.ts
- import { defineStore } from 'pinia';
- export const useUserStore = defineStore('user', () => {
- const profile = ref(null);
- const isLoggedIn = computed(() => !!profile.value);
- const login = async (credentials) => {
- profile.value = await api.login(credentials);
- };
- return { profile, isLoggedIn, login };
- });
复制代码 在组件中:- const userStore = useUserStore();
- userStore.login({ email, password });
复制代码 Pinia 上风:
- Composition API 风格
- 完善 TS 支持
- DevTools 调试友爱
- 服务端渲染(SSR)兼容
总结:什么时间用哪种?
不要:
- 用 $parent / $children(粉碎封装)
- 用 EventBus(Vue 3 已废弃)
- 全部状态都塞进 Pinia(过分计划)
如果对您有所资助,接待您点个关注,我会定时更新技能文档,各人一起讨论学习,一起进步。
免责声明:如果侵犯了您的权益,请联系站长及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金. |