如何设置从prop中派生的不可变数据,这些数据可能会发生变化

时间:2017-10-19 17:03:42

标签: vue.js

我正在尝试完成类似于Todo-List的演示,图纸为

Parent.vue

<template>
<li v-show="currentTab === 1">
    <child key="1" :items="projects"></child>
</li>
<li v-show="currentTab === 2">
    <child key="2" :items="awards"></child>
</li>
</template>
<script>
export default {

data: function() {
    return {
        awards: [{
            name: ''
        }],
        projects:[{
            content:''
        }]
    }
},
}

</script>

Child.vue

<template>
<div>
    <el-form>
        <div v-for="(item,index) in items" :key="index">
            <el-form-item>
                <el-input v-model="item[key]"></el-input>
            </el-form-item>
            <i class="el-icon-close" @click="remove(index)"></i>
        </div>
        <el-button type="primary" @click="add">Add</el-button>
    </el-form>
</div>
</template>

<script>
export default {
props: ['items'],
computed: {
    keys: function() {
        return Object.keys(this.items[0])
    },
},
// data: function() {
//     return {
//         copyItems: this.items.slice(0)
//     }
// },
methods: {
    add: function() {
        let temp = {}
        this.keys.map((key) => {
            temp[key] = ''
        })
        this.items.push(temp)
    },
    remove: function(index) {
        this.items.splice(index, 1)
    }
}
}
</script>

问题是当方法删除被调用然后 [] 时,计算属性会出错,原因是 this.items [0] 不存在,方法添加不可用,也许我应该定义另一个道具来获取密钥派生形式Parent.vue像这样: <child key="1" :items="projects" objectKey="content"></child> <child key="2" :items="awards" objectKey="name"></child> 虽然我觉得这种方式不合适。那么如何处理这个问题?

1 个答案:

答案 0 :(得分:0)

删除时,如果列表中只有一个项目,请不要将其删除,只需将其初始化为空。该列表永远不会为空,您将始终拥有密钥。

&#13;
&#13;
Vue.component('child', {
  template: '#child-template',
  props: ['items'],
  computed: {
    keys: function() {
      return Object.keys(this.items[0]);
    },
  },
  methods: {
    initialize: function (item) {
      this.keys.map((key) => {
        item[key] = '';
      });
    },
    add: function() {
      let temp = {}
      this.initialize(temp);
      this.items.push(temp)
    },
    remove: function(index) {
      if (this.items.length > 1) {
        this.items.splice(index, 1)
      }
      else {
        this.initialize(this.items[0]);
      }
    }
  }
});

new Vue({
  el: '#app',
  data() {
    return {
      currentTab: 1,
      awards: [{
        name: ''
      }],
      projects: [{
        content: ''
      }]
    }
  }
});
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <li v-show="currentTab === 1">
    <child key="1" :items="projects"></child>
  </li>
  <li v-show="currentTab === 2">
    <child key="2" :items="awards"></child>
  </li>
  <div v-for="item in projects">{{item.content}}</div>
</div>

<template id="child-template">
<div>
    <el-form>
        <div v-for="(item,index) in items" :key="index">
            <div>
                <input v-model="item[keys[0]]">
            </div>
            <button class="el-icon-close" @click="remove(index)">X</button>
        </div>
        <button type="primary" @click="add">Add</button>
    </el-form>
</div>
</template>
&#13;
&#13;
&#13;