首页 >社区问答列表 >javascript - vue组件extend扩展报错

javascript - vue组件extend扩展报错

写了一个select组件,具体在业务中使用需要修改下,在继承select的基础上做了修改,重新命名为teble-select, vue提示 [Vue warn]: Error in render function: "TypeError: Cannot read property 'name' of undefined" 这是啥原因,是我select组件写的有问题导致的吗? 请教下同志们
select组件:

<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 ??

  • 淡淡烟草味
  • 淡淡烟草味    2017-07-05 10:47:061楼

    options 有可能为空吗?如果有可能为空,那么 selected 有可能是 undefined

    如果涉及到异步,在这个组件模板根元素上加 v-if="options.length !== 0"

    +0添加回复

  • 回复