Code前端首页关于Code前端联系我们

Vue2里computed的get和set到底怎么用?

terry 7小时前 阅读数 9 #Vue
文章标签 Vue2computed

不少刚开始学Vue2的朋友,对computed里的get和set总是有点懵——明明平时只用个函数也能实现计算,那set存在的意义是啥?啥场景必须用set?今天咱们从实际开发里的需求出发,把computed的get和set拆得明明白白,以后遇到类似需求再也不慌~

先搞懂computed里的get是干啥的

平时写computed,最常见的写法是这样:

computed: {
  fullName() {
    return this.firstName + ' ' + this.lastName
  }
}

这种写法其实是get的简写,Vue会自动把这个函数当成computed属性的getter(获取器),它的核心作用是:基于响应式依赖(比如这里的firstName、lastName),动态计算出一个结果,而且Vue给computed做了缓存优化——只要依赖的响应式数据没变化,每次访问fullName时,不会重复执行计算逻辑,直接拿缓存结果,性能更优。

举个实际场景:做用户信息展示模块,姓和名存在data里的firstName、lastName,页面上要显示“全名”,用computed的get来拼接,既保证了全名和姓/名的联动(姓或名改了,全名自动变),又利用缓存减少不必要的计算,这时候只用get就够,因为只是“读”全名这个计算结果。

set什么时候派上用场?

如果只是“读”计算结果,get足够;但要是遇到“写”的场景——也就是需要主动修改computed属性,进而影响它依赖的响应式数据时,set就必须出场了。

举个例子:还是全名的需求,但这次是用户编辑环节——页面上有个输入框,用户要直接输入全名(张三”),你需要把输入的内容拆成“张”(firstName)和“三”(lastName)存到data里,这时候如果直接给fullName赋值(比如this.fullName = '李四'),Vue会报错,因为默认computed只有get,是只读的,这时候就得给computed加上set,让它变成“可写”的。

再延伸个场景:后台返回的用户信息里,地址是“省-市-区”拼接好的字符串,但前端表单里省、市、区是三个下拉框,编辑时,需要把拼接的地址拆分成省、市、区三个字段回显;保存时,又要把三个字段拼成地址字符串传给后台,这时候用computed的address,get负责拼接显示,set负责拆分赋值,就能优雅解决联动问题。

get和set一起用的完整写法

语法长这样:

computed: {
  fullName: {
    // 获取计算结果
    get() {
      return this.firstName + ' ' + this.lastName
    },
    // 当给fullName赋值时触发
    set(newVal) {
      // newVal是赋值时的新值,比如this.fullName = 'Li Si' 时,newVal就是'Li Si'
      const arr = newVal.split(' ')
      this.firstName = arr[0]
      this.lastName = arr[1] || ''
    }
  }
}

这里要注意两个点:

  • get里不需要传参,它自动依赖data里的firstName、lastName,这些数据变了,get会自动重新计算;
  • set里接收一个参数newVal,就是给computed属性赋值时的那个“新值”,在set里,你要做的是把这个新值拆解,去修改它依赖的响应式数据(比如firstName、lastName)。

结合实际交互看:页面上有个输入框<input v-model="fullName" />,用户输入“Wang Wu”后,v-model会触发this.fullName = 'Wang Wu',这时set被调用,newVal是'Wang Wu',拆分后给firstName赋值'Wang',lastName赋值'Wu',firstName或lastName变化时,get又会重新计算fullName,输入框内容也会跟着变——这就实现了“输入全名拆分成姓和名,姓或名变化时全名也变”的双向联动。

常见误区:只用get够不够?

很多新手会疑惑:“我不用set,好像也没毛病啊?” 这得看场景:

  • 纯展示场景(比如用户信息卡片里的全名):只用get完全够,因为不需要修改computed属性,只需要它跟着依赖变。
  • 有交互修改需求(比如编辑时的全名输入框):必须用set!因为如果没写set,直接给computed属性赋值(比如this.fullName = 'XXX'),Vue会抛出“Avoid mutating a computed property directly”的错误——意思是“别直接改计算属性啊,它默认是只读的”。

举个反面例子:如果没写set,硬要做编辑场景,你可能得给输入框绑定@input事件,在事件里手动拆分字符串、修改firstName和lastName,但这样代码会很零碎,不如用computed的set把“拆分-赋值”的逻辑封装起来,代码更简洁,也更符合Vue的响应式设计思想。

实战案例:用get和set优化表单处理

假设做一个“用户资料编辑”页面,需求是:

  • 姓和名分别存在data的firstName、lastName里;
  • 页面上有个“全名”输入框,用户输入全名时,自动拆分到姓和名;
  • 姓或名的输入框变化时,全名输入框也自动更新。

不用computed的set的话,代码会很繁琐:

<input v-model="firstName" placeholder="姓" />
<input v-model="lastName" placeholder="名" />
<input v-model="inputFullName" @input="handleFullNameChange" />
<script>
export default {
  data() {
    return {
      firstName: '',
      lastName: '',
      inputFullName: ''
    }
  },
  watch: {
    // 姓或名变化时,更新全名输入框
    firstName() {
      this.inputFullName = this.firstName + ' ' + this.lastName
    },
    lastName() {
      this.inputFullName = this.firstName + ' ' + this.lastName
    },
  },
  methods: {
    // 全名输入框变化时,拆分到姓和名
    handleFullNameChange(e) {
      const val = e.target.value
      const arr = val.split(' ')
      this.firstName = arr[0]
      this.lastName = arr[1] || ''
    }
  }
}
</script>

但用computed的get和set,代码会简洁很多:

<input v-model="firstName" placeholder="姓" />
<input v-model="lastName" placeholder="名" />
<input v-model="fullName" />
<script>
export default {
  data() {
    return {
      firstName: '',
      lastName: ''
    }
  },
  computed: {
    fullName: {
      get() {
        return this.firstName + ' ' + this.lastName
      },
      set(newVal) {
        const arr = newVal.split(' ')
        this.firstName = arr[0]
        this.lastName = arr[1] || ''
      }
    }
  }
}
</script>

可以看到:

  • 不用额外的watch和methods,computed的get自动处理“姓/名→全名”的联动;
  • set自动处理“全名→姓/名”的拆分赋值;
  • 页面上只需要绑定v-model="fullName",逻辑全被computed封装起来了,代码量少了一半还多,维护性也更高。

和methods、watch的区别里,computed的get/set有啥独特性?

最后再对比下,帮大家彻底理清概念:

  • 和methods比:methods里的函数每次调用都执行,不管依赖变没变;而computed的get有缓存,依赖不变时直接拿结果,性能更好,而且methods主要是“执行动作”,computed是“计算结果”。
  • 和watch比:watch是“监听某个数据变化,执行回调”,属于被动响应;computed的get是“主动根据依赖计算结果”,set是“主动处理赋值时的逻辑”,属于主动管理数据联动,比如watch适合做异步请求、复杂逻辑;computed适合做简单的同步计算+可写控制。

computed的get负责“根据依赖计算结果”,set负责“被赋值时修改依赖”,平时开发里,纯展示用get足够;遇到需要修改computed属性来联动源数据的场景(比如表单编辑、复杂数据拆分/拼接),就得把get和set一起用上,掌握这俩的配合,能让代码更简洁、响应式逻辑更优雅,下次遇到类似需求,别再绕弯路啦~

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门