Vue.js - 计算属性的getter和setter方法详解(给计算属性设置值)
作者:hangge | 2026-03-13 08:52
计算属性是 Vue 最常用的特性之一。它们看起来像属性,但本质上是基于它们的依赖进行缓存的函数。通常我们写的计算属性只有 getter(只读),但在 Vue 中我们也可以为计算属性提供 setter,从而实现“可写的计算属性”。这个非常适合把多个数据源双向绑定为一个逻辑字段(例如表单中的合成字段)或将 UI 变更回写到多个数据源上。
(2)运行结果如下:
(2)运行效果如下,默认 firstName 和 lastName 变量值分别为“张”和“三”。点击按钮后将 fullName 计算属性的值改为“李四”,此时会同步将 firstName 和 lastName 变量值设置为“李”和“四”

(2)父组件代码如下:
(2)运行结果如下,当子组件的 input 输入框内容修改时,会自动更新父组件传入的对象值。
1,基本介绍
Vue.js 内部会根据传递参数类型采用不用的处理方式:
- 传递的如果是函数,则直接作为 getter 函数处理。
- 传递的如果是对象,则从中获取 getter 和 setter 函数,并进行相应处理。
2,只写 getter 的计算属性
(1)最常见计算属性场景就是只写 getter。
<template>
<div class="my-component">
<p>firstName: {{ firstName }}</p>
<p>lastName: {{ lastName }}</p>
<p>fullName: {{ fullName }}</p>
</div>
</template>
<script>
export default {
name: 'MyComponent',
data() {
return {
firstName: '张',
lastName: '三'
}
},
computed: {
fullName() {
return this.firstName + this.lastName;
}
},
methods: {
}
}
</script>
(2)运行结果如下:

3,带 getter 和 setter 的计算属性
(1)下面样例用对象形式定义计算属性,实现从 UI 修改 fullName 并把拆分结果回写到 firstName 和 lastName。
<template>
<div class="my-component">
<p>firstName: {{ firstName }}</p>
<p>lastName: {{ lastName }}</p>
<p>fullName: {{ fullName }}</p>
<button @click="changeName">修改fullName</button>
</div>
</template>
<script>
export default {
name: 'MyComponent',
data() {
return {
firstName: '张',
lastName: '三'
}
},
computed: {
fullName: {
get() {
return this.firstName + this.lastName;
},
set(value) {
this.firstName = value.charAt(0) || '';
this.lastName = value.slice(1) || '';
}
}
},
methods: {
changeName() {
this.fullName = '李四'
}
}
}
</script>
(2)运行效果如下,默认 firstName 和 lastName 变量值分别为“张”和“三”。点击按钮后将 fullName 计算属性的值改为“李四”,此时会同步将 firstName 和 lastName 变量值设置为“李”和“四”

附:带有 setter 方法的计算属性使用场景示例
1,表单中“合成字段”的双向绑定示例
(1)下面是样例有 price(数字)和 unit(字符串)这两个变量,需要一个展示为类似“100 元”的输入框,并且用户可直接编辑。
<template>
<div class="my-component">
<p>price:{{ price }}</p>
<p>unit:{{ unit }}</p>
<input v-model="priceText" />
</div>
</template>
<script>
export default {
name: 'MyComponent',
data() {
return { price: 100, unit: '元' }
},
computed: {
priceText: {
get() {
return `${this.price} ${this.unit}`;
},
set(value) {
// 假设用户输入 "200 元" 或 "200"
const num = parseFloat(value);
if (!isNaN(num)) this.price = num;
// unit 保持不变或从输入中判断(这里简化处理)
}
}
},
methods: {
}
}
</script>
(2)运行效果如下,默认 input 输入框的值为“100 元”。我们可以修改 input 输入框里面金额,会同步更新 price 变量值。

2,在组件中实现 v-model 的“代理”
(1)父组件传入 value,子组件希望在内部用合成字段并回写。下面是子组件 CompositeInput.vue 代码:
<template>
<div>
<input v-model="proxy" />
</div>
</template>
<script>
export default {
name: 'CompositeInput',
// v-model 默认使用 prop: value + event: input
props: {
value: {
type: Object,
required: true,
// 如 { a: "100", b: "200" }
}
},
computed: {
proxy: {
get() {
// 将父组件传入的对象合成一个字符串
return `${this.value.a}-${this.value.b}`;
},
set(val) {
// 将用户输入的字符串拆分回对象
const [a, b] = val.split("-");
// 通知父组件更新 value(标准 v-model 回写方式)
this.$emit("input", {
a: a || "",
b: b || ""
});
}
}
},
}
</script>
(2)父组件代码如下:
<template>
<div class="my-component">
<CompositeInput v-model="formData" />
<p>a: {{ formData.a }}</p>
<p>b: {{ formData.b }}</p>
</div>
</template>
<script>
import CompositeInput from './CompositeInput.vue';
export default {
name: 'MyView',
components: {
CompositeInput
},
data() {
return {
formData: {
a: "100",
b: "200"
}
}
},
methods: {
}
}
</script>
(2)运行结果如下,当子组件的 input 输入框内容修改时,会自动更新父组件传入的对象值。

全部评论(0)