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]" />
我想我想聪明了一半!
我封装了一些优秀的 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]" />
我想我想聪明了一半!