Files
element/packages/cascader/src/menu.vue
2017-02-04 10:46:43 +08:00

133 lines
3.4 KiB
Vue

<script>
export default {
name: 'ElCascaderMenu',
data() {
return {
options: [],
visible: false,
activeValue: [],
value: [],
expandTrigger: 'click',
changeOnSelect: false
};
},
watch: {
visible(value) {
if (value) {
this.activeValue = this.value;
}
},
value: {
immediate: true,
handler(value) {
this.activeValue = value;
}
}
},
computed: {
activeOptions: {
cache: false,
get() {
const activeValue = this.activeValue;
let options = this.options;
const loadActiveOptions = (options, activeOptions = []) => {
const level = activeOptions.length;
activeOptions[level] = options;
let active = activeValue[level];
if (active) {
options = options.filter(option => option.value === active)[0];
if (options && options.children) {
loadActiveOptions(options.children, activeOptions);
}
}
return activeOptions;
};
const result = loadActiveOptions(options);
return result;
}
}
},
methods: {
selectItem(item, menuIndex) {
const len = this.activeOptions.length;
const closeMenu = !item.children;
if (item.__IS__FLAT__OPTIONS) {
this.activeValue.splice(menuIndex, len, ...item.value);
} else {
this.activeValue.splice(menuIndex, len, item.value);
}
if (this.changeOnSelect) {
this.$emit('change', this.activeValue, closeMenu);
}
},
expandItem(item, menuIndex) {
const len = this.activeOptions.length;
if (item.children) {
this.activeValue.splice(menuIndex, len, item.value);
this.activeOptions.splice(menuIndex + 1, len, item.children);
}
},
handleItemClick(item, menuIndex) {
this.expandItem(item, menuIndex);
this.selectItem(item, menuIndex);
if (!item.children && !this.changeOnSelect) {
this.$emit('change', this.activeValue);
}
}
},
render(h) {
const {
activeValue,
activeOptions,
visible,
expandTrigger
} = this;
const menus = this._l(activeOptions, (menu, index) => {
const items = this._l(menu, item => {
const events = {
on: {}
};
if (expandTrigger === 'click' || !item.children) {
events.on['click'] = () => { this.handleItemClick(item, index); };
} else {
events.on['mouseenter'] = () => { this.expandItem(item, index); };
}
return (
<li
class={{
'el-cascader-menu__item': true,
'el-cascader-menu__item--extensible': item.children,
'is-active': item.value === activeValue[index]
}}
{...events}
>
{item.label}
</li>
);
});
return <ul class="el-cascader-menu">{items}</ul>;
});
return (
<transition name="el-zoom-in-top">
<div class="el-cascader-menus" v-show={visible}>
{menus}
</div>
</transition>
);
}
};
</script>