1
0
Fork 0
management/front/dkha-web-sz-main/node_modules/element-ui/packages/cascader-panel/src/cascader-menu.vue

139 lines
3.4 KiB
Vue

<script>
import ElScrollbar from 'element-ui/packages/scrollbar';
import CascaderNode from './cascader-node.vue';
import Locale from 'element-ui/src/mixins/locale';
import { generateId } from 'element-ui/src/utils/util';
export default {
name: 'ElCascaderMenu',
mixins: [Locale],
inject: ['panel'],
components: {
ElScrollbar,
CascaderNode
},
props: {
nodes: {
type: Array,
required: true
},
index: Number
},
data() {
return {
activeNode: null,
hoverTimer: null,
id: generateId()
};
},
computed: {
isEmpty() {
return !this.nodes.length;
},
menuId() {
return `cascader-menu-${this.id}-${this.index}`;
}
},
methods: {
handleExpand(e) {
this.activeNode = e.target;
},
handleMouseMove(e) {
const { activeNode, hoverTimer } = this;
const { hoverZone } = this.$refs;
if (!activeNode || !hoverZone) return;
if (activeNode.contains(e.target)) {
clearTimeout(hoverTimer);
const { left } = this.$el.getBoundingClientRect();
const startX = e.clientX - left;
const { offsetWidth, offsetHeight } = this.$el;
const top = activeNode.offsetTop;
const bottom = top + activeNode.offsetHeight;
hoverZone.innerHTML = `
<path style="pointer-events: auto;" fill="transparent" d="M${startX} ${top} L${offsetWidth} 0 V${top} Z" />
<path style="pointer-events: auto;" fill="transparent" d="M${startX} ${bottom} L${offsetWidth} ${offsetHeight} V${bottom} Z" />
`;
} else if (!hoverTimer) {
this.hoverTimer = setTimeout(this.clearHoverZone, this.panel.config.hoverThreshold);
}
},
clearHoverZone() {
const { hoverZone } = this.$refs;
if (!hoverZone) return;
hoverZone.innerHTML = '';
},
renderEmptyText(h) {
return (
<div class="el-cascader-menu__empty-text">{ this.t('el.cascader.noData') }</div>
);
},
renderNodeList(h) {
const { menuId } = this;
const { isHoverMenu } = this.panel;
const events = { on: {} };
if (isHoverMenu) {
events.on.expand = this.handleExpand;
}
const nodes = this.nodes.map((node, index) => {
const { hasChildren } = node;
return (
<cascader-node
key={ node.uid }
node={ node }
node-id={ `${menuId}-${index}` }
aria-haspopup={ hasChildren }
aria-owns = { hasChildren ? menuId : null }
{ ...events }></cascader-node>
);
});
return [
...nodes,
isHoverMenu ? <svg ref='hoverZone' class='el-cascader-menu__hover-zone'></svg> : null
];
}
},
render(h) {
const { isEmpty, menuId } = this;
const events = { nativeOn: {} };
// optimize hover to expand experience (#8010)
if (this.panel.isHoverMenu) {
events.nativeOn.mousemove = this.handleMouseMove;
// events.nativeOn.mouseleave = this.clearHoverZone;
}
return (
<el-scrollbar
tag="ul"
role="menu"
id={ menuId }
class="el-cascader-menu"
wrap-class="el-cascader-menu__wrap"
view-class={{
'el-cascader-menu__list': true,
'is-empty': isEmpty
}}
{ ...events }>
{ isEmpty ? this.renderEmptyText(h) : this.renderNodeList(h) }
</el-scrollbar>
);
}
};
</script>