VueJs:包装 el-select:列表元素在 DOM 刷新期间添加了 3 次

VueJs: Wrapping el-select: list elements added 3 times during DOM refreshes

我封装了一些优秀的 element-ui 组件。因为我通常在所有地方都使用相同的设置。另外,我想要更简洁的代码。一切正常,除了 el-select 我收到关于重复键的 DOM 错误。

[Vue warn]: Duplicate keys detected: 'XXX VALUE'. This may cause an update error.

最初我只是将列表直接传递给 <el-select> 得到了同样的错误,然后做了一个 localList var,同样的事情。

我在安装部分添加了 nextTick,这里有一个完整的例子。

列表的内容被添加 3 次,因此出现错误。

// Please note: The original code is a .vue component, modified it for this example.

Vue.component('select-input', {
  props: {
    label: {
     type: String,
     default: 'Select'
    },

  value: {
      required: true
    },

    list: {
      type: Array,
      default: null
    },
    
    disabled: {
     type: Boolean,
     default: false
    }
  },

  methods: {
    init () {
      this.localList = this.list
    },

    updated (value) {
      this.form = value
      this.$emit('input', this.form)
      this.$emit('change', this.form)
    }
  },

  data () {
    return {
      form: this.value,
      localList: []
    }
  },


  mounted () {
    this.$nextTick().then(this.init())
  },

  template: '<el-form-item :label="label" v-if="localList"><el-select v-if="!disabled" v-model="form" placeholder="Select..." :disabled="disabled" @change="updated"><el-option v-if="item[valueKey]" v-for="item in localList" :label="item[labelValue]":value="item[valueKey]" :key="item[valueKey]" /><el-option v-else v-for="(item, index) in list" :label="item" :value="item" :key="index" /></el-select> <b v-else>{{this.form}}</b></el-form-item>'
})

var app = new Vue({
  el: '#app',
  data: {
    select1: null,
    select2: null,
    list: ['Minutes', 'Hours', 'Days']
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui@2.8.2/lib/theme-chalk/index.css">
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui@2.8.2/lib/index.js"></script>

<body>

<div id="app">
  <h3>Normal Select Works OK</h3>
  <el-select v-model="select1" placeholder="Select...">
    <el-option v-for="item in list" :value="item" :key="item"></el-option>
  </el-select>
 
  <p>You chose: <b>{{select1}}</b></p>
  
  <hr />

  <h3>Wrapped Component Select Works Gives Errors</h3>
  <p><i>See browser console</i></p>

  <el-form>
    <select-input label="Period" v-model="select2" :list="list"></select-input>
  </el-form>
  <p>You chose: <b>{{select2}}</b></p>
  

</div>



</body>

试试这个

你的 v-for 循环键是 item 尝试将其更改为这样的索引

<el-option v-for="(item, index) in localList" :label="item" :value="item" :key="index" /> </el-select>

找到了 - 怀疑 v-else 条件是问题所在。由于使用简单的列表,而不是带有标签、值对的对象数组,它会进入 else 条件。

<el-option v-if="item[valueKey]" v-for="item in localList"
 :label="item[labelValue]":value="item[valueKey]" :key="item[valueKey]" />

<el-option v-else v-for="(item, index) in list"
  :label="item" :value="item" :key="index" />

如果组件得到一个普通列表,它现在会处理它,因此可以按如下方式处理:

<el-option v-for="item in localList"
 :label="item[labelValue]":value="item[valueKey]" :key="item[valueKey]" />

我想我想聪明了一半!