Vue组件列表2事件处理

时间:2018-04-17 19:54:25

标签: vuejs2 vue-component

在从列表中呈现组件时,如何使用.sync挣扎。如何处理组件中发出的事件以更新父组件?

尝试更新输入中的categorySet.gradeCategory.predictionWeight

<category-set v-for="cat in categories" v-bind:key="cat.id" v-bind:category-set="cat"></category-set>

    Vue.component('category-set', {

  props: ['categorySet'],
  template: '            <div class="form-group">\n' +
    '                <label for="gradeRange" class="col-sm-2 control-label">{{ categorySet.gradeCategory.gradeCategoryName }}</label>\n' +
    '                <div class="col-sm-1">\n' +
    '                    <input id="gradeRange" class="form-control" type="number" v-bind:value.number="categorySet.gradeCategory.predictionWeight" \n' +
    '                           step="0.5" v-on:input="$emit(\'input\', $event.target.value)" > \n' +
    '                </div>\n' +
    '            </div>'
});

小提琴:https://jsfiddle.net/rhmiller/aq9Laaew/10971/

2 个答案:

答案 0 :(得分:1)

就个人而言,我会这样做:

组件传递数组索引和项目(cat),使用您在组件中定义项目的项目,然后绑定输入事件,然后将完整对象发回给具有索引的父项,然后是父项将项目设置回数据。

由于Final Exam项在视图中使用时需要处理/恢复gradeCategory属性。此外,标签在父级中也是相同的,因此如果您使用gradeCategory,则更喜欢使用它,否则它将为null。

Vue.component('categorySet', {
  template: '#category-set',
  props: ['data', 'index'],
  data() {
    return {
      item: {
         label: this.data.label,
         showInSummary: this.data.showInSummary,
         gradeCategory: Object.assign({
            "gradeCategoryName": null,
            "groupGradeWeight": 0.0,
            "predictionWeight": null,
            "id": this.data.id
         }, this.data.gradeCategory),
         id: this.data.id
       }
    }
  },
  methods: {
    inputOccurred(e) {
      this.$emit('on-change', this.item, this.index)
    }
  }
});

//
var vm = new Vue({
  el: '#app',
  data() {
    return {
      categories: [
        {
          "label": "Assignments",
          "showInSummary": true,
          "gradeCategory": {
            "gradeCategoryName": "Assignments",
            "groupGradeWeight": 0.0,
            "predictionWeight": null,
            "id": 81
          },
          "id": 81
        }, {
          "label": "Reflections",
          "showInSummary": true,
          "gradeCategory": {
            "gradeCategoryName": "Reflections",
            "groupGradeWeight": 10.0,
            "predictionWeight": null,
            "id": 82
          },
          "id": 82
        }, {
          "label": "Quizzes",
          "showInSummary": true,
          "gradeCategory": {
            "gradeCategoryName": "Quizzes",
            "groupGradeWeight": 10.0,
            "predictionWeight": 10.0,
            "id": 83
          },
          "id": 83
        }, {
          "label": "Attendance \u0026 Participation",
          "showInSummary": true,
          "gradeCategory": {
            "gradeCategoryName": "Attendance \u0026 Participation",
            "groupGradeWeight": 0.0,
            "predictionWeight": null,
            "id": 84
          },
          "id": 84
        }, {
          "label": "Final Exam",
          "showInSummary": true,
          "gradeCategory": null,
          "id": 92
        }
      ]
    }
  },
  methods: {
    syncCategorie(value, index) {
      this.categories[index] = Object.assign(this.categories[index], value);
    }
  }
});
<div id="app">
  <category-set v-for="(cat, index) in categories" :key="cat.id" :data="cat" :index="index" @on-change="syncCategorie"></category-set>
  <pre>{{ categories }}</pre>
</div>

<template id="category-set">
  <div class="form-group">
    <label for="gradeRange" class="col-sm-3 control-label">{{ item.label }}</label>
      <div class="col-sm-1">
        <input id="gradeRange" class="form-control" type="number" v-model="item.gradeCategory.predictionWeight" step="0.5" @input="inputOccurred">
      </div>
  </div>
</template>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.14/vue.min.js"></script>

运行代码片段,看到它更新了父母的罚款。

答案 1 :(得分:0)

添加.sync修饰符时,可以省略v-on:input部分。

:prop.sync="binding"

将有效扩展为:

:prop="binding" @update:prop="value => binding = value"

(:只是v-bind的缩写:和@ for v-on:)