【问题标题】:Vue reactivity stays after form submit表单提交后 Vue 反应性保持不变
【发布时间】:2019-12-03 22:53:36
【问题描述】:

我正在学习 Vue.js,并且正在构建一个桶列表应用程序。我遇到的问题是,当我添加一个新项目时,我的输入被清除了,但是当我开始添加一个新项目时,前一个项目也会更新。

HTML

<div class="container">
  <add-form></add-form>
  <bucketlist></bucketlist>
</div>

AddForm.vue

<template>
  <div>
    <h2>
        Add new item
    </h2>
    <form method="post" @submit.prevent="formSubmit">
        <div>
            <input type="text" placeholder="Title" v-model="title">
        </div>
        <div>
            <label for="">Status</label>
            <input type="checkbox" v-model="status">
        </div>
        <div>
            <input type="submit" value="Save">
        </div>
    </form>
  </div>
</template>

<script>
  export default {
    data() {
        return {
            title: '',
            status: false,
        }
    },
    methods: {
        formSubmit(event) {
            axios.post('/add-item', this.$data)
              .then((response) => {
                  this.$eventBus.$emit('newitem', this.$data)
              })
            // this.title = '';
            event.target.reset();
        },
    }
  }
</script>

Bucketlist.vue

<template>
  <div class="bucketlist">
    <div v-for="bucket in bucketlist" class="bucketitem">
        <h3>
            {{ bucket.title }}
        </h3>
        <input type="checkbox" :id="bucket.id"
                     :checked="bucket.status ? true : false"
                     @click="updateStatus">
    </div>
  </div>
</template>

<script>
  export default {
    data() {
        return {
            bucketlist: []
        }
    },
    methods: {
        updateStatus(value) {
            axios.post('/update-status/'+value.target.id, this.$data);
        }
    },
    mounted() {
        axios.get('/bucketlist')
            .then(response => (this.bucketlist = response.data.bucketlist));

        this.$eventBus.$on('newitem', (data) => {
            this.bucketlist.push(data);
        });
    }
  }
</script>

我尝试了this.title = '',但在提交请求时收到错误Column 'title' cannot be null

这不是添加新项目并保持 Vue 反应性的正确方法吗?

我制作了一个小(而且很糟糕)的 GIF 来说明我的问题。

【问题讨论】:

标签: vue.js vuejs2 vue-component


【解决方案1】:

为什么发送的项目仍然发生变异?

您正在发射整个$data 对象...正如您在下图中看到的那样,$data 对象包含一堆与内存中的数据变量直接相关的函数(setters/@ 987654326@).

因此,当您将该对象传递给其他组件时....您输入中的v-model 仍会针对内存中的该数据,因此它仍然可以setget它。

解决方案:

而不是传递整个 $data 对象,只需传递一个包含要推送到该数组中的数据的文字对象,例如:

formSubmit(event) {
  var obj = {
    title: this.title,
    status: this.status
  };
  axios.post('/add-item', this.$data)
    .then((response) => {
      this.$eventBus.$emit('newitem', obj)
    })
  event.target.reset();
}

【讨论】:

    【解决方案2】:

    问题是您将整个 $data 对象传递给您的事件。

    为什么会出现这个问题?

    引用自here

    分配了非原始值的变量将获得对该值的引用。该引用指向对象在内存中的位置。变量实际上并不包含值。

    解决问题

    const arr = [];
    
    const obj = { title: 'a title!' };
    
    arr.push(obj);
    console.log(arr) // 0: {title: "a title!"}
    
    obj.title = 'a modified title!';
    console.log(arr) // 0: {title: "a modified title!"}
    

    解决方案

    创建shallow copy

    按照上面的例子,我们可以这样做:

    arr.push({ ...obj });
    

    请注意,如果您的对象有嵌套对象(或任何不是原始值),浅拷贝方法将不起作用,因为您还需要处理这些嵌套对象。

    【讨论】:

      猜你喜欢
      • 2015-04-23
      • 1970-01-01
      • 2021-11-18
      • 2013-07-03
      • 2019-01-17
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      • 2013-01-08
      相关资源
      最近更新 更多