Reputation: 427
I have one file vue component with one property 'todo-item' with such structure
{
id:1,
text:'Buy tickets',
isDone: false,
person:'Boss',
location:'Boryspil',
childTask:null,
},
And I have computed properties:
computed:{
hasLocation(){
return this.todoItem.location;
},
hasPerson(){
return this.todoItem.person;
},
hasChildTask(){
return this.todoItem.childTask;
},
hasParentTask(){
return true;
},
}
And I want to make all of object properties reactive, but when I change properties in method:
deletePerson(){
this.$set(this.todoItem, 'person', null);
console.log(this.hasPerson);
console.log(this.todoItem.person);
},
todoItem.person is still not reactive, this.hasPerson have old value, and this.todoItemPerson shows null value.
I tried to make them reactive on created
method, but it's still not reactive.
This is by component whole js code, without template and css for short:
<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>
Upvotes: 0
Views: 2675
Reputation: 427
My problem was in props, I get todoItem from parent element, and I can't do it reactive, but with deep watch all object properties becomes reactive. I solved my problem just adding watch property to my component:
And now when I change person (or any other) property of my todoItem changes updates in computed properties either.
watch:{
todoItem:{
deep: true,
handler(){
this.saveTodoAction(this.todoItem);
}
}
},
And this is the whole code:
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(){
}
}
Upvotes: 0
Reputation: 973
The issue is with your property name. Change the 'todo-item' in the data section to todoItem.
This works
<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>
Also, using "this.todoItem.person = null" works.
If still doesn't work for you, edit your question and add the complete component code and we can help.
Upvotes: 4