Vue warn: Computed property ‘X’ was assigned to but it has no setter の解決方法

「Vue warn: Computed property ‘X’ was assigned to but it has no setter」という警告は、Vue.jsの計算プロパティに直接代入しようとした際に発生します。この警告の原因と解決方法を解説します。
目次
1. 警告が発生する条件
- computedプロパティがgetterのみ定義されている場合
- getter-onlyの計算プロパティに値を代入しようとした場合
- 誤って双方向データバインディングで使用した場合
2. 警告の具体例
以下のコードで、警告が発生します。
export default {
data() {
return {
message: 'Hello World'
};
},
computed: {
upperCaseMessage() {
return this.message.toUpperCase();
}
},
methods: {
updateMessage() {
this.upperCaseMessage = 'NEW MESSAGE'; // 警告が発生する
}
}
};
3. computedプロパティの仕組み
computedプロパティはデフォルトでgetterのみを提供します。そのため、代入操作は無効です。
4. setterを追加する方法
getterとsetterの両方を定義することで、代入操作を可能にします。
export default {
data() {
return {
message: 'Hello World'
};
},
computed: {
upperCaseMessage: {
get() {
return this.message.toUpperCase();
},
set(newValue) {
this.message = newValue.toLowerCase();
}
}
},
methods: {
updateMessage() {
this.upperCaseMessage = 'NEW MESSAGE'; // setterが呼び出される
}
}
};
5. computedプロパティで双方向バインディングを使用するケース
フォーム要素とcomputedプロパティを双方向にバインディングする場合、setterが必要です。
export default {
data() {
return {
firstName: '',
lastName: ''
};
},
computed: {
fullName: {
get() {
return `${this.firstName} ${this.lastName}`;
},
set(value) {
const names = value.split(' ');
this.firstName = names[0];
this.lastName = names[1] || '';
}
}
}
};
6. setterがない場合の解決策
computedプロパティが必要な場合でもsetterを追加したくない場合は、代入操作を避けます。
export default {
data() {
return {
message: 'Hello World'
};
},
computed: {
upperCaseMessage() {
return this.message.toUpperCase();
}
},
methods: {
updateMessage() {
this.message = 'new message'; // messageに直接代入
}
}
};
7. 双方向データバインディングを避ける
computedプロパティを一方向データフローで使用し、フォーム要素に直接バインディングするのが適切な場合もあります。
<input v-model="message" />
<p>{{ message.toUpperCase() }}</p>
8. コンポーネント間での注意点
子コンポーネントにpropsとして渡される値にsetterは追加できません。子コンポーネントで変更が必要な場合、イベントを発火して親コンポーネントで更新します。
// 子コンポーネント
export default {
props: ['value'],
methods: {
updateValue(newValue) {
this.$emit('input', newValue);
}
}
};
9. Vue 3でのreactiveの利用
Vue 3では、reactiveを活用して双方向データバインディングを実現する方法があります。
import { reactive, computed } from 'vue';
export default {
setup() {
const state = reactive({
message: 'Hello World'
});
const upperCaseMessage = computed({
get: () => state.message.toUpperCase(),
set: (value) => {
state.message = value.toLowerCase();
}
});
return { state, upperCaseMessage };
}
};
10. readonlyでの利用
計算プロパティが読み取り専用の場合、readonlyを使用して明示的に宣言することもできます。
import { readonly, computed } from 'vue';
export default {
setup() {
const message = 'Hello World';
const upperCaseMessage = readonly(computed(() => message.toUpperCase()));
return { upperCaseMessage };
}
};
11. 結論
「Vue warn: Computed property ‘X’ was assigned to but it has no setter」は、computedプロパティに値を代入しようとした場合に発生します。getterとsetterの両方を適切に設定するか、代入を避けて設計を見直すことで解決できます。
-
前の記事
Rubyのエラー『NameError: undefined local variable or method』の解決方法 2025.07.04
-
次の記事
Google Colaboratory セルを削除するショートカットキー 2025.07.04
コメントを書く