Write a select component, which needs to be modified when used in business. I modified it based on inheriting select and renamed it teble-select. Vue prompts [Vue warn]: Error in render function: "TypeError: Cannot read property 'name' of undefined" What is the reason for this? Is it caused by a problem with the writing of my select component? Please let me know, comrades
select component:
<template>
<p ref="element" :class="$style.root" :readonly="readonly" v-if="visible" :style="{width: width+'px'}" @click="toggle()">
<p :class="$style.head" :disabled="disabled">
<span>{{selected.name}}</span>
</p>
<p :class="$style.body" v-if="open">
<ul :class="$style.listview">
<li :class="$style.listitem" v-for="(item,index) in options" :disabled="item.disabled" :pider="item.pider" :role="(index === selectedIndex) ? 'z-sel':''" @click="select($event,index)">{{item.name}}</li>
</ul>
</p>
</p>
</template>
<script>
const Select = Base.extend({
name: 'u-select',
props: {
options: Array,
readonly: Boolean,
disabled: Boolean,
visible: { type: Boolean, default: true },
width: { type: [String, Number], default: '160' },
value: [String, Number],
},
data() {
return {
open: false,
selectedIndex: this.initSelectedIndex(this.value),
};
},
created() {
EventUtil.addHandler(document, 'click', this.fadeOut.bind(this));
},
computed: {
selected() {
return this.options[this.selectedIndex];
},
},
methods: {
toggle(value) {
if (this.disabled)
return;
if (value)
this.open = value;
else
this.open = !this.open;
},
select(event, index) {
if (this.readonly)
return;
if (this.options[index].disabled || this.options[index].pider) {
event.stopPropagation();
return false;
}
// this.selected = this.options[index];
this.selectedIndex = index;
/**
* @event select 选中列表项时触发
* @property {object} sender 事件发送对象
* @property {object} selected 选中后的列表对象
* @property {String} value 选中后的列表对象的值
*/
this.$emit('select', {
sender: this,
selected: this.options[index],
value: this.options[index].value,
});
},
initSelectedIndex(value) {
let selIndex = 0;
if (this.value) {
this.options.some((item, index) => {
if (item.value === value) {
selIndex = index;
return true;
}
return false;
});
}
return selIndex;
},
fadeOut(event) {
Select.opens.forEach((item, index) => {
// 这个地方不能用stopPropagation来处理,因为展开一个Select的同时要收起其他Select
const element = item.$refs.element;
let element2 = event.target;
while (element2) {
if (element === element2)
return;
element2 = element2.parentElement;
}
item.toggle(false);
});
},
},
watch: {
open(newValue) {
const index = Select.opens.indexOf(this);
if (newValue && index < 0)
Select.opens.push(this);
else if (!newValue && index > -1)
Select.opens.splice(index, 1);
},
/**
* @event change 选中列表项改变时触发
* @property {object} sender 事件发送对象
* @property {object} selected 改变后的列表对象
* @property {String} value 改变后的列表对象的值
*/
selected(newValue) {
this.$emit('change', {
sender: this,
selected: newValue,
value: newValue.value,
});
},
value(newValue) {
this.selectedIndex = this.initSelectedIndex(newValue);
},
},
});
//Select 类的静态属性 用来保存当前处于open状态的Select对象
Select.opens = [];
export default Select;
</script>
组件是可以正常使用的,但是重新包装下 就会提示name undefined ??
Is it possible for options to be empty? If it is possible to be empty, then selected may be undefined
If asynchronous is involved, add v-if="options.length !== 0" to the root element of this component template