UNPKG

vxe-table-demonic

Version:

一个基于 vue 的 PC 端表单/表格组件,支持增删改查、虚拟列表、虚拟树、懒加载、快捷菜单、数据校验、树形结构、打印导出、表单渲染、数据分页、弹窗、自定义模板、渲染器、JSON 配置式...

352 lines (351 loc) 14.4 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; import { defineComponent, h, ref, nextTick, onBeforeUnmount, onMounted, reactive, watch } from 'vue'; import XEUtils from 'xe-utils'; import GlobalConfig from '../../v-x-e-table/src/conf'; import { useSize } from '../../hooks/size'; import { getLastZIndex, nextZIndex, formatText } from '../../tools/utils'; import { getAbsolutePos, getDomNode } from '../../tools/dom'; import { getSlotVNs } from '../../tools/vn'; export default defineComponent({ name: 'VxeTooltip', props: { modelValue: Boolean, size: { type: String, default: function () { return GlobalConfig.tooltip.size || GlobalConfig.size; } }, trigger: { type: String, default: function () { return GlobalConfig.tooltip.trigger; } }, theme: { type: String, default: function () { return GlobalConfig.tooltip.theme; } }, content: { type: [String, Number], default: null }, useHTML: Boolean, zIndex: [String, Number], popupClassName: [String, Function], isArrow: { type: Boolean, default: true }, enterable: Boolean, enterDelay: { type: Number, default: function () { return GlobalConfig.tooltip.enterDelay; } }, leaveDelay: { type: Number, default: function () { return GlobalConfig.tooltip.leaveDelay; } } }, emits: [ 'update:modelValue' ], setup: function (props, context) { var slots = context.slots, emit = context.emit; var xID = XEUtils.uniqueId(); var computeSize = useSize(props); var reactData = reactive({ target: null, isUpdate: false, visible: false, tipContent: '', tipActive: false, tipTarget: null, tipZindex: 0, tipStore: { style: {}, placement: '', arrowStyle: {} } }); var refElem = ref(); var refMaps = { refElem: refElem }; var $xetooltip = { xID: xID, props: props, context: context, reactData: reactData, getRefMaps: function () { return refMaps; } }; var tooltipMethods = {}; var updateTipStyle = function () { var tipTarget = reactData.tipTarget, tipStore = reactData.tipStore; if (tipTarget) { var _a = getDomNode(), scrollTop = _a.scrollTop, scrollLeft = _a.scrollLeft, visibleWidth = _a.visibleWidth; var _b = getAbsolutePos(tipTarget), top_1 = _b.top, left = _b.left; var el = refElem.value; var marginSize = 6; var offsetHeight = el.offsetHeight; var offsetWidth = el.offsetWidth; var tipLeft = left; var tipTop = top_1 - offsetHeight - marginSize; tipLeft = Math.max(marginSize, left + Math.floor((tipTarget.offsetWidth - offsetWidth) / 2)); if (tipLeft + offsetWidth + marginSize > scrollLeft + visibleWidth) { tipLeft = scrollLeft + visibleWidth - offsetWidth - marginSize; } if (top_1 - offsetHeight < scrollTop + marginSize) { tipStore.placement = 'bottom'; tipTop = top_1 + tipTarget.offsetHeight + marginSize; } tipStore.style.top = "".concat(tipTop, "px"); tipStore.style.left = "".concat(tipLeft, "px"); tipStore.arrowStyle.left = "".concat(left - tipLeft + tipTarget.offsetWidth / 2, "px"); } }; var updateValue = function (value) { if (value !== reactData.visible) { reactData.visible = value; reactData.isUpdate = true; emit('update:modelValue', value); } }; var updateZindex = function () { if (reactData.tipZindex < getLastZIndex()) { reactData.tipZindex = nextZIndex(); } }; var clickEvent = function () { if (reactData.visible) { tooltipMethods.close(); } else { tooltipMethods.open(); } }; var targetMouseenterEvent = function () { tooltipMethods.open(); }; var targetMouseleaveEvent = function () { var trigger = props.trigger, enterable = props.enterable, leaveDelay = props.leaveDelay; reactData.tipActive = false; if (enterable && trigger === 'hover') { setTimeout(function () { if (!reactData.tipActive) { tooltipMethods.close(); } }, leaveDelay); } else { tooltipMethods.close(); } }; var wrapperMouseenterEvent = function () { reactData.tipActive = true; }; var wrapperMouseleaveEvent = function () { var trigger = props.trigger, enterable = props.enterable, leaveDelay = props.leaveDelay; reactData.tipActive = false; if (enterable && trigger === 'hover') { setTimeout(function () { if (!reactData.tipActive) { tooltipMethods.close(); } }, leaveDelay); } }; var showTip = function () { var tipStore = reactData.tipStore; var el = refElem.value; if (el) { var parentNode = el.parentNode; if (!parentNode) { document.body.appendChild(el); } } updateValue(true); updateZindex(); tipStore.placement = 'top'; tipStore.style = { width: 'auto', left: 0, top: 0, zIndex: props.zIndex || reactData.tipZindex }; tipStore.arrowStyle = { left: '50%' }; return tooltipMethods.updatePlacement(); }; var showDelayTip = XEUtils.debounce(function () { if (reactData.tipActive) { showTip(); } }, props.enterDelay, { leading: false, trailing: true }); tooltipMethods = { dispatchEvent: function (type, params, evnt) { emit(type, Object.assign({ $tooltip: $xetooltip, $event: evnt }, params)); }, open: function (target, content) { return tooltipMethods.toVisible(target || reactData.target, content); }, close: function () { reactData.tipTarget = null; reactData.tipActive = false; Object.assign(reactData.tipStore, { style: {}, placement: '', arrowStyle: null }); updateValue(false); return nextTick(); }, toVisible: function (target, content) { if (target) { var trigger = props.trigger, enterDelay = props.enterDelay; reactData.tipActive = true; reactData.tipTarget = target; if (content) { reactData.tipContent = content; } if (enterDelay && trigger === 'hover') { showDelayTip(); } else { return showTip(); } } return nextTick(); }, updatePlacement: function () { return nextTick().then(function () { var tipTarget = reactData.tipTarget; var el = refElem.value; if (tipTarget && el) { updateTipStyle(); return nextTick().then(updateTipStyle); } }); }, isActived: function () { return reactData.tipActive; }, setActived: function (actived) { reactData.tipActive = !!actived; } }; Object.assign($xetooltip, tooltipMethods); watch(function () { return props.content; }, function () { reactData.tipContent = props.content; }); watch(function () { return props.modelValue; }, function () { if (!reactData.isUpdate) { if (props.modelValue) { tooltipMethods.open(); } else { tooltipMethods.close(); } } reactData.isUpdate = false; }); onMounted(function () { nextTick(function () { var trigger = props.trigger, content = props.content, modelValue = props.modelValue; var wrapperElem = refElem.value; if (wrapperElem) { var parentNode_1 = wrapperElem.parentNode; if (parentNode_1) { reactData.tipContent = content; reactData.tipZindex = nextZIndex(); XEUtils.arrayEach(wrapperElem.children, function (elem, index) { if (index > 1) { parentNode_1.insertBefore(elem, wrapperElem); if (!reactData.target) { reactData.target = elem; } } }); parentNode_1.removeChild(wrapperElem); var target = reactData.target; if (target) { if (trigger === 'hover') { target.onmouseenter = targetMouseenterEvent; target.onmouseleave = targetMouseleaveEvent; } else if (trigger === 'click') { target.onclick = clickEvent; } } if (modelValue) { tooltipMethods.open(); } } } }); }); onBeforeUnmount(function () { var trigger = props.trigger; var target = reactData.target; var wrapperElem = refElem.value; if (wrapperElem) { var parentNode = wrapperElem.parentNode; if (parentNode) { parentNode.removeChild(wrapperElem); } } if (target) { if (trigger === 'hover') { target.onmouseenter = null; target.onmouseleave = null; } else if (trigger === 'click') { target.onclick = null; } } }); var renderContent = function () { var useHTML = props.useHTML; var tipContent = reactData.tipContent; var contentSlot = slots.content; if (contentSlot) { return h('div', { key: 1, class: 'vxe-table--tooltip-content' }, getSlotVNs(contentSlot({}))); } if (useHTML) { return h('div', { key: 2, class: 'vxe-table--tooltip-content', innerHTML: tipContent }); } return h('div', { key: 3, class: 'vxe-table--tooltip-content' }, formatText(tipContent)); }; var renderVN = function () { var _a; var popupClassName = props.popupClassName, theme = props.theme, isArrow = props.isArrow, enterable = props.enterable; var tipActive = reactData.tipActive, visible = reactData.visible, tipStore = reactData.tipStore; var defaultSlot = slots.default; var vSize = computeSize.value; var ons; if (enterable) { ons = { onMouseenter: wrapperMouseenterEvent, onMouseleave: wrapperMouseleaveEvent }; } return h('div', __assign({ ref: refElem, class: ['vxe-table--tooltip-wrapper', "theme--".concat(theme), popupClassName ? (XEUtils.isFunction(popupClassName) ? popupClassName({ $tooltip: $xetooltip }) : popupClassName) : '', (_a = {}, _a["size--".concat(vSize)] = vSize, _a["placement--".concat(tipStore.placement)] = tipStore.placement, _a['is--enterable'] = enterable, _a['is--visible'] = visible, _a['is--arrow'] = isArrow, _a['is--active'] = tipActive, _a)], style: tipStore.style }, ons), __spreadArray([ renderContent(), h('div', { class: 'vxe-table--tooltip-arrow', style: tipStore.arrowStyle }) ], (defaultSlot ? getSlotVNs(defaultSlot({})) : []), true)); }; $xetooltip.renderVN = renderVN; return $xetooltip; }, render: function () { return this.renderVN(); } });