为什么在Vue3 setup()中直接解构props会丢失响应性详解

 更新时间:2026年05月29日 11:10:54   作者:用户3905133219288  
props是响应式的,当传入新的prop时,它将被更新,因为props是响应式的,这篇文章主要介绍了为什么在Vue3 setup()中直接解构props会丢失响应性的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

很多使用 Vue3 的朋友都遇到过一个问题:在 setup() 函数里直接解构 props,数据就不再响应了。这是为什么呢?

我们先看一个例子。假设我们有一个组件,它接收一个 user 属性。在 setup() 里我们可能会这样写:

export default {
  props: ['user'],
  setup(props) {
    const { name } = props.user
    return { name }
  }
}

这样写看起来没问题,但实际上,name 已经失去了响应性。父组件更新 user 时,这里的 name 不会跟着变。

原因:理解 Vue3 的响应式原理

要明白原因,得先知道 Vue3 的响应式原理。Vue3 用 Proxy 来追踪数据变化。props 本身是响应式的,但当你解构出 props.user.name 时,你拿到的是一个普通的值。这个值和原来的响应式数据断开了联系。

一个比喻

就像你有一根水管,水在水管里流动。你把水接出来放到杯子里,水还在杯子里。但水管里再流动的水,就和杯子里的水没关系了。

Vue3 的响应式系统也是这样工作的。它只能追踪那些被 reactive 或 ref 包裹的数据。直接解构出来的值,只是一个普通的 JavaScript 值,系统不知道这个值需要被追踪。

正确的做法是什么?

那么,正确的做法是什么呢?有两种方法。

方法一:避免提前解构

不要提前解构,在模板里直接使用 props.user.name。这样就能保持响应性。

方法二:使用toRefs

import { toRefs } from 'vue'

export default {
  props: ['user'],
  setup(props) {
    const { user } = toRefs(props)
    const name = user.value.name
    return { name }
  }
}

toRefs 会把响应式对象的每个属性都转成 ref。这样解构出来的属性还是响应式的。

注意细节

toRefs 处理的是 props 本身,不是 props.user。因为 props 才是响应式对象,props.user 可能只是一个普通对象。

如果你需要解构 props.user 里的属性,可以这样写:

import { toRefs, reactive } from 'vue'

export default {
  props: ['user'],
  setup(props) {
    const user = reactive({ ...props.user })
    const { name } = toRefs(user)
    return { name }
  }
}

先用 reactive 包裹,再用 toRefs 解构。这样 name 就是响应式的了。

特殊情况:将props值传递给函数

还有一种情况要注意。有些时候,你解构 props 是为了传值给其他函数。比如:

setup(props) {
  const { id } = props
  fetchData(id)
}

这样写,id 变化时,fetchData 不会重新执行,因为这里的 id 只是一个普通值。

正确的写法是用 watch 或 watchEffect

import { watch } from 'vue'

setup(props) {
  watch(
    () => props.id,
    (newId) => {
      fetchData(newId)
    }
  )
}

这样,props.id 变化时,fetchData 就会用新的 id 重新执行。

总结

直接解构 props 会丢失响应性,因为解构出来的是普通值。要保持响应性,可以:

  1. 在模板里直接使用props.xxx
  2. 用 toRefs 处理后再解构
  3. 需要响应式地使用 props 值时,记得用 watch 或 watchEffect

相关文章

  • 解决element-ui中Popconfirm气泡确认框的事件不生效问题

    解决element-ui中Popconfirm气泡确认框的事件不生效问题

    这篇文章主要介绍了解决element-ui中Popconfirm气泡确认框的事件不生效问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • Vue项目中解决数字精度丢失问题

    Vue项目中解决数字精度丢失问题

    我们知道,浮点类型的数据,在计算机中是以二进制的方式存储的,但是表示的数据也有个上限和下限,当超过限制 ,在计算机上显示只能取最接近的限值, 数字解析精度丢失说的就是这个现象,所以本文给大家介绍了Vue项目中解决数字精度丢失问题的解决,需要的朋友可以参考下
    2024-02-02
  • vue.js指令v-model实现方法

    vue.js指令v-model实现方法

    这篇文章主要为大家详细介绍了vue.js指令v-model实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • vue.js基于ElementUI封装了CRUD的弹框组件

    vue.js基于ElementUI封装了CRUD的弹框组件

    这篇文章主要介绍了vue.js基于ElementUI封装了CRUD的弹框组件,问咋会给你围绕主题展开详细的内容介绍,感兴趣的小伙伴可以参考一下
    2022-07-07
  • Ant Design Vue 添加区分中英文的长度校验功能

    Ant Design Vue 添加区分中英文的长度校验功能

    这篇文章主要介绍了Ant Design Vue 添加区分中英文的长度校验功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下功能,
    2020-01-01
  • vue3结合ts从零实现vueuse的useRouteQuery方法

    vue3结合ts从零实现vueuse的useRouteQuery方法

    这篇文章主要为大家详细介绍了如何使用vue3与ts从零实现一个类vueuse的useRouteQuery方法,并解决vueuse的useRouteQuery方法存在的一些问题,感兴趣的可以了解下
    2024-03-03
  • vue实现分页组件

    vue实现分页组件

    这篇文章主要为大家详细介绍了vue实现分页组件的具体代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • uniapp+Vue实现App端用户每日弹出签到弹窗功能

    uniapp+Vue实现App端用户每日弹出签到弹窗功能

    用户签到这个功能是很多APP、小程序等都具备的,也是其成长体系中的重要环节,这篇文章主要介绍了uniapp+Vue实现App端用户每日弹出签到弹窗功能的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2026-05-05
  • vue实现图片预览组件封装与使用

    vue实现图片预览组件封装与使用

    这篇文章主要为大家详细介绍了vue实现图片预览组件封装与使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • vue中的公共方法调用方式

    vue中的公共方法调用方式

    这篇文章主要介绍了vue中的公共方法调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09

最新评论