【问题标题】:Vue.js 2 - Array change detectionVue.js 2 - 数组变化检测
【发布时间】:2017-11-16 05:31:54
【问题描述】:

这是我的代码的简化版本:

    <template>

        /* ---------------------------------------------------------- 
         *  Displays a list of templates, @click, select the template
        /* ----------------------------------------------------------
        <ul>
            <li 
                v-for="form in forms.forms" 
                @click="selectTemplate(form)" 
                :key="form.id" 
                :class="{selected: templateSelected == form}">
                <h4>{{ form.name }}</h4>
                <p>{{ form.description }}</p>
            </li>
        </ul>

        /* -------------------------------------------------------- 
         *  Displays the "Editable fields" of the selected template
        /* --------------------------------------------------------

        <div class="form-group" v-for="(editableField, index) in editableFields" :key="editableField.id">                                       
            <input 
                    type="text" 
                    class="appfield appfield-block data-to-document" 
                    :id="'item_'+index" 
                    :name="editableField.tag" 
                    v-model="editableField.value">
        </div>                    
    </template>

    <script> 
        export default {                        
            data: function () {
                return {
                    editableFields: [],
                }
            },
            methods: {
                selectTemplate: function (form) {

                    /* ------------------ 
                    *  My problem is here
                    */ ------------------

                    for (let i = 0; i < form.editable_fields.length; i++) {                                         
                        this.editableFields.push(form.editable_fields[i]);              
                    }
                }
            }
        }
    </script>

基本上我想在用户每次点击模板时更新数组 EditableFields。我的问题是 Vuejs 没有更新显示,因为没有触发检测。我已经阅读了here 的文档,该文档建议要么 $set 数组,要么只使用 Array 实例方法,例如 splice 和 push。

上面的代码(带有推送)工作,但数组永远不会被清空,因此“可编辑字段”不断堆积,这不是我想要的行为。

为了在用新数据再次填充之前清空数组,我尝试了几件事但没有运气:

this.editableFields.splice(0, this.editableFields.length);

for (let i = 0; i < form.editable_fields.length; i++) {
    this.editableFields.push(form.editable_fields[i]);                   
}

==> 不更新显示

for (let i = 0; i < form.editable_fields.length; i++) {                 
    this.$set(this.editableFields, i, form.editable_fields[i]);
}

==> 不更新显示

this.editableFields = form.editable_fields;

==> 不更新显示

我还没有尝试过使用新数据设置一个全新的数组,但我无法理解如何将其放置到位,因为我希望用户能够单击(并更改模板选择)不止一次。

我在这个问题上纠结了几个小时,如果有任何帮助,我将不胜感激。 提前谢谢你:)!

【问题讨论】:

    标签: javascript arrays vue.js splice


    【解决方案1】:

    我使用 splice + push 没有问题。如您提供的链接中所述,应正常触发反应性。

    查看我的代码示例:

    new Vue({
      el: '#app',
      data: function() {
        return {
          forms: {
            forms: [{
                id: 'form1',
                editable_fields: [{
                    id: 'form1_field1',
                    value: 'form1_field1_value'
                  },
                  {
                    id: 'form1_field2',
                    value: 'form1_field2_value'
                  }
                ]
              },
              {
                id: 'form2',
                editable_fields: [{
                    id: 'form2_field1',
                    value: 'form2_field1_value'
                  },
                  {
                    id: 'form2_field2',
                    value: 'form2_field2_value'
                  }
                ]
              }
            ]
          },
          editableFields: []
        }
      },
      methods: {
        selectTemplate(form) {
          this.editableFields.splice(0, this.editableFields.length);
          for (let i = 0; i < form.editable_fields.length; i++) {
            this.editableFields.push(form.editable_fields[i]);
          }
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
    <div id="app">
        <ul>
            <li v-for="form in forms.forms" 
                @click="selectTemplate(form)" 
                :key="form.id">
                <h4>{{ form.id }}</h4>
            </li>
        </ul>
    
        <div class="form-group"
            v-for="(editableField, index) in editableFields"
            :key="editableField.id">
                {{ editableField.id }}:
            <input type="text" v-model="editableField.value">
        </div>
    </div>

    【讨论】:

    • 谢谢,你完全正确,我的代码中不相关的部分导致了错误。
    【解决方案2】:

    问题解决了...实际上是代码的另一个远程部分导致了问题。

    为了将来参考,这个解决方案是正确的:

    this.editableFields.splice(0, this.editableFields.length);
    
    for (let i = 0; i < form.editable_fields.length; i++) {
        this.editableFields.push(form.editable_fields[i]);                   
    }
    

    仅使用 Array 实例方法是使用 Vuejs 的方式。

    【讨论】:

    • 您也可以使用this.editableFields = [ ] 将数组设置为空
    • 谢谢!这更短!
    猜你喜欢
    • 2017-03-01
    • 1970-01-01
    • 2017-06-07
    • 2017-08-15
    • 2017-05-04
    • 2017-02-09
    • 2017-06-16
    • 2017-07-03
    • 1970-01-01
    相关资源
    最近更新 更多