Vue组合式API如何正确解构props不会丢失响应性

 更新时间:2024年01月15日 10:28:05   作者:人猫神话 大家的林语冰  
响应式 API 赋予了组合式 API 一大坨可能性的同时,代码精简,虽然但是,我们应该意识到响应性的某些陷阱,比如丢失响应性,在本文中,我们将学习如何正确解构 Vue 组件的 props,使得 props 不会丢失响应性

解构 props

编译器宏 defineProps() 可以辅助读写提供给 <script setup> 中的组件的 props

上述示例中,props 是一个响应式对象,包含了提供给组件的 props。如果组件 props 变化了,props 响应式对象也会随之变化。

读写 props 对象时,我们要做的第一件事可能是,解构 props 对象,然后读写各个属性。但当我学习 Vue 组合式 API 时,令我大吃一惊的是,解构的 props 丢失了响应性!

让我们来看一个例子。下述组件 <EvenOdd :count="5"> 接受 count 属性作为数字,并显示一条消息,无论 count 是偶数还是奇数。

在解构 props 对象 const { count } = defineProps() 之后,访问该 count 属性:

单击几次增加按钮。您会注意到,尽管 count 属性不断累加,但 "The number is even" 消息始终保持不变。

当解构 props 对象 const { count } = defineProps() 时,响应性就会丢失。

响应性之所以会丢失,是因为在解构时 count 变异为具有原始值的变量(一个平平无奇的数字罢了)。但 Vue 的响应性不能直接作用于原始值:Vue 必须诉诸 ref 或响应式对象。

粉丝请注意,在 Vue 中将原始值直接赋值给变量时要小心:此乃丢失响应性的前提。

解决方案 1:使用“props”对象

第一个显而易见的解决方案是,不要解构 props 对象,并使用属性读写器直接读写 props: props.count

上述示例中,读写 computed() 内的 props.count 可以在 props.count 变更时保留响应性。props 对象是响应式的,对其进行任何变更都会被正确追踪。

这种方案的短板是,我们必须始终使用属性读写器(比如 props.count)来读写 <script setup 中的 prop

解决方案 2:使用 toRefs() 辅助函数

如果您阅读至此,我敢打赌您是解构赋值的忠实粉丝,并且没有它就活不下去。

问题不大,那么您可以有意识地将 props 对象的每个属性转换为 ref,来保留解构 props 的响应性。Vue 提供了一个特殊的辅助函数 toRefs(reactiveObject) 来精准完成此操作。

其工作机制如下:

toRefs(props) 返回一个对象,其中每个属性都是对相应 prop 的 ref

现在解构 const { count } = toRefs(props) 是安全的,因为 count 是基于 count 属性的 ref。现在,每次 count 属性变更时,count 的 ref 都会响应属性更改。

将 count 作为 ref,在 computed() 内,我们必须使用 count.value 读写 prop 的值(因为 count.value 是我们读写 ref 的值的方式)。

我发现此方案可以方便地将 prop ref 作为参数传递给组合式函数:比如 useMyComposable(count),并且不会丢失响应性。

否则,我会坚持之前的方案,直接使用 props 对象读写 prop

总结

粉丝请注意,通过应用解构 const { propA, propB } = defineProps(),我们会丢失 props 的响应性。

解决响应性丢失的方案主要有两种:

  • 不解构 props,而是诉诸属性读写器直接读写 props:比如 props.xxx/props.cat

  • 有意识地使用 props 作为 refs 的对象:const { propA, propB } = toRefs(props)。这保留了解构后的响应性。然后我们可以将属性作为独立 ref 读写,比如 propsA.value/propB.value 等。

免责声明

本文属于是语冰的直男翻译了属于是,略有删改,仅供粉丝参考,英文原味版请传送 How to Destructure Props in Vue (Composition API)

以上就是Vue组合式API如何正确解构props不会丢失响应性的详细内容,更多关于Vue组合式API解构props的资料请关注脚本之家其它相关文章!

相关文章

  • Element-UI 多个el-upload组件自定义上传不用上传url并且携带自定义传参(文件序号)

    Element-UI 多个el-upload组件自定义上传不用上传url并且携带自定义传参(文件序号)

    有多个upload组件,每个都需要单独上传获取文件(JS File类型),不需要action上传到指定url,自定义上传动作和http操作,下面通过本文给大家分享Element-UI 多个el-upload组件自定义上传不用上传url并且携带自定义传参(文件序号),感兴趣的朋友一起看看吧
    2024-06-06
  • vue中v-model和响应式的实现原理解析

    vue中v-model和响应式的实现原理解析

    这篇文章主要介绍了vue中v-model和响应式的实现原理,通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • 前端vue如何监听对象或者数组某个属性的变化详解

    前端vue如何监听对象或者数组某个属性的变化详解

    这篇文章主要给大家介绍了关于前端vue如何监听对象或者数组某个属性的变化的相关资料,在Vue中你可以使用watch或者computed来监听对象或数组某个属性的变化,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-03-03
  • vue 路由视图 router-view嵌套跳转的实现

    vue 路由视图 router-view嵌套跳转的实现

    这篇文章主要介绍了vue 路由视图 router-view嵌套跳转,主要实现的内容有制作一个登录页面,跳转到首页,首页包含菜单栏、顶部导航栏、主体,标准的后台网页格式,菜单点击显示不同的页面,感兴趣的小伙伴请参考下面文章内容
    2021-09-09
  • vue使用driver.js完成页面引导功能的示例详解

    vue使用driver.js完成页面引导功能的示例详解

    在Vue中,driver.js通常是指用于实现用户引导和教程功能的JavaScript库,它可以帮助开发者在应用程序中创建交互式的引导和教程,以引导用户了解应用程序的不同功能和界面,本文就简单的给大家介绍一下vue如何使用driver.js完成页面引导功能
    2023-08-08
  • Vue组件高级通讯之$attrs与$listeners

    Vue组件高级通讯之$attrs与$listeners

    这篇文章主要为大家介绍了Vue组件高级通讯之$attrs与$listeners使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • vue组件详解之使用slot分发内容

    vue组件详解之使用slot分发内容

    这篇文章主要介绍了vue组件详解之使用slot分发内容及Vue组件中slot的用法,需要的朋友可以参考下
    2018-04-04
  • 基于electron+vue3+ts搭建桌面端应用并且可以热更新

    基于electron+vue3+ts搭建桌面端应用并且可以热更新

    这篇文章主要为大家详细介绍了如何基于electron+vue3+ts搭建桌面端应用并且可以热更新,文中的示例代码讲解详细,感兴趣的小伙伴可以参考下
    2023-10-10
  • vue组件传递对象中实现单向绑定的示例

    vue组件传递对象中实现单向绑定的示例

    下面小编就为大家分享一篇vue组件传递对象中实现单向绑定的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • vue按需加载实例详解

    vue按需加载实例详解

    在本篇文章里小编给大家整理的是关于vue按需加载实例的相关知识点内容,有需要的朋友们可以学习参考下。
    2019-09-09

最新评论