@fesjs/fes-design
Version:
fes-design for PC
103 lines (99 loc) • 3.58 kB
JavaScript
import { defineComponent, ref, onMounted, watch, createVNode, nextTick } from 'vue';
import { isFunction, isString } from 'lodash-es';
import getPrefixCls from '../_util/getPrefixCls';
import LoadingOutlined from '../icon/LoadingOutlined';
import Scrollbar from '../scrollbar';
import getElementFromVueInstance from '../_util/getElementFromVueInstance';
import { COMPONENT_NAME } from './const';
import useCascaderMenu from './useCascaderMenu';
import CascaderNode from './cascaderNode';
import { scrollIntoParentView } from './helper';
const prefixCls = getPrefixCls('cascader-menu');
const scrollbarContainerClass = `${prefixCls}-dropdown`;
const nodePrefixCls = getPrefixCls('cascader-node');
const cascaderMenuProps = {
menuKey: {
type: [String, Number],
required: true
},
initialLoaded: Boolean,
listEmptyText: String
};
var cascaderMenu = defineComponent({
name: COMPONENT_NAME.CASCADER_MENU,
props: cascaderMenuProps,
setup(props) {
const scrollbarRef = ref(null);
const {
menuNodes,
isCascaderOpened,
menuScrollNode
} = useCascaderMenu(props);
const renderNode = node => {
const itemSlots = {};
if (isFunction(node.prefix)) {
itemSlots.prefix = node.prefix;
}
if (isString(node.prefix)) {
itemSlots.prefix = () => node.prefix;
}
if (isFunction(node.suffix)) {
itemSlots.suffix = node.suffix;
}
if (isString(node.suffix)) {
itemSlots.suffix = () => node.suffix;
}
return createVNode(CascaderNode, {
"key": node.value,
"level": node.level,
"value": node.value,
"label": node.label,
"disabled": node.disabled,
"selectable": node.selectable,
"checkable": node.checkable,
"isLeaf": node.isLeaf
}, itemSlots);
};
const renderNodes = nodes => nodes.map(node => renderNode(node));
// 将第一个选中元素自动滚动到可见区域
const doScrollNode = async () => {
await nextTick();
if (!isCascaderOpened.value || !menuScrollNode.value) {
return;
}
const scrollbarEl = getElementFromVueInstance(scrollbarRef.value);
const scrollbarContainerEl = scrollbarEl === null || scrollbarEl === void 0 ? void 0 : scrollbarEl.querySelector(`.${scrollbarContainerClass}`);
const activeNodeEl = scrollbarContainerEl === null || scrollbarContainerEl === void 0 ? void 0 : scrollbarContainerEl.querySelector(
// matches unescaped double quotes
`.${nodePrefixCls}[data-value="${menuScrollNode.value.value}"]`);
if (activeNodeEl) {
scrollIntoParentView(activeNodeEl, scrollbarContainerEl);
}
};
onMounted(() => {
// 监听当前 menu 展示状态
watch([isCascaderOpened, () => props.menuKey], () => {
doScrollNode();
}, {
flush: 'post',
immediate: true
});
});
return () => createVNode(Scrollbar, {
"ref": scrollbarRef,
"class": `${prefixCls}-scrollbar`,
"containerClass": scrollbarContainerClass,
"key": props.menuKey
}, {
default: () => [createVNode("div", {
"class": `${prefixCls}`,
"role": "cascader-menu"
}, [menuNodes.value.length ? renderNodes(menuNodes.value) : props.initialLoaded ? createVNode("div", {
"class": `${prefixCls}-null`
}, [props.listEmptyText]) : createVNode("div", {
"class": `${prefixCls}-loading`
}, [createVNode(LoadingOutlined, null, null)])])]
});
}
});
export { cascaderMenu as default };