UNPKG

shu-c-view

Version:

rollup 打包vue组件库框架

1,179 lines (1,177 loc) 39.1 kB
/** * @desc NavMenu 导航菜单 */ import _assign from 'lodash/assign'; import _get from 'lodash/get'; import _has from 'lodash/has'; import _isEmpty from 'lodash/isEmpty'; import _map from 'lodash/map'; import _split from 'lodash/split'; import _join from 'lodash/join'; import _last from 'lodash/last'; import _isNil from 'lodash/isNil'; import _includes from 'lodash/includes'; import _find from 'lodash/find'; import _omit from 'lodash/omit'; import _every from 'lodash/every'; import _filter from 'lodash/filter'; import _isArray from 'lodash/isArray'; import _sum from 'lodash/sum'; import jQuery from 'jquery'; import _round from 'lodash/round'; import { BaseBorderLayout } from '../border-layout/index.js'; import { devConsole, apply } from '../helper/util.js'; import MoreMenu from './more-menu.js'; const BaseNavMenu = { name: 'BaseNavMenu', mixins: [MoreMenu], components: { BaseBorderLayout }, inheritAttrs: false, props: { props: { type: Object, default() { return { menuCode: 'menuCode', menuName: 'menuName', menuUrl: 'menuUrl', iconUrl: 'iconUrl', children: 'children' }; } }, nodeKey: { type: String, default: 'id' }, // 导航菜单顶部标题栏文字 navTitle: { type: String }, // 导航菜单顶部标题栏文字左侧小图标 navIcon: { type: String }, // 收起导航的位置 collapsePosition: { type: String, default: 'top', validator(value) { return ['top', 'bottom'].indexOf(value) !== -1; } }, collapseText: { type: String, default: '收起导航' }, // 菜单数据 menus: { type: Array, default() { return []; } }, // subMenu 参数 subMenuProps: { type: Object, default() { return {}; } }, // 是否渲染 收起导航 的节点 isRenderCollapsed: { type: Boolean, default: true }, // 是否渲染 导航菜单顶部标题栏 的节点 isRenderNavTitle: { type: Boolean, default: true }, // 侧栏收起状态 collapsed: { type: Boolean, default: false }, // 图标的尺寸 svgSize: { type: String, default: '16px' }, // svg 图标集合 [{name: 'studyState', component: studyState}] svgIcons: { type: Array, default() { return []; } }, // 菜单内容区上面和下面两块区间的高度 titleBlockHeight: { type: String, default: '40px' }, // 顶部边距 paddingTop: { type: String, default: '0' }, // el-submenu__title 的标题文字颜色 menuTitleTextColor: { type: String, default: 'rgb(191, 203, 217)' }, // 禁用的节点,值必须比配 nodeKey disabledKeys: { type: Array, default() { return []; } }, // 不渲染的节点menuCode noRenderCodes: { type: Array, default() { return []; } }, // 是否需要滚动区域 /* isScrollbar: { type: Boolean, default: true }, */ // 是否只渲染第一级subMenu isRenderFirstSubMenu: { type: Boolean, default: false }, // 是否渲染图标 isRenderIcon: { type: Boolean, default: true }, // 是否启用`更多`展示功能—水平布局`horizontal`时起效 isEnableMoreMenu: { type: Boolean, default: false }, // 子菜单打开的触发方式(只在 mode 为 horizontal 时有效) menuTrigger: { type: String, default: 'hover' }, // 模式 mode: { type: String, default: 'vertical', validator(value) { return ['vertical', 'horizontal'].includes(value); } }, // 中间内容区域自定义样式 centerContainerCls: { type: String, default: '' } }, watch: { collapsed(val, oldVal) { if (val !== oldVal) { this.isCollapse = val; } }, isCollapse(val) { this.$nextTick(() => { this.$emit('collapse', val); // 收缩事件 }); }, /* menus: { // 监听的对象 handler: function (newV, oldV) { console.info('------------------------------------------'); this.firstSubMenuIndex = ''; this.firstElMenuItem = ''; } } */ menus() { this.firstElMenuItem = ''; this.subMenuList = []; this.nodeKeyPaths = []; this.grade1Index = ''; } }, data() { this.defaultRouterPath = []; // 默认打开的第一个路由 this.defaultBreadCrumbPath = []; // 默认打开的第一个路由对应的面包屑地址 this.grade1Index = ''; // 一级菜单 index,适用于 1级菜单和2级菜单分离时设置(比如:顶部是一级菜单,左侧是二级菜单) this.subMenuList = []; this.nodeKeyPaths = []; // nodeKey 对应的 path this.firstElMenuItem = ''; this.firstSubMenuIndex = ''; this.openMenuIndex = null; // 打开open打开的菜单index return { collapseIcon: 'el-icon-s-fold', // 折叠图表 isCollapse: this.collapsed, // 是否水平折叠收起菜单 (仅在 mode 为 vertical 时可用) collapsePanelWidth: 'auto', // westWidth: '280px', level: this.elMenuItemLevel }; }, created() { // setTimeout(() => { // this.$emit('update:width', '64px'); // console.log(this.$refs[`${this._uid}-base-nav-menu-ref`]); // this.$refs[`${this._uid}-base-nav-menu-ref`].$el.style.width = '240px'; // }, 3000); // setTimeout(() => { // this.$refs[`${this._uid}-base-nav-menu-ref`].$el.style.width = '240px'; // }, 0); // console.log('22222222222'); }, mounted() { this.$nextTick(function() { // DOM 现在更新了 // `this` 绑定到当前实例 this.collapsePanelWidth = `${this.$parent.$el.clientWidth}px`; }); }, methods: { /** * @desc 设置顶层 index 下标,用于一级菜单和二级菜单分离时区分不同的二级菜单 index * @param {Number} index - 路径下标 */ setGrade1Index(index = 0) { this.grade1Index = index; }, /** * @desc 获取第一个 sub-menu 的 index 属性值 */ getFirstSubMenuIndex() { return this.firstSubMenuIndex; }, /** * @desc 获取第一个 el-menu-item 的 index 属性值 */ getFirstElMenuItem() { return this.firstElMenuItem; }, /** * @desc 获取 sub-menu index列表 */ getSubMenuIndexList() { return this.subMenuList; // 1.2.56 }, getSubMenuList() { return this.subMenuList; // 兼容 1.2.56 之前的版本 }, /** * @desc 获取默认打开的 menu 对应的面包屑路径 */ getDefaultBreadCrumbPath() { return this.defaultBreadCrumbPath; }, /** * @desc 通过 el-menu-item 的 index 转换面包屑路径 * @param {String} keyPath - 路径 0-0-0 * @param {Boolean} isToPath=false - 是否需要返回 to 用于面包屑的路由跳转 */ getKeyPath2BreadCrumbPath(keyPath, isToPath = false) { let menus = this.menus; const breadCrumbPath = []; const aKeyPathList = _split(keyPath, '-'); for (let i = 0, len = aKeyPathList.length; i < len; i++) { const menu = menus[aKeyPathList[i]]; if (menu && _has(menu, this.props.menuName)) { const obj = { text: _get(menu, this.props.menuName), menuCode: _get(menu, this.props.menuCode), menuUrl: _get(menu, this.props.menuUrl) }; if (isToPath) { obj.to = _get(menu, this.props.menuCode); } breadCrumbPath.push(obj); } if ( !_isNil(_get(menu, this.props.children)) && _has(menu, this.props.children) && _get(menu, this.props.children, []).length > 0 ) { menus = _get(menu, this.props.children); } } return breadCrumbPath; }, /** * @desc 根据菜单的 index 获取对应的路由路径 * @param {String} index - 菜单对应的 index 属性 0-0-1 */ getRouterPath(index) { const sRouterPath = []; let menus = this.menus; for (const value of Object.values(_split(index, '-'))) { const menu = menus[value]; if (menu) { menus = _get(menu, this.props.children); sRouterPath.push(_get(menu, this.props.menuCode)); } } return _join(sRouterPath, '/'); }, /** * @desc 根据菜单的 index 获取菜单列表中最内部的一个节点 * @param {String} index - 菜单对应的 index 属性 */ getLastMenu(index) { const sRouterPath = []; let menus = this.menus; for (const value of Object.values(_split(index, '-'))) { const menu = menus[value]; if (menu) { menus = _get(menu, this.props.children); sRouterPath.push(menu); } } return _last(sRouterPath); }, /** * @desc 通过 nodeKey 获取指定菜单的 path * @param {String|Number} value - 菜单 nodeKey 对应的唯一值 */ getMenuPathByNodeKey(value) { return _find(this.nodeKeyPaths, v => v.nodeKey === value); }, /** * @desc 展开指定的 sub-menu * @param {String} index - 需要打开的 sub-menu 的 index */ open(index = '0') { this.openMenuIndex = index; this.$refs[`${this._uid}-base-nav-menu-ref`].open(index); }, /** * @desc 收起指定的 sub-menu * @param {String} index - 需要收起的 sub-menu 的 index */ close(index = '0') { this.openMenuIndex = null; this.$refs[`${this._uid}-base-nav-menu-ref`].close(index); }, /** * @desc 创建 导航菜单顶部标题栏 */ createNavTitle() { const vNode = []; if (_isNil(this.navTitle)) { return vNode; } let backgroundColor = this.$attrs.backgroundColor; if (_has(this.$attrs, 'background-color')) { backgroundColor = this.$attrs['background-color']; } const style = { 'background-color': backgroundColor, // height: '100%' // height: this.titleBlockHeight, 'line-height': this.titleBlockHeight }; // if (this.collapsePosition === 'top') { // _assign(style, { position: 'absolute', bottom: '0px' }); // } vNode.push( this.$createElement( 'div', { class: { 'nav-top-title': true }, style }, [ !_isNil(this.navIcon) && this.$createElement('i', { class: this.navIcon }, []), this.$createElement( 'span', { style: { display: !this.isCollapse ? 'inline-block' : 'none' } }, this.navTitle ) ] ) ); return vNode; }, /** * @desc 创建 收起导航 */ createContractBlock() { const vNode = []; if ( !_has(this.$attrs, 'mode') || (_has(this.$attrs, 'mode') && this.$attrs.mode !== 'horizontal') ) { let backgroundColor = this.$attrs.backgroundColor; if (_has(this.$attrs, 'background-color')) { backgroundColor = this.$attrs['background-color']; } const style = { 'background-color': backgroundColor, height: '100%' // height: this.titleBlockHeight }; // if (this.collapsePosition === 'bottom') { // _assign(style, { position: 'absolute', bottom: '0px' }); // } else { // _assign(style, { // 'border-bottom': '1px solid rgba(236, 236, 236, 0.5)' // }); // } vNode.push( // this.$createElement('template', { slot: 'default' }, [ this.$createElement( 'div', { style, class: { collapse: true }, on: { click: () => { this.isCollapse = !this.isCollapse; /* this.collapseIcon = this.isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'; if (!this.isCollapse) { // this.westWidth = '60px'; } */ } } }, [ this.$createElement('i', { class: { [this.collapseIcon]: true } }), this.$createElement( 'span', { style: { display: !this.isCollapse ? 'inline-block' : 'none' } }, this.collapseText ) ] ) // ]) ); } return vNode; }, createElMenu() { const h = this.$createElement; const isVertical = this.mode === 'vertical'; return h( 'el-menu', { ref: `${this._uid}-base-nav-menu-ref`, attrs: { id: this.$attrs.id }, class: { 'base-nav-menu': true, 'base-vertical-nav-menu': isVertical, 'base-more-nav-menu': this.isEnableMoreMenu && !isVertical }, style: { marginLeft: this.isEnableMoreMenu && !isVertical ? `${this.marginLeft}px` : false // display: 'flex', // position: 'relative' }, props: _assign( {}, _omit(this.$attrs, [ 'backgroundColor', 'collapseText', 'collapsePosition', 'navIcon', 'defaultActive', 'background-color', 'collapse-text', 'collapse-position', 'nav-icon', 'default-active', 'menuTrigger', 'menu-trigger', 'mode' ]), { 'default-active': `${this.$attrs.defaultActive}` || `${this.$attrs['default-active']}`, collapse: this.isCollapse, 'background-color': this.$attrs.backgroundColor || this.$attrs['background-color'], menuTrigger: this.menuTrigger, mode: this.mode } ), on: { select: (index, indexPath) => { this.$emit('select', index, indexPath); this.openMenuIndex = null; const isVertical = this.mode === 'vertical'; if (!isVertical && this.isEnableMoreMenu) { const sOneLevelMenu = indexPath[0]; // 一级菜单 // console.log('sOneLevelMenu: ', sOneLevelMenu); const $ = jQuery; const jQueryEl = $( this.$refs[`${this._uid}-base-nav-menu-ref`].$el ) .children() .eq(sOneLevelMenu); const jQueryNextEl = jQueryEl.next(); // console.log(jQueryEl, jQueryNextEl); if (Math.abs(this.marginLeft) - jQueryEl.position().left > 0) { // 左侧 console.log('左侧'); this.isRenderRightArrow = true; this.$nextTick(() => { const position = jQueryNextEl.position(); const showItemElWidth = _round(position.left, 0) - Math.abs(this.marginLeft); // console.log('showItemElWidth: ', showItemElWidth); const coverItemWidth = _round( jQueryEl.outerWidth(true) - showItemElWidth, 0 ); // console.log('coverItemWidth: ', coverItemWidth); this.marginLeft += coverItemWidth; // console.log('this.marginLeft: ', this.marginLeft); if (this.marginLeft === 0) { this.isRenderLeftArrow = false; } }); } else { // 右侧 console.log('右侧'); this.isRenderLeftArrow = true; this.$nextTick(() => { /* const jQueryNextElPosition = jQueryNextEl.position(); const showNextItemElLeft = _round(jQueryNextElPosition.left, 0) - Math.abs(this.marginLeft); console.log('showNextItemElLeft: ', showNextItemElLeft); */ const leftVal = _round(jQueryEl.position().left, 0) - Math.abs(this.marginLeft); const itemElWidth = _round(jQueryEl.outerWidth(true), 0); // console.log('leftVal: ', leftVal, itemElWidth); const itemBoxWidth = _round( $(this.$refs.itemBoxRef).outerWidth(true, 0) ); // console.log('itemBoxWidth: ', itemBoxWidth); const showItemElWidth = _round(itemBoxWidth - leftVal, 0); const coverItemBackElWidth = _round( itemElWidth - showItemElWidth, 0 ); // 点击元素后面的覆盖值 /* const marginLeftVal = coverItemBackElWidth; console.log( 'coverItemBackElWidth: ', coverItemBackElWidth, marginLeftVal ); */ // console.log( // 'this.isRenderLeftArrow: ', // jQueryNextEl.length // ); if (coverItemBackElWidth > 0) { this.marginLeft -= coverItemBackElWidth; } if (this.marginLeft === 0) { this.isRenderLeftArrow = false; } if (jQueryNextEl.length === 0) { this.isRenderRightArrow = false; } }); } } }, open: (index, indexPath) => { this.openMenuIndex = index; this.$emit('open', index, indexPath); }, close: (index, indexPath) => { this.openMenuIndex = null; this.$emit('close', index, indexPath); } } }, [this.createSubMenu()] ); }, /** * @desc 创建 el-subMenu */ createSubMenu() { this.subMenuList = []; this.defaultBreadCrumbPath = []; const subMenuElements = []; for (let i = 0, len = this.menus.length; i < len; i++) { const menu = this.menus[i]; const currentMenuCode = _get(menu, this.props.menuCode, ''); if (_includes(this.noRenderCodes, currentMenuCode)) { continue; } const everyChildren = _every(menu[this.props.children], v => { return _includes(this.noRenderCodes, v[this.props.menuCode]); }); let menuVNode = null; const iconUrl = this.getIconNode(menu); if (_has(menu, 'hide') && menu.hide === true) { continue; } const h = this.$createElement; if ( _has(menu, this.props.children) && !_isEmpty(_get(menu, this.props.children, [])) && !everyChildren ) { const subMenuIndex = this.grade1Index !== '' ? `${this.grade1Index}-${i}` : `${i}`; this.subMenuList.push(subMenuIndex); if (i === 0) { this.defaultBreadCrumbPath.push({ text: _get(menu, this.props.menuName, '') }); } if (this.firstSubMenuIndex === '') { this.firstSubMenuIndex = subMenuIndex; } // 二级 const style = {}; if (!_get(menu, 'isGroupShow', true)) { style.display = 'none'; // 是否要在组内一起展示该菜单 } const nodeKeyValue = _get(menu, this.nodeKey, ''); this.nodeKeyPaths.push({ nodeKey: _get(menu, this.nodeKey, ''), path: subMenuIndex }); menuVNode = h( 'el-submenu', { key: subMenuIndex, props: { 'popper-append-to-body': true, // 一级子菜单:true / 非一级子菜单:false index: subMenuIndex, disabled: _includes(this.disabledKeys, nodeKeyValue), ..._omit(this.subMenuProps, [ 'popper-append-to-body', 'index', 'disabled' ]) }, style }, [ h('template', { slot: 'title' }, [ /* this.$createElement('i', { class: _get(menu, 'iconUrl', '') }), */ iconUrl, // _get(menu, this.props.menuName, '') h( 'span', { style: { color: this.menuTitleTextColor } }, _get(menu, this.props.menuName, '') ), _has(this.$scopedSlots, 'labelSuffixScope') && !this.isCollapse ? this.$scopedSlots.labelSuffixScope(apply({}, menu)) : h() ]), this.createElMenuItemGroup(i, _get(menu, this.props.children)) ] ); } else { const menuItemIndex = this.grade1Index !== '' ? `${this.grade1Index}-${i}` : `${i}`; if (this.firstElMenuItem === '') { this.firstElMenuItem = menuItemIndex; } if (i === 0) { this.defaultBreadCrumbPath.push({ text: _get(menu, this.props.menuName, '') }); } const style = {}; if (!_get(menu, 'isGroupShow', true)) { style.display = 'none'; // 是否要在组内一起展示该菜单 } const nodeKeyValue = _get(menu, this.nodeKey, ''); this.nodeKeyPaths.push({ nodeKey: _get(menu, this.nodeKey, ''), path: menuItemIndex }); menuVNode = h( 'el-menu-item', { key: menuItemIndex, props: { index: menuItemIndex, disabled: _includes(this.disabledKeys, nodeKeyValue) }, style }, [ iconUrl, // _get(menu, this.props.menuName, '') h('span', {}, _get(menu, this.props.menuName, '')), _has(this.$scopedSlots, 'labelSuffixScope') && !this.isCollapse ? this.$scopedSlots.labelSuffixScope(apply({}, menu)) : h() ] ); } subMenuElements.push(menuVNode); } return subMenuElements; }, /** * @desc 创建 el-menu-item */ createElMenuItemGroup(parentIndex = 0, children = []) { const vNodes = []; for (let i = 0, len = children.length; i < len; i++) { // 三级 const iconUrl = this.getIconNode(children[i]); const currentMenuCode = children[i][this.props.menuCode]; if (_includes(this.noRenderCodes, currentMenuCode)) { continue; } const everyChildren = _every(children[i][this.props.children], v => { return _includes(this.noRenderCodes, v[this.props.menuCode]); }); if ( _has(children[i], this.props.children) && !_isEmpty(_get(children[i], this.props.children)) && !everyChildren && !this.isRenderFirstSubMenu ) { if (i === 0) { this.defaultBreadCrumbPath.push({ text: _get(children[i], this.props.menuName, '') }); } const subMenuItems = _map( _filter( _get(children[i], this.props.children), v => !_includes(this.noRenderCodes, v[this.props.menuCode]) ), (item, key) => { const iconUrl = this.getIconNode(item); if (key === 0) { this.defaultBreadCrumbPath.push({ text: _get(item, this.props.menuName, '') }); } const menuItemIndex = this.grade1Index !== '' ? `${this.grade1Index}-${parentIndex}-${i}-${key}` : `${parentIndex}-${i}-${key}`; // console.log('children-menuItemIndex: ', menuItemIndex, item.name); /* if (this.firstElMenuItem === '') { this.firstElMenuItem = menuItemIndex; } */ const nodeKeyValue = _get(item, this.nodeKey, ''); this.nodeKeyPaths.push({ nodeKey: _get(item, this.nodeKey, ''), path: menuItemIndex }); const everyChildren = _every(item[this.props.children], v => { return _includes(this.noRenderCodes, v[this.props.menuCode]); }); if ( _has(item, this.props.children) && !_isEmpty(_get(item, this.props.children)) && !everyChildren ) { const subMenuItems = this.createElMenuItemGroup( menuItemIndex, _get(item, this.props.children), key ); const style = {}; if (!_get(item, 'isGroupShow', true)) { style.display = 'none'; // 是否要在组内一起展示该菜单 } this.subMenuList.push(menuItemIndex); return this.$createElement( 'el-submenu', { key: menuItemIndex, props: { 'popper-append-to-body': false, // 一级子菜单:true / 非一级子菜单:false index: menuItemIndex, disabled: _includes(this.disabledKeys, nodeKeyValue), ..._omit(this.subMenuProps, [ 'popper-append-to-body', 'index', 'disabled' ]) }, style }, [ this.$createElement('template', { slot: 'title' }, [ /* this.$createElement('i', { class: _get(children[i], 'iconUrl', '') }), */ iconUrl, _get(item, this.props.menuName, ''), _has(this.$scopedSlots, 'labelSuffixScope') ? this.$scopedSlots.labelSuffixScope(apply({}, item)) : this.$createElement() ]), subMenuItems ] ); } if (this.firstElMenuItem === '') { this.firstElMenuItem = menuItemIndex; } return this.$createElement( 'el-menu-item', { props: { index: menuItemIndex, disabled: _includes(this.disabledKeys, nodeKeyValue) } }, [ // this.$createElement('i', { class: _get(item, 'iconUrl', '') }), iconUrl, _get(item, this.props.menuName, ''), _has(this.$scopedSlots, 'labelSuffixScope') ? this.$scopedSlots.labelSuffixScope(apply({}, item)) : this.$createElement() ] ); } ); const subMenuIndex = this.grade1Index !== '' ? `${this.grade1Index}-${parentIndex}-${i}` : `${parentIndex}-${i}`; // console.log('subMenuIndex: ', subMenuIndex); this.subMenuList.push(subMenuIndex); const style = {}; if (!_get(children[i], 'isGroupShow', true)) { style.display = 'none'; // 是否要在组内一起展示该菜单 } const nodeKeyValue = _get(children[i], this.nodeKey, ''); this.nodeKeyPaths.push({ nodeKey: _get(children[i], this.nodeKey, ''), path: subMenuIndex }); vNodes.push( this.$createElement( 'el-submenu', { key: subMenuIndex, props: { 'popper-append-to-body': false, // 一级子菜单:true / 非一级子菜单:false index: subMenuIndex, disabled: _includes(this.disabledKeys, nodeKeyValue), ..._omit(this.subMenuProps, [ 'popper-append-to-body', 'index', 'disabled' ]) }, style }, [ this.$createElement('template', { slot: 'title' }, [ /* this.$createElement('i', { class: _get(children[i], 'iconUrl', '') }), */ iconUrl, _get(children[i], this.props.menuName, ''), _has(this.$scopedSlots, 'labelSuffixScope') ? this.$scopedSlots.labelSuffixScope(apply({}, children[i])) : this.$createElement() ]), subMenuItems ] ) ); } else { if (i === 0) { this.defaultBreadCrumbPath.push({ text: _get(children[i], this.props.menuName, '') }); } const indexPath = this.grade1Index !== '' ? `${this.grade1Index}-${parentIndex}-${i}` : `${parentIndex}-${i}`; // console.log('indexPath: ', indexPath); if (this.firstElMenuItem === '') { this.firstElMenuItem = indexPath; } const style = {}; if (!_get(children[i], 'isGroupShow', true)) { style.display = 'none'; // 是否要在组内一起展示该菜单 } const nodeKeyValue = _get(children[i], this.nodeKey, ''); this.nodeKeyPaths.push({ nodeKey: _get(children[i], this.nodeKey, ''), path: indexPath }); vNodes.push( this.$createElement( 'el-menu-item', { style, props: { index: indexPath, disabled: _includes(this.disabledKeys, nodeKeyValue) } }, [ /* this.$createElement('i', { class: _get(children[i], 'iconUrl', '') }), */ iconUrl, _get(children[i], this.props.menuName, ''), _has(this.$scopedSlots, 'labelSuffixScope') ? this.$scopedSlots.labelSuffixScope(apply({}, children[i])) : this.$createElement() ] ) ); } } return vNodes; }, /** * @desc 转换 menu 菜单中的 iconUrl * @param {Object} item - menu 对象 */ getIconNode(item = {}) { if (!this.isRenderIcon) { return this.$createElement(); } let iconUrl = _get(item, this.props.iconUrl, ''); if (_includes(iconUrl, 'svg-')) { // svg图 const curUrl = iconUrl.replace('svg-', ''); const svgObj = _find(this.svgIcons, o => o.name === curUrl); if (!_isNil(svgObj)) { iconUrl = this.$createElement(_get(svgObj, 'component', 'span'), { style: { width: this.svgSize, height: this.svgSize, marginRight: '5px', display: 'inline' } }); } else { iconUrl = this.$createElement('i', {}, []); } } else if (/\.(gif|png|jpg|jpeg|webp|svg|psd|bmp|tif)$/.test(iconUrl)) { // 静态资源图 iconUrl = this.$createElement('img', { style: { marginRight: '5px', display: 'inline' }, attrs: { src: iconUrl, width: this.svgSize, height: this.svgSize } }); } else if (iconUrl.indexOf('symbol-') !== -1) { // symbol 图 iconUrl = this.$createElement( 'base-svg-icon', { style: { marginRight: '5px' }, props: { size: this.svgSize, iconname: iconUrl.replace('symbol-', '') } }, [] ); } else { iconUrl = this.$createElement('i', { class: iconUrl }); } return iconUrl; } }, render(h) { const style = {}; if (this.mode === 'horizontal') { style.width = '100%'; } let northHeight = this.titleBlockHeight; let southHeight = this.titleBlockHeight; if (!this.isRenderNavTitle) { if (this.collapsePosition === 'top') { southHeight = '0px'; } else { northHeight = '0px'; } } let collapsedNode = h(); let titleNode = h(); if (this.isRenderCollapsed) { collapsedNode = this.createContractBlock(); } if (this.isRenderNavTitle) { titleNode = this.createNavTitle(); } const isVertical = this.mode === 'vertical'; return h( BaseBorderLayout, { props: { northHeight, southHeight, eastWidth: !isVertical && this.isEnableMoreMenu ? '25px' : '0', westWidth: !isVertical && this.isEnableMoreMenu ? '25px' : '0', isPadding: false, westCls: '', eastCls: '', ctCls: 'base-nav-menu-box' }, style: { 'background-color': this.$attrs.backgroundColor || this.$attrs['background-color'] // 兼容QQ浏览器 }, on: { 'hook:mounted': () => { if (!isVertical && this.isEnableMoreMenu) { this.$nextTick(() => { const $ = jQuery; const jMenuEl = $( this.$refs[`${this._uid}-base-nav-menu-ref`].$el ); const menuParentEl = jMenuEl.parent(); const menuItemList = jMenuEl.children(); const parentWidth = menuParentEl.width(); // const parentHeight = menuParentEl.height(); const menuItemAllWidth = _sum( _map(menuItemList, menuItem => $(menuItem).width()) ); this.itemRefList = menuItemList; if (menuItemAllWidth > parentWidth) { // 大于父元素的宽度 this.isRenderLeftArrow = false; this.isRenderRightArrow = true; } else { this.isRenderLeftArrow = false; this.isRenderRightArrow = false; } }); } } } }, [ h('template', { slot: 'north' }, [ this.collapsePosition === 'top' ? collapsedNode : titleNode ]), h('template', { slot: 'center' }, [ h( 'div', { style: { 'background-color': this.$attrs.backgroundColor || this.$attrs['background-color'], height: '100%', position: 'relative' }, class: !isVertical && this.isEnableMoreMenu ? `${this.centerContainerCls} border-box` : this.centerContainerCls, ref: 'itemBoxRef' // key: 'menuOuterBoxKey' }, [ /* this.isScrollbar ? h('el-scrollbar', { style: { height: '100%' } }, [ this.createElMenu() ]) : this.createElMenu() */ this.createElMenu() ] ) ]), !isVertical && this.isEnableMoreMenu && this.isRenderRightArrow ? h('template', { slot: 'east' }, [ h( 'div', { class: 'base-nav-menu-box__arrow', on: { click: this.onLeftMargin } }, [ _has(this.$slots, 'rightArrow') ? this.$slots.rightArrow : h( 'i', { class: { 'base-nav-menu-box__arrow--right': true, 'el-icon-caret-right': true } }, [] ) ] ) ]) : h(), !isVertical && this.isEnableMoreMenu && this.isRenderLeftArrow ? h('template', { slot: 'west' }, [ h( 'div', { class: 'base-nav-menu-box__arrow', on: { click: this.onRightMargin } }, [ _has(this.$slots, 'leftArrow') ? this.$slots.leftArrow : h( 'i', { class: { 'base-nav-menu-box__arrow--left': true, 'el-icon-caret-left': true } }, [] ) ] ) ]) : h(), h('template', { slot: 'south' }, [ this.collapsePosition === 'bottom' ? collapsedNode : titleNode ]) ] ); } }; BaseNavMenu.install = function(Vue, ElComponents) { // 用于按需加载的时候独立使用 devConsole(`按需加载独立组件:${BaseNavMenu.name}`); if (_isArray(ElComponents) && !_isEmpty(ElComponents)) { for (let i = 0; i < ElComponents.length; i++) { if (ElComponents[i].name !== BaseNavMenu.name) { Vue.use(ElComponents[i]); } } } Vue.component(BaseNavMenu.name, BaseNavMenu); }; export { BaseNavMenu };