【译】Vue 模式:诉诸 Vue 3 组合式 API 赋能响应式父子通信

大家好,这里是大家的林语冰。今天分享的是 Vue 官方周报安利的一篇博客。

免责声明

本文属于是语冰的直男翻译了属于是,仅供粉丝参考,英文原味版请临幸 Vue.js Patterns: Using Vue.js 3 Composition API for Reactive Parent to Child Communication。

不同于 React,Vue 围绕响应式系统做"圆周运动"。在本文中,我们将探讨如何使用 Vue 3 组合式 API 创建响应式父子通信。

用例如下:父组件需要将数据传递给子组件。祂使用 Props 实现。子组件需要接收这个外部数据作为其初始状态,但也能在内部变更祂,举个栗子:文本输入元素的双向数据绑定。

我们在实现时面临的限制如下:

  • prop 被设计为不可变属性。子组件不该改变祂从父组件接收的数据。
  • Ref 是可变数据,且允许您设置初始数据,比如 const content = ref(props.content),但最终可能是一个坑,这取决于您如何使用它们。

Ref 有什么问题?

Ref 是 Vue 响应式系统的一部分。祂们用于创建响应式数据,并且是 Vue 3 组合式 API 妥当的构建区块。

虽然但是,根据我见过的大多数指南,可能您使用祂们的方式对于已定义用例没有帮助。

请考虑下列父组件的代码:

在子组件中,您可能会考虑将 ref 绑定到源自父组件的 props 初始值,以此来使用 ref,如下所示:

这是一段合法的代码,并且就技术而言可以奏效,但是您必须了解 Vue 的生命周期 hook 才能理解为什么这绝非最佳实践。

在此组件的 setup 手法中,ref() 当且仅当组件挂载时会调用一次。这意味着,如果父组件更改 content prop,子组件无法得知该更改。

Ref 的正确打开方式是什么?watch 来援救!

此问题的解决方案是使用 watch() 函数或其更智能的同胞函数:watchEffect()。类似于 Ref,watch 函数是 Vue 响应式系统的一部分,且允许您监测更改响应式对象的变化,而不用顾虑组件的生命周期 hook。

以下是完整的代码示例。

我们将表演如何将默认初始值从父组件传递到子组件,并将其设置为使用 Vuetify 3 和 Vue 组合式 API 的值,同时启动双向绑定。

父组件定义如下,附带传递给子组件的 content prop,且该属性可能被父组件根据其自身状态动态更改:

在子组件中,我们会定义一个文本输入元素,该元素使用 Vue 的 v-model 指令绑定到一个内容引用。这将允许我们更改子组件中 content ref 的值,实现我们想要的双向绑定。

这也允许父组件更改 content prop 的值,这将反映在子组件中。

为了让子组件知道传递给祂的 props 的变化,我们会使用 watchEffect() 函数来监测 content prop 的变化。这将允许我们更新 content ref 的值,该值会反映在子组件中。

将以下代码添加到全局作用域中子组件的 content 变量定义旁边:

让我们解释一下此处 watch() 函数的行为。

您在此处看到的 watch 函数是 Vue 组合式 API 的一部分。其目的是观察特定响应源的变化并做出反应。祂可以是简单的响应式引用(比如 ref),也可以是返回响应源的函数。

祂的工作机制如下:

  • () => props.content:这叫做"源"函数。祂应该返回您想监测的值。在本例中,祂是从 props 传递过来的 content 值。
  • () => { content.value = props.content }:这是源更改时执行的回调函数。在本例中,祂将 props.content 的值赋值给 content ref。

您还可以传递额外的第三个参数选项对象,比如 { immediate: true },这意味着回调应该在创建 watch 之后立即运行,甚至在源更改之前。对于在设置 watch 时您希望初始运行回调的情况,这很有用。

我们可以使用更精简的 watchEffect() 函数来代替,也能达到相同的结果。每次 content prop 水合(hydrate)时都会调用 watchEffect() 函数,并更新 content ref 的值,这将反映在子组件中。

粉丝福利:脱离 setup 语法糖使用此模式

这是对上述内容的通用重写,但不使用 setup 脚本手法,用于演示如何使用 Vue 3 组合式 API 来实现我们的用例:

在这个例子中,initialData 是父组件传递过来的 prop。响应式变量 data 是 initialData 的局部拷贝。watchEffect 函数用于在 initialData 更改时更新 data,确保 data 始终以 initialData 的当前值开始。

由于 data 是局部拷贝,因此祂可以在子组件内自由变更,而不会影响父组件中 prop 的值。

您现在收看的是直男翻译系列,学废了的小伙伴可以点赞友情赞助本系列,我们每天佛系投稿,欢迎关注和订阅最新动态。谢谢大家的彼芯,掰掰~

相关推荐
雪芽蓝域zzs9 小时前
第 2 节:基础扩展 - 下拉弹窗常用原生属性
vue.js·elementui
xxwl58520 小时前
vue3的入门学习
前端·vue.js·学习
web打印社区20 小时前
政务办事大厅:叫号小票、办理回执网页怎么静默出纸
前端·javascript·vue.js·pdf·html·政务
斯内普吖21 小时前
(开源)水果蔬菜商城实战指南 基于 Java + SSM + Vue + MySQL
java·vue.js·mysql·开源
ss2731 天前
AI全栈实战 | 2.2-02 React 思维模型:数据不可变 vs Vue 数据可变,两种哲学把复杂度推给谁
前端·vue.js·react.js
天衍四九-1 天前
Docker Compose企业实战系列(三):Vue/React前端项目容器化完整部署
前端·vue.js·docker
墨鱼老师1 天前
SpringBoot+Vue 毕设项目开发踩坑记录(前后端分离)
vue.js·spring boot·毕业设计·课程设计·前后端分离·java 毕设
雪芽蓝域zzs1 天前
Vue3 + Element Plus el-select 下拉弹窗
vue.js·elementui
Wx-bishekaifayuan1 天前
springboot房屋租赁系统11574-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·sql·spring·课程设计
小白的码BUG之路1 天前
Docker -- 构建nginx镜像,启动vue项目
vue.js·nginx·docker