UNPKG

shu-c-view

Version:

rollup 打包vue组件库框架

337 lines (335 loc) 9.44 kB
/** * @desc 菜单按钮 */ import _has from 'lodash/has'; import _isEmpty from 'lodash/isEmpty'; import _find from 'lodash/find'; import _isNil from 'lodash/isNil'; import _set from 'lodash/set'; import _omit from 'lodash/omit'; import _isArray from 'lodash/isArray'; import _includes from 'lodash/includes'; import _get from 'lodash/get'; import { devConsole, apply } from '../helper/util.js'; const BaseMenuButton = { name: 'BaseMenuButton', inheritAttrs: false, props: { props: { type: Object, default() { return {}; } }, // 一个可选添加的CSS样式类,加入到组件的容器上 ctCls: { type: String }, // 标题名称 dropdownLabel: { type: String, default: '下拉菜单' }, // 左边的icon prefixIcon: { type: String }, // 触发下拉的行为 hover, click trigger: { type: String, default: 'click' }, // 数据 options: { type: Array }, // 是否显示所有分割线 isShowDivided: { type: Boolean, default: false }, // 图标的尺寸 svgSize: { type: String, default: '16px' }, // svg 图标集合 [{name: 'studyState', component: studyState}] svgIcons: { type: Array, default() { return []; } }, // 当前激活菜单的 index defaultActive: { type: String }, // 当前激活菜单的文字颜色 activeTextColor: { type: String, default: '#409EFF' } }, watch: { dropdownLabel(val) { if (val !== this.curDropdownLabel) { this.curDropdownLabel = val; } } }, data() { this.oData = {}; this.defaultProps = { children: 'children', label: 'label', value: 'value', icon: 'icon' }; return { cascaderValue: [], curDropdownLabel: this.dropdownLabel }; }, created() { if (!_isNil(this.props)) { apply(this.defaultProps, this.props); } }, mounted() { setTimeout(() => { if (!_isNil(this.defaultActive)) { const checkedData = _get(this.oData, this.defaultActive); if (!_isNil(checkedData)) { this.$nextTick(() => { this.curDropdownLabel = _get(checkedData, this.defaultProps.label); }); } } }, 0); }, methods: { /** * @desc 根据菜单的 index 获取对应的路由路径 * @param {String} index - 菜单对应的 index 属性 */ getRouterPath(index) { return _get(this.oData, index); }, /** * @desc 创建元素自身 * @param {*} self - 元素自身 * @returns VNode */ createElSelf(self) { const h = this.$createElement; /* return h( { render(h) { return this.$scopedSlots.default(); } }, { scopedSlots: { default: props => self } }, [] ); */ return h('base-render-self', { props: { self } }); }, /** * @desc 创建图表 */ createIcon(iconUrl) { const h = this.$createElement; if (/\.(gif|png|jpg|jpeg|webp|svg|psd|bmp|tif)$/.test(iconUrl)) { return h('img', { style: { marginRight: '5px' }, attrs: { src: iconUrl, width: this.svgSize, height: this.svgSize } }); } if (iconUrl.indexOf('symbol-') !== -1) { return h( 'base-svg-icon', { style: { marginRight: '5px' }, props: { size: this.svgSize, iconname: iconUrl.replace('symbol-', '') } }, [] ); } if (_includes(iconUrl, 'svg-')) { // svg图 const curUrl = iconUrl.replace('svg-', ''); const svgObj = _find(this.svgIcons, o => o.name === curUrl); if (!_isNil(svgObj)) { return this.$createElement(_get(svgObj, 'component', 'span'), { style: { width: this.svgSize, height: this.svgSize, marginRight: '5px' } }); } } return h('i', { class: iconUrl }, []); }, /** * @desc 创建 menu 的内部子元素 * @private * @method */ createMenuElements() { const h = this.$createElement; const nodes = []; for (let i = 0, len = this.options.length; i < len; i++) { const option = this.options[i]; const index = '1-' + i; const disabled = option.disabled; if ( _has(option, this.defaultProps.children) && !_isEmpty(_get(option, this.defaultProps.children, [])) ) { if (!_isNil(option[this.defaultProps.children])) { nodes.push(this.createElSubMenu(option, index)); } } else { const menuItem = h('el-menu-item', { props: { index, disabled } }, [ _has(option, this.defaultProps.icon) ? this.createIcon(option[this.defaultProps.icon]) : h(), this.createElSelf(option[this.defaultProps.label]) ]); nodes.push(menuItem); } _set( this.oData, index, JSON.parse( JSON.stringify(_omit(option, [this.defaultProps.children])) ) ); } return nodes; }, /** * @desc 创建 el-submenu */ createElSubMenu(option, index) { const h = this.$createElement; const nodes = []; const aOptionData = option[this.defaultProps.children]; for (let i = 0, len = aOptionData.length; i < len; i++) { const childOption = aOptionData[i]; const innerIndex = `${index}-${i}`; if ( _has(childOption, this.defaultProps.children) && !_isEmpty(_get(childOption, this.defaultProps.children, [])) ) { const sumMenu = this.createElSubMenu(childOption, innerIndex); nodes.push(sumMenu); } else { const menuItem = h( 'el-menu-item', { props: { index: innerIndex, disabled: childOption.disabled } }, [ _has(childOption, this.defaultProps.icon) ? this.createIcon(childOption[this.defaultProps.icon]) : h(), this.createElSelf(childOption[this.defaultProps.label]) ] ); nodes.push(menuItem); } _set( this.oData, innerIndex, JSON.parse( JSON.stringify(_omit(childOption, [this.defaultProps.children])) ) ); } return h('el-submenu', { props: { index } }, [ h('template', { slot: 'title' }, [ _has(option, this.defaultProps.icon) ? this.createIcon(option[this.defaultProps.icon]) : h(), this.createElSelf(option[this.defaultProps.label]) ]), nodes ]); } }, render(h) { return h( 'div', { class: { 'base-menu-button': true, [this.ctCls]: !!this.ctCls } }, [ h( 'el-menu', { props: { mode: 'horizontal', 'menu-trigger': this.trigger, 'unique-opened': true, 'default-active': this.defaultActive, 'active-text-color': this.activeTextColor }, on: { select: (index, indexPath) => { const data = JSON.parse( JSON.stringify(_get(this.oData, index)) ); data.index = index; data.indexPath = indexPath; this.$emit('select', data); } } }, [ h( 'el-submenu', { props: { index: '0', 'popper-append-to-body': true, 'popper-class': 'base-menu--horizontal_popup' } }, [ h('template', { slot: 'title' }, [ _isNil(this.prefixIcon) ? h() : h( 'i', { class: this.prefixIcon + ' base-drop-down_prefix' }, [] ), this.createElSelf(this.curDropdownLabel) ]), this.createMenuElements() ] ) ] ) ] ); } }; BaseMenuButton.install = function(Vue, ElComponents) { // 用于按需加载的时候独立使用 devConsole('按需加载独立组件:' + BaseMenuButton.name); if (_isArray(ElComponents) && !_isEmpty(ElComponents)) { for (let i = 0; i < ElComponents.length; i++) { if (ElComponents[i].name !== BaseMenuButton.name) { Vue.use(ElComponents[i]); } } } Vue.component(BaseMenuButton.name, BaseMenuButton); }; export { BaseMenuButton };