【问题标题】:Vue.js update only works if other property changed?Vue.js 更新仅在其他属性更改时才有效?
【发布时间】:2018-05-16 20:00:39
【问题描述】:

我想知道什么是适合我的情况的好方法。考虑以下代码:

<div id="app-4">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }} + {{todo.added_text}} <button v-on:click="add_text(todo)">do</button>
    </li>
  </ol>
</div>

<script type="text/javascript">
    var app4 = new Vue({
        el: '#app-4',
        data: {
            todos: [
              { text: 'Learn JavaScript' },
              { text: 'Learn Vue' },
            ]
        },
        methods: {
            add_text(item){
                index = this.todos.indexOf(item);
                this.todos[index].added_text = "something else";
                // this.todos[index].text = 'learn more';
            }
        }
    })
</script>

如果按下按钮,我想添加 todo.added_text。但是,因为在 vue 实例化时这个属性不是数组中元素的一部分,所以这个属性根本不会出现(这是我的假设,我可能错了)。

但是,当我更改同一元素中的其他内容时(例如,注释行:this.todos[index].text = 'learn more';),todo.text 和 todo.added_text 都会更新。

我的问题是,除了更改同一元素的其他一些属性之外,还有什么好方法可以告诉 vue 元素中发生了某些变化?

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    但是,因为这个属性在vue实例化的时候并不是数组中元素的一部分,所以这个属性根本就没有出现

    是的,你是对的

    当您将纯 JavaScript 对象作为其数据选项传递给 Vue 实例时,Vue 将遍历其所有属性并使用 Object.defineProperty 将它们转换为 getter/setter。

    getter/setter 对用户是不可见的,但在底层,它们使 Vue 能够在访问或修改属性时执行依赖关系跟踪和更改通知。

    Vue 无法检测属性添加或删除。由于 Vue 在实例初始化期间执行 getter/setter 转换过程,因此数据对象中必须存在一个属性,以便 Vue 对其进行转换并使其具有响应性。

    您可以使用Vue.set(object, key, value) 进行此操作,例如

    Vue.set(vm.someObject, 'b', 2)
    

    阅读here

    【讨论】:

    • 正如上面anwser已经指出的那样,另一种方法:将this.todos更改为todos: [ { text: 'Learn JavaScript' , 'added_text':''}, { text: 'Learn Vue' , 'added_text':''}, ]
    • @george-bailey 谢谢,那行得通。我想知道,当您更改另一个属性(Vue 以前知道)时,“新”属性怎么可能更新?是否在任何更改时再次实例化整个对象?
    【解决方案2】:

    您可以通过分配给反应性元素来获得反应性。 this.todos[index] 已经是反应性的,所以如果你重新分配整个事情,所有的部分都将是反应性的。因为它是一个数组元素,所以你必须使用set,但是你可以对整个对象使用一次,而不是对每个添加的成员使用一次:

            add_text(item){
                const index = this.todos.indexOf(item);
                const newObject = Object.assign({}, item, {
                    text: 'learn more',
                    added_text: 'something else'
                });
    
                this.$set(this.todos, index, newObject);
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-05
      • 1970-01-01
      • 2018-05-09
      • 1970-01-01
      • 1970-01-01
      • 2018-03-01
      • 2011-05-01
      • 1970-01-01
      相关资源
      最近更新 更多