【问题标题】:Can't set object property as reactive in Vue.js无法在 Vue.js 中将对象属性设置为反应式
【发布时间】:2021-04-03 01:11:24
【问题描述】:

我有一个文件 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);
},

tod​​oItem.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-items 吗?
  • 是和@kasvith 相同的问题,数据是prop 还是data
  • 是的,我将 todo-item 作为父元素的属性传递,我认为这是主要问题,我必须在父元素中进行反应,或者在更新时替换父元素中的整个对象一些属性,无论如何它必须发送到服务器并在将来替换,所以我想我会尝试这种方式,如果添加新的 todo-item 我将使用数据对象。

标签: vue.js reactive


【解决方案1】:

问题在于您的属性名称。将数据部分中的“待办事项”更改为待办事项。

这行得通

<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”也可以。

如果仍然不适合您,请编辑您的问题并添加完整的组件代码,我们可以提供帮助。

【讨论】:

    【解决方案2】:

    我的问题出在 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(){
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-10-28
      • 2020-01-02
      • 1970-01-01
      • 2020-03-06
      • 2015-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多