shu-c-view
Version:
rollup 打包vue组件库框架
1,179 lines (1,177 loc) • 39.1 kB
JavaScript
/**
* @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 };