vxe-table-demonic
Version:
一个基于 vue 的 PC 端表单/表格组件,支持增删改查、虚拟列表、虚拟树、懒加载、快捷菜单、数据校验、树形结构、打印导出、表单渲染、数据分页、弹窗、自定义模板、渲染器、JSON 配置式...
344 lines (343 loc) • 12.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _vue = require("vue");
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _conf = _interopRequireDefault(require("../../v-x-e-table/src/conf"));
var _size = require("../../hooks/size");
var _dom = require("../../tools/dom");
var _utils = require("../../tools/utils");
var _event = require("../../tools/event");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _default = (0, _vue.defineComponent)({
name: 'VxePulldown',
props: {
modelValue: Boolean,
disabled: Boolean,
placement: String,
size: {
type: String,
default: function () {
return _conf.default.size;
}
},
className: [String, Function],
popupClassName: [String, Function],
destroyOnClose: Boolean,
transfer: Boolean
},
emits: ['update:modelValue', 'hide-panel'],
setup: function (props, context) {
var slots = context.slots,
emit = context.emit;
var xID = _xeUtils.default.uniqueId();
var computeSize = (0, _size.useSize)(props);
var reactData = (0, _vue.reactive)({
inited: false,
panelIndex: 0,
panelStyle: null,
panelPlacement: null,
visiblePanel: false,
animatVisible: false,
isActivated: false
});
var refElem = (0, _vue.ref)();
var refPulldowContent = (0, _vue.ref)();
var refPulldowPnanel = (0, _vue.ref)();
var refMaps = {
refElem: refElem
};
var $xepulldown = {
xID: xID,
props: props,
context: context,
reactData: reactData,
getRefMaps: function () {
return refMaps;
}
};
var pulldownMethods = {};
var updateZindex = function () {
if (reactData.panelIndex < (0, _utils.getLastZIndex)()) {
reactData.panelIndex = (0, _utils.nextZIndex)();
}
};
var isPanelVisible = function () {
return reactData.visiblePanel;
};
/**
* 手动更新位置
*/
var updatePlacement = function () {
return (0, _vue.nextTick)().then(function () {
var transfer = props.transfer,
placement = props.placement;
var panelIndex = reactData.panelIndex,
visiblePanel = reactData.visiblePanel;
if (visiblePanel) {
var targetElem = refPulldowContent.value;
var panelElem = refPulldowPnanel.value;
if (panelElem && targetElem) {
var targetHeight = targetElem.offsetHeight;
var targetWidth = targetElem.offsetWidth;
var panelHeight = panelElem.offsetHeight;
var panelWidth = panelElem.offsetWidth;
var marginSize = 5;
var panelStyle = {
zIndex: panelIndex
};
var _a = (0, _dom.getAbsolutePos)(targetElem),
boundingTop = _a.boundingTop,
boundingLeft = _a.boundingLeft,
visibleHeight = _a.visibleHeight,
visibleWidth = _a.visibleWidth;
var panelPlacement = 'bottom';
if (transfer) {
var left = boundingLeft;
var top_1 = boundingTop + targetHeight;
if (placement === 'top') {
panelPlacement = 'top';
top_1 = boundingTop - panelHeight;
} else if (!placement) {
// 如果下面不够放,则向上
if (top_1 + panelHeight + marginSize > visibleHeight) {
panelPlacement = 'top';
top_1 = boundingTop - panelHeight;
}
// 如果上面不够放,则向下(优先)
if (top_1 < marginSize) {
panelPlacement = 'bottom';
top_1 = boundingTop + targetHeight;
}
}
// 如果溢出右边
if (left + panelWidth + marginSize > visibleWidth) {
left -= left + panelWidth + marginSize - visibleWidth;
}
// 如果溢出左边
if (left < marginSize) {
left = marginSize;
}
Object.assign(panelStyle, {
left: "".concat(left, "px"),
top: "".concat(top_1, "px"),
minWidth: "".concat(targetWidth, "px")
});
} else {
if (placement === 'top') {
panelPlacement = 'top';
panelStyle.bottom = "".concat(targetHeight, "px");
} else if (!placement) {
// 如果下面不够放,则向上
if (boundingTop + targetHeight + panelHeight > visibleHeight) {
// 如果上面不够放,则向下(优先)
if (boundingTop - targetHeight - panelHeight > marginSize) {
panelPlacement = 'top';
panelStyle.bottom = "".concat(targetHeight, "px");
}
}
}
}
reactData.panelStyle = panelStyle;
reactData.panelPlacement = panelPlacement;
}
}
return (0, _vue.nextTick)();
});
};
var hidePanelTimeout;
/**
* 显示下拉面板
*/
var showPanel = function () {
if (!reactData.inited) {
reactData.inited = true;
}
return new Promise(function (resolve) {
if (!props.disabled) {
clearTimeout(hidePanelTimeout);
reactData.isActivated = true;
reactData.animatVisible = true;
setTimeout(function () {
reactData.visiblePanel = true;
emit('update:modelValue', true);
updatePlacement();
setTimeout(function () {
resolve(updatePlacement());
}, 40);
}, 10);
updateZindex();
} else {
(0, _vue.nextTick)(function () {
resolve();
});
}
});
};
/**
* 隐藏下拉面板
*/
var hidePanel = function () {
reactData.visiblePanel = false;
reactData.isActivated = false;
(0, _dom.blurRecursive)(refPulldowContent.value);
emit('update:modelValue', false);
return new Promise(function (resolve) {
if (reactData.animatVisible) {
hidePanelTimeout = window.setTimeout(function () {
reactData.animatVisible = false;
(0, _vue.nextTick)(function () {
resolve();
});
}, 350);
} else {
(0, _vue.nextTick)(function () {
resolve();
});
}
});
};
/**
* 切换下拉面板
*/
var togglePanel = function () {
if (reactData.visiblePanel) {
return hidePanel();
}
return showPanel();
};
var handleGlobalMousewheelEvent = function (evnt) {
var disabled = props.disabled;
var visiblePanel = reactData.visiblePanel;
var panelElem = refPulldowPnanel.value;
if (!disabled) {
if (visiblePanel) {
if ((0, _dom.getEventTargetNode)(evnt, panelElem).flag) {
updatePlacement();
} else if (!(0, _dom.isInside)(evnt.target, refPulldowPnanel.value) && Array.from(evnt.target.classList).every(function (e) {
return _dom.ignoreWheelList.every(function (i) {
return !e.startsWith(i);
});
})) {
hidePanel();
pulldownMethods.dispatchEvent('hide-panel', {}, evnt);
}
}
}
};
var handleGlobalMousedownEvent = function (evnt) {
var disabled = props.disabled;
var visiblePanel = reactData.visiblePanel;
var el = refElem.value;
var panelElem = refPulldowPnanel.value;
if (!disabled) {
reactData.isActivated = (0, _dom.getEventTargetNode)(evnt, el).flag || (0, _dom.getEventTargetNode)(evnt, panelElem).flag;
if (visiblePanel && !reactData.isActivated) {
hidePanel();
pulldownMethods.dispatchEvent('hide-panel', {}, evnt);
}
}
};
var handleGlobalBlurEvent = function (evnt) {
if (reactData.visiblePanel) {
reactData.isActivated = false;
hidePanel();
pulldownMethods.dispatchEvent('hide-panel', {}, evnt);
}
};
pulldownMethods = {
dispatchEvent: function (type, params, evnt) {
emit(type, Object.assign({
$pulldown: $xepulldown,
$event: evnt
}, params));
},
isPanelVisible: isPanelVisible,
togglePanel: togglePanel,
showPanel: showPanel,
hidePanel: hidePanel
};
Object.assign($xepulldown, pulldownMethods);
(0, _vue.watch)(function () {
return props.modelValue;
}, function (value) {
if (value) {
showPanel();
} else {
hidePanel();
}
});
(0, _vue.nextTick)(function () {
_event.GlobalEvent.on($xepulldown, 'mousewheel', handleGlobalMousewheelEvent);
_event.GlobalEvent.on($xepulldown, 'mousedown', handleGlobalMousedownEvent);
_event.GlobalEvent.on($xepulldown, 'blur', handleGlobalBlurEvent);
});
(0, _vue.onUnmounted)(function () {
_event.GlobalEvent.off($xepulldown, 'mousewheel');
_event.GlobalEvent.off($xepulldown, 'mousedown');
_event.GlobalEvent.off($xepulldown, 'blur');
});
var renderVN = function () {
var _a, _b;
var className = props.className,
popupClassName = props.popupClassName,
destroyOnClose = props.destroyOnClose,
transfer = props.transfer,
disabled = props.disabled;
var inited = reactData.inited,
isActivated = reactData.isActivated,
animatVisible = reactData.animatVisible,
visiblePanel = reactData.visiblePanel,
panelStyle = reactData.panelStyle,
panelPlacement = reactData.panelPlacement;
var vSize = computeSize.value;
var defaultSlot = slots.default;
var headerSlot = slots.header;
var footerSlot = slots.footer;
var dropdownSlot = slots.dropdown;
return (0, _vue.h)('div', {
ref: refElem,
class: ['vxe-pulldown', className ? _xeUtils.default.isFunction(className) ? className({
$pulldown: $xepulldown
}) : className : '', (_a = {}, _a["size--".concat(vSize)] = vSize, _a['is--visible'] = visiblePanel, _a['is--disabled'] = disabled, _a['is--active'] = isActivated, _a)]
}, [(0, _vue.h)('div', {
ref: refPulldowContent,
class: 'vxe-pulldown--content'
}, defaultSlot ? defaultSlot({
$pulldown: $xepulldown
}) : []), (0, _vue.h)(_vue.Teleport, {
to: 'body',
disabled: transfer ? !inited : true
}, [(0, _vue.h)('div', {
ref: refPulldowPnanel,
class: ['vxe-table--ignore-clear vxe-pulldown--panel', popupClassName ? _xeUtils.default.isFunction(popupClassName) ? popupClassName({
$pulldown: $xepulldown
}) : popupClassName : '', (_b = {}, _b["size--".concat(vSize)] = vSize, _b['is--transfer'] = transfer, _b['animat--leave'] = animatVisible, _b['animat--enter'] = visiblePanel, _b)],
placement: panelPlacement,
style: panelStyle
}, dropdownSlot ? [(0, _vue.h)('div', {
class: 'vxe-pulldown--panel-wrapper'
}, !inited || destroyOnClose && !visiblePanel && !animatVisible ? [] : [headerSlot ? (0, _vue.h)('div', {
class: 'vxe-pulldown--panel-header'
}, headerSlot({
$pulldown: $xepulldown
})) : (0, _vue.createCommentVNode)(), (0, _vue.h)('div', {
class: 'vxe-pulldown--panel-body'
}, dropdownSlot({
$pulldown: $xepulldown
})), footerSlot ? (0, _vue.h)('div', {
class: 'vxe-pulldown--panel-footer'
}, footerSlot({
$pulldown: $xepulldown
})) : (0, _vue.createCommentVNode)()])] : [])])]);
};
$xepulldown.renderVN = renderVN;
return $xepulldown;
},
render: function () {
return this.renderVN();
}
});
exports.default = _default;