无法在 Vue.js 中将对象 属性 设置为反应式
Can't set object property as reactive in Vue.js
我有一个文件 vue 组件和一个 属性 'todo-item' 这种结构
{
id:1,
text:'Buy tickets',
isDone: false,
person:'Boss',
location:'Boryspil',
childTask:null,
},
并且我计算了属性:
computed:{
hasLocation(){
return this.todoItem.location;
},
hasPerson(){
return this.todoItem.person;
},
hasChildTask(){
return this.todoItem.childTask;
},
hasParentTask(){
return true;
},
}
而且我想让所有对象属性都具有反应性,但是当我在方法中更改属性时:
deletePerson(){
this.$set(this.todoItem, 'person', null);
console.log(this.hasPerson);
console.log(this.todoItem.person);
},
todoItem.person 仍然没有反应,this.hasPerson 有旧值,this.todoItemPerson 显示空值。
我试图让它们对 created
方法有反应,但它仍然没有反应。
这是按组件整体js代码,没有模板,简称css:
<script>
import HoveredChip from "@/components/HoveredChip";
import {mapMutations} from 'vuex';
export default {
name: "TodoItem",
components: {HoveredChip},
props:['todo-item'],
data() {
return{
isActive : true,
}
},
computed:{
hasLocation(){
return this.todoItem.location;
},
hasPerson(){
return this.todoItem.person;
},
hasChildTask(){
return this.todoItem.childTask;
},
hasParentTask(){
return true;
},
people(){
return [
"dad",
"Ann",
"boss",
"prostitute"
]
},
places(){
return []
}
},
methods:{
...mapMutations(['addPersonMutation'],{
}),
moveToPerson(){
},
moveToLocation(){
},
moveToPatentTask(){
},
addLocation(){
},
addPerson(val){
this.addPersonMutation(val);
this.$set(this.todoItem,'person',val);
console.log(this.hasPerson);
console.log(this.todoItem.person);
},
addChildTask(){
},
deletePerson(){
this.$set(this.todoItem, 'person', null);
console.log(this.hasPerson);
console.log(this.todoItem.person);
},
deleteLocation(){
},
deleteChildTask(){
},
editLocation(){
},
savePerson(){
},
editChildTask(){
}
},
created(){
// this.$set(this.todoItem, 'person', 'undefined');
// this.$set(this.todoItem, 'location', '????');
// this.$set(this.todoItem, 'isDone', "....");
}
}
</script>
问题出在您的 属性 名字上。将数据部分中的 'todo-item' 更改为 todoItem.
这个有效
<template>
<div>
<button @click.prevent="printPerson">Print Person</button>
<br />
<button @click.prevent="deletePerson">Delete Person</button>
</div>
</template>
<script>
export default {
data: () => ({
todoItem: {
id: 1,
text: 'Buy tickets',
isDone: false,
person: 'Boss',
location: 'Boryspil',
childTask: null,
},
}),
computed: {
hasLocation() {
return this.todoItem.location;
},
hasPerson() {
return this.todoItem.person;
},
hasChildTask() {
return this.todoItem.childTask;
},
hasParentTask() {
return true;
},
},
methods: {
deletePerson() {
this.$set(this.todoItem, 'person', null);
// this.todoItem.person = "null"
console.log(this.hasPerson);
console.log(this.todoItem.person);
},
printPerson() {
console.log(this.hasPerson);
console.log(this.todoItem.person);
}
}
}
</script>
此外,使用“this.todoItem.person = null”也有效。
如果仍然不适合您,请编辑您的问题并添加完整的组件代码,我们可以提供帮助。
我的问题出在 props 上,我从父元素中获取了 todoItem,但我无法做到响应式,但是通过深入观察,所有对象属性都变成了响应式。
我解决了我的问题,只是将 watch 属性 添加到我的组件中:
现在,当我更改人(或任何其他人)时,我的 todoItem 属性 也会更改计算属性中的更新。
watch:{
todoItem:{
deep: true,
handler(){
this.saveTodoAction(this.todoItem);
}
}
},
这是完整的代码:
import HoveredChip from "@/components/HoveredChip";
import {mapMutations, mapActions} from 'vuex';
export default {
name: "TodoItem",
components: {HoveredChip},
props:['todo-item'],
data() {
return{
isActive : true,
}
},
computed:{
hasLocation(){
return this.todoItem.location;
},
hasPerson(){
return this.todoItem.person;
},
hasChildTask(){
return this.todoItem.childTask;
},
hasParentTask(){
return true;
},
people(){
return [
"Dad",
"Ann",
"Boss",
"Prostitute"
]
},
places(){
return []
}
},
methods:{
...mapMutations(['addPersonMutation'],{
}),
...mapActions(['saveTodoAction']),
moveToPerson(){
},
moveToLocation(){
},
moveToPatentTask(){
},
addLocation(){
},
addPerson(val){
this.addPersonMutation(val);
},
addChildTask(){
},
deletePerson(){
this.todoItem.person = null;
},
deleteLocation(){
},
deleteChildTask(){
},
editLocation(){
},
savePerson(){
},
editChildTask(){
},
},
watch:{
todoItem:{
deep: true,
handler(){
this.saveTodoAction(this.todoItem);
}
}
},
created(){
}
}
我有一个文件 vue 组件和一个 属性 'todo-item' 这种结构
{
id:1,
text:'Buy tickets',
isDone: false,
person:'Boss',
location:'Boryspil',
childTask:null,
},
并且我计算了属性:
computed:{
hasLocation(){
return this.todoItem.location;
},
hasPerson(){
return this.todoItem.person;
},
hasChildTask(){
return this.todoItem.childTask;
},
hasParentTask(){
return true;
},
}
而且我想让所有对象属性都具有反应性,但是当我在方法中更改属性时:
deletePerson(){
this.$set(this.todoItem, 'person', null);
console.log(this.hasPerson);
console.log(this.todoItem.person);
},
todoItem.person 仍然没有反应,this.hasPerson 有旧值,this.todoItemPerson 显示空值。
我试图让它们对 created
方法有反应,但它仍然没有反应。
这是按组件整体js代码,没有模板,简称css:
<script>
import HoveredChip from "@/components/HoveredChip";
import {mapMutations} from 'vuex';
export default {
name: "TodoItem",
components: {HoveredChip},
props:['todo-item'],
data() {
return{
isActive : true,
}
},
computed:{
hasLocation(){
return this.todoItem.location;
},
hasPerson(){
return this.todoItem.person;
},
hasChildTask(){
return this.todoItem.childTask;
},
hasParentTask(){
return true;
},
people(){
return [
"dad",
"Ann",
"boss",
"prostitute"
]
},
places(){
return []
}
},
methods:{
...mapMutations(['addPersonMutation'],{
}),
moveToPerson(){
},
moveToLocation(){
},
moveToPatentTask(){
},
addLocation(){
},
addPerson(val){
this.addPersonMutation(val);
this.$set(this.todoItem,'person',val);
console.log(this.hasPerson);
console.log(this.todoItem.person);
},
addChildTask(){
},
deletePerson(){
this.$set(this.todoItem, 'person', null);
console.log(this.hasPerson);
console.log(this.todoItem.person);
},
deleteLocation(){
},
deleteChildTask(){
},
editLocation(){
},
savePerson(){
},
editChildTask(){
}
},
created(){
// this.$set(this.todoItem, 'person', 'undefined');
// this.$set(this.todoItem, 'location', '????');
// this.$set(this.todoItem, 'isDone', "....");
}
}
</script>
问题出在您的 属性 名字上。将数据部分中的 'todo-item' 更改为 todoItem.
这个有效
<template>
<div>
<button @click.prevent="printPerson">Print Person</button>
<br />
<button @click.prevent="deletePerson">Delete Person</button>
</div>
</template>
<script>
export default {
data: () => ({
todoItem: {
id: 1,
text: 'Buy tickets',
isDone: false,
person: 'Boss',
location: 'Boryspil',
childTask: null,
},
}),
computed: {
hasLocation() {
return this.todoItem.location;
},
hasPerson() {
return this.todoItem.person;
},
hasChildTask() {
return this.todoItem.childTask;
},
hasParentTask() {
return true;
},
},
methods: {
deletePerson() {
this.$set(this.todoItem, 'person', null);
// this.todoItem.person = "null"
console.log(this.hasPerson);
console.log(this.todoItem.person);
},
printPerson() {
console.log(this.hasPerson);
console.log(this.todoItem.person);
}
}
}
</script>
此外,使用“this.todoItem.person = null”也有效。
如果仍然不适合您,请编辑您的问题并添加完整的组件代码,我们可以提供帮助。
我的问题出在 props 上,我从父元素中获取了 todoItem,但我无法做到响应式,但是通过深入观察,所有对象属性都变成了响应式。 我解决了我的问题,只是将 watch 属性 添加到我的组件中:
现在,当我更改人(或任何其他人)时,我的 todoItem 属性 也会更改计算属性中的更新。
watch:{
todoItem:{
deep: true,
handler(){
this.saveTodoAction(this.todoItem);
}
}
},
这是完整的代码:
import HoveredChip from "@/components/HoveredChip";
import {mapMutations, mapActions} from 'vuex';
export default {
name: "TodoItem",
components: {HoveredChip},
props:['todo-item'],
data() {
return{
isActive : true,
}
},
computed:{
hasLocation(){
return this.todoItem.location;
},
hasPerson(){
return this.todoItem.person;
},
hasChildTask(){
return this.todoItem.childTask;
},
hasParentTask(){
return true;
},
people(){
return [
"Dad",
"Ann",
"Boss",
"Prostitute"
]
},
places(){
return []
}
},
methods:{
...mapMutations(['addPersonMutation'],{
}),
...mapActions(['saveTodoAction']),
moveToPerson(){
},
moveToLocation(){
},
moveToPatentTask(){
},
addLocation(){
},
addPerson(val){
this.addPersonMutation(val);
},
addChildTask(){
},
deletePerson(){
this.todoItem.person = null;
},
deleteLocation(){
},
deleteChildTask(){
},
editLocation(){
},
savePerson(){
},
editChildTask(){
},
},
watch:{
todoItem:{
deep: true,
handler(){
this.saveTodoAction(this.todoItem);
}
}
},
created(){
}
}