You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3中给可写计算属性赋值时为什么必须使用.value?

在Vue可写计算属性章节给出的示例代码如下:

<script setup>
import { ref, computed } from 'vue'

const firstName = ref('John')
const lastName = ref('Doe')

const fullName = computed({
  // getter
  get() {
    return firstName.value + ' ' + lastName.value
  },
  // setter
  set(newValue) {
    // 此处使用了解构赋值语法
    [firstName.value, lastName.value] = newValue.split(' ')
  }
})
</script>

该计算属性的正确赋值方式为:

fullName.value = 'John Doe'
问题解答

核心结论

不是。必须通过.value赋值的要求,和getter、setter内部是否使用ref()创建的响应式对象没有任何关系。

具体原因

  • 不管是只读计算属性还是可写计算属性,computed()的返回值本身就是一个标准的Ref类型实例,这个返回规则是固定的,和计算属性内部的逻辑无关。
  • 所有Ref类型的响应式数据,在<script>块的普通JavaScript逻辑里读写值,都必须通过.value属性操作。这是Ref的基础设计:JavaScript的原始类型不支持引用传递,Vue必须把值包裹在带.value属性的对象上,才能追踪值的读写动作,触发对应的响应式更新、以及你自定义的get/set逻辑。
  • 如果直接给计算属性变量赋值(比如写fullName = 'John Doe'),本质是直接覆盖了fullName变量的引用,你定义的setter根本不会被执行,自然不会生效,这和计算属性内部有没有用到其他ref没有关联。

反例验证

哪怕可写计算属性内部完全不依赖任何ref()创建的响应式对象,修改时依然必须走.value才能触发setter:

import { computed } from 'vue'

// 内部完全没有使用ref
const demo = computed({
  get() {
    return window.__demo_val__ ?? 'init'
  },
  set(newVal) {
    console.log('setter被触发,新值:', newVal)
    window.__demo_val__ = newVal
  }
})

// 正确写法:触发setter,控制台打印日志
demo.value = 'test'

// 错误写法:直接覆盖变量,setter完全不执行,没有任何效果
// demo = 'test'

补充说明

只有两种场景不需要写.value访问Ref:

  • 在Vue模板中使用Ref时,Vue会自动做顶层解包
  • 把Ref挂载到reactive()创建的响应式对象属性上时,访问该属性会自动解包

内容的提问来源于stack exchange,提问作者Skeletor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 01:30:28