vxe-table
Version:
一个基于 vue 的 PC 端表格组件,支持增删改查、虚拟滚动、懒加载、快捷菜单、数据校验、树形结构、打印导出、表单渲染、数据分页、虚拟列表、模态窗口、自定义模板、渲染器、贼灵活的配置项、扩展接口等...
845 lines (741 loc) • 26.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _conf = _interopRequireDefault(require("../../v-x-e-table/src/conf"));
var _size = _interopRequireDefault(require("../../mixins/size"));
var _vXETable = _interopRequireDefault(require("../../v-x-e-table"));
var _tools = require("../../tools");
var _util = require("./util");
var _dom = require("../../tools/src/dom");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Rule = /*#__PURE__*/function () {
function Rule(rule) {
_classCallCheck(this, Rule);
Object.assign(this, {
$options: rule,
required: rule.required,
min: rule.min,
max: rule.min,
type: rule.type,
pattern: rule.pattern,
validator: rule.validator,
trigger: rule.trigger,
maxWidth: rule.maxWidth
});
}
_createClass(Rule, [{
key: "message",
get: function get() {
return _tools.UtilTools.getFuncText(this.$options.message);
}
}]);
return Rule;
}();
function getResetValue(value, resetValue) {
if (_xeUtils.default.isArray(value)) {
resetValue = [];
}
return resetValue;
}
function callSlot(_vm, slotFunc, params, h) {
if (slotFunc) {
var $scopedSlots = _vm.$scopedSlots;
if (_xeUtils.default.isString(slotFunc)) {
slotFunc = $scopedSlots[slotFunc] || null;
}
if (_xeUtils.default.isFunction(slotFunc)) {
return slotFunc.call(_vm, params, h);
}
}
return [];
}
function renderPrefixIcon(h, titlePrefix) {
return h('span', {
class: 'vxe-form--item-title-prefix'
}, [h('i', {
class: titlePrefix.icon || _conf.default.icon.FORM_PREFIX
})]);
}
function renderSuffixIcon(h, titleSuffix) {
return h('span', {
class: 'vxe-form--item-title-suffix'
}, [h('i', {
class: titleSuffix.icon || _conf.default.icon.FORM_SUFFIX
})]);
}
function renderTitle(h, _vm, item) {
var data = _vm.data;
var slots = item.slots,
field = item.field,
itemRender = item.itemRender,
titlePrefix = item.titlePrefix,
titleSuffix = item.titleSuffix;
var compConf = (0, _tools.isEnableConf)(itemRender) ? _vXETable.default.renderer.get(itemRender.name) : null;
var params = {
data: data,
property: field,
item: item,
$form: _vm
};
var tss = [];
if (titlePrefix) {
tss.push(titlePrefix.message ? h('vxe-tooltip', {
props: {
content: _tools.UtilTools.getFuncText(titlePrefix.message),
enterable: titlePrefix.enterable,
theme: titlePrefix.theme
}
}, [renderPrefixIcon(h, titlePrefix)]) : renderPrefixIcon(h, titlePrefix));
}
tss.push(h('span', {
class: 'vxe-form--item-title-label'
}, compConf && compConf.renderItemTitle ? compConf.renderItemTitle(itemRender, params) : slots && slots.title ? callSlot(_vm, slots.title, params, h) : _tools.UtilTools.getFuncText(item.title)));
if (titleSuffix) {
tss.push(titleSuffix.message ? h('vxe-tooltip', {
props: {
content: _tools.UtilTools.getFuncText(titleSuffix.message),
enterable: titleSuffix.enterable,
theme: titleSuffix.theme
}
}, [renderSuffixIcon(h, titleSuffix)]) : renderSuffixIcon(h, titleSuffix));
}
return tss;
}
function renderItems(h, _vm, itemList) {
var _e = _vm._e,
rules = _vm.rules,
data = _vm.data,
collapseAll = _vm.collapseAll,
validOpts = _vm.validOpts,
allTitleOverflow = _vm.titleOverflow;
return itemList.map(function (item, index) {
var slots = item.slots,
title = item.title,
folding = item.folding,
visible = item.visible,
visibleMethod = item.visibleMethod,
field = item.field,
collapseNode = item.collapseNode,
itemRender = item.itemRender,
showError = item.showError,
errRule = item.errRule,
className = item.className,
titleOverflow = item.titleOverflow,
children = item.children;
var compConf = (0, _tools.isEnableConf)(itemRender) ? _vXETable.default.renderer.get(itemRender.name) : null;
var span = item.span || _vm.span;
var align = item.align || _vm.align;
var titleAlign = item.titleAlign || _vm.titleAlign;
var titleWidth = item.titleWidth || _vm.titleWidth;
var itemVisibleMethod = visibleMethod;
var itemOverflow = _xeUtils.default.isUndefined(titleOverflow) || _xeUtils.default.isNull(titleOverflow) ? allTitleOverflow : titleOverflow;
var showEllipsis = itemOverflow === 'ellipsis';
var showTitle = itemOverflow === 'title';
var showTooltip = itemOverflow === true || itemOverflow === 'tooltip';
var hasEllipsis = showTitle || showTooltip || showEllipsis;
var params = {
data: data,
property: field,
item: item,
$form: _vm
};
var isRequired;
if (visible === false) {
return _e();
} // 如果为项集合
var isGather = children && children.length > 0;
if (isGather) {
var childVNs = renderItems(h, _vm, item.children);
return childVNs.length ? h('div', {
class: ['vxe-form--gather vxe-row', item.id, span ? "vxe-col--".concat(span, " is--span") : '', className ? _xeUtils.default.isFunction(className) ? className(params) : className : '']
}, childVNs) : _e();
}
if (!itemVisibleMethod && compConf && compConf.itemVisibleMethod) {
itemVisibleMethod = compConf.itemVisibleMethod;
}
if (rules) {
var itemRules = rules[field];
if (itemRules) {
isRequired = itemRules.some(function (rule) {
return rule.required;
});
}
}
var contentVNs = [];
if (slots && slots.default) {
contentVNs = callSlot(_vm, slots.default, params, h);
} else if (compConf && compConf.renderItemContent) {
contentVNs = compConf.renderItemContent.call(_vm, h, itemRender, params);
} else if (compConf && compConf.renderItem) {
contentVNs = compConf.renderItem.call(_vm, h, itemRender, params);
} else if (field) {
contentVNs = ["".concat(_xeUtils.default.get(data, field))];
}
var ons = showTooltip ? {
mouseenter: function mouseenter(evnt) {
_vm.triggerHeaderHelpEvent(evnt, params);
},
mouseleave: _vm.handleTargetLeaveEvent
} : {};
return h('div', {
class: ['vxe-form--item', item.id, span ? "vxe-col--".concat(span, " is--span") : null, className ? _xeUtils.default.isFunction(className) ? className(params) : className : '', {
'is--title': title,
'is--required': isRequired,
'is--hidden': folding && collapseAll,
'is--active': !itemVisibleMethod || itemVisibleMethod(params),
'is--error': showError
}],
key: index
}, [h('div', {
class: 'vxe-form--item-inner'
}, [title || slots && slots.title ? h('div', {
class: ['vxe-form--item-title', titleAlign ? "align--".concat(titleAlign) : null, {
'is--ellipsis': hasEllipsis
}],
style: titleWidth ? {
width: isNaN(titleWidth) ? titleWidth : "".concat(titleWidth, "px")
} : null,
attrs: {
title: showTitle ? _tools.UtilTools.getFuncText(title) : null
},
on: ons
}, renderTitle(h, _vm, item)) : null, h('div', {
class: ['vxe-form--item-content', align ? "align--".concat(align) : null]
}, contentVNs.concat([collapseNode ? h('div', {
class: 'vxe-form--item-trigger-node',
on: {
click: _vm.toggleCollapseEvent
}
}, [h('span', {
class: 'vxe-form--item-trigger-text'
}, collapseAll ? _conf.default.i18n('vxe.form.unfolding') : _conf.default.i18n('vxe.form.folding')), h('i', {
class: ['vxe-form--item-trigger-icon', collapseAll ? _conf.default.icon.FORM_FOLDING : _conf.default.icon.FORM_UNFOLDING]
})]) : null, errRule && validOpts.showMessage ? h('div', {
class: 'vxe-form--item-valid',
style: errRule.maxWidth ? {
width: "".concat(errRule.maxWidth, "px")
} : null
}, errRule.message) : null]))])]);
});
}
var _default2 = {
name: 'VxeForm',
mixins: [_size.default],
props: {
loading: Boolean,
data: Object,
size: {
type: String,
default: function _default() {
return _conf.default.form.size || _conf.default.size;
}
},
span: [String, Number],
align: {
type: String,
default: function _default() {
return _conf.default.form.align;
}
},
titleAlign: {
type: String,
default: function _default() {
return _conf.default.form.titleAlign;
}
},
titleWidth: [String, Number],
titleColon: {
type: Boolean,
default: function _default() {
return _conf.default.form.titleColon;
}
},
titleAsterisk: {
type: Boolean,
default: function _default() {
return _conf.default.form.titleAsterisk;
}
},
titleOverflow: {
type: [Boolean, String],
default: null
},
items: Array,
rules: Object,
preventSubmit: {
type: Boolean,
default: function _default() {
return _conf.default.form.preventSubmit;
}
},
validConfig: Object
},
data: function data() {
return {
collapseAll: true,
staticItems: [],
formItems: [],
tooltipTimeout: null,
tooltipActive: false,
tooltipStore: {
item: null,
visible: false
}
};
},
provide: function provide() {
return {
$xeform: this
};
},
computed: {
validOpts: function validOpts() {
return Object.assign({}, _conf.default.form.validConfig, this.validConfig);
},
tooltipOpts: function tooltipOpts() {
var opts = Object.assign({
leaveDelay: 300
}, _conf.default.form.tooltipConfig, this.tooltipConfig);
if (opts.enterable) {
opts.leaveMethod = this.handleTooltipLeaveMethod;
}
return opts;
}
},
created: function created() {
var _this = this;
this.$nextTick(function () {
var items = _this.items;
if (items) {
_this.loadItem(items);
}
});
},
watch: {
staticItems: function staticItems(value) {
this.formItems = value;
},
items: function items(value) {
this.loadItem(value);
}
},
render: function render(h) {
var _ref;
var _e = this._e,
loading = this.loading,
vSize = this.vSize,
tooltipOpts = this.tooltipOpts,
formItems = this.formItems;
var hasUseTooltip = _vXETable.default._tooltip;
return h('form', {
class: ['vxe-form', (_ref = {}, _defineProperty(_ref, "size--".concat(vSize), vSize), _defineProperty(_ref, 'is--colon', this.titleColon), _defineProperty(_ref, 'is--asterisk', this.titleAsterisk), _defineProperty(_ref, 'is--loading', loading), _ref)],
on: {
submit: this.submitEvent,
reset: this.resetEvent
}
}, [h('div', {
class: 'vxe-form--wrapper vxe-row'
}, renderItems(h, this, formItems)), h('div', {
class: 'vxe-form-slots',
ref: 'hideItem'
}, this.$slots.default), h('div', {
class: ['vxe-loading', {
'is--visible': loading
}]
}, [h('div', {
class: 'vxe-loading--spinner'
})]),
/**
* 工具提示
*/
hasUseTooltip ? h('vxe-tooltip', _objectSpread({
ref: 'tooltip'
}, tooltipOpts)) : _e()]);
},
methods: {
loadItem: function loadItem(list) {
var _this2 = this;
if (process.env.NODE_ENV === 'development') {
var $scopedSlots = this.$scopedSlots;
list.forEach(function (item) {
if (item.slots) {
_xeUtils.default.each(item.slots, function (func) {
if (!_xeUtils.default.isFunction(func)) {
if (!$scopedSlots[func]) {
_tools.UtilTools.error('vxe.error.notSlot', [func]);
}
}
});
}
});
}
this.staticItems = list.map(function (item) {
return (0, _util.createItem)(_this2, item);
});
return this.$nextTick();
},
getItems: function getItems() {
var itemList = [];
_xeUtils.default.eachTree(this.formItems, function (item) {
itemList.push(item);
}, {
children: 'children'
});
return itemList;
},
toggleCollapse: function toggleCollapse() {
this.collapseAll = !this.collapseAll;
return this.$nextTick();
},
toggleCollapseEvent: function toggleCollapseEvent(evnt) {
this.toggleCollapse();
this.$emit('toggle-collapse', {
collapse: !this.collapseAll,
data: this.data,
$form: this,
$event: evnt
}, evnt);
},
submitEvent: function submitEvent(evnt) {
var _this3 = this;
evnt.preventDefault();
if (!this.preventSubmit) {
this.beginValidate().then(function () {
_this3.$emit('submit', {
data: _this3.data,
$form: _this3,
$event: evnt
});
}).catch(function (errMap) {
_this3.$emit('submit-invalid', {
data: _this3.data,
errMap: errMap,
$form: _this3,
$event: evnt
});
});
}
},
reset: function reset() {
var _this4 = this;
var data = this.data;
if (data) {
var itemList = this.getItems();
itemList.forEach(function (item) {
var field = item.field,
resetValue = item.resetValue,
itemRender = item.itemRender;
if ((0, _tools.isEnableConf)(itemRender)) {
var compConf = _vXETable.default.renderer.get(itemRender.name);
if (compConf && compConf.itemResetMethod) {
compConf.itemResetMethod({
data: data,
property: field,
item: item,
$form: _this4
});
} else if (field) {
_xeUtils.default.set(data, field, resetValue === null ? getResetValue(_xeUtils.default.get(data, field), undefined) : resetValue);
}
}
});
}
return this.clearValidate();
},
resetEvent: function resetEvent(evnt) {
evnt.preventDefault();
this.reset();
this.$emit('reset', {
data: this.data,
$form: this,
$event: evnt
});
},
handleTooltipLeaveMethod: function handleTooltipLeaveMethod() {
var _this5 = this;
var tooltipOpts = this.tooltipOpts;
setTimeout(function () {
if (!_this5.tooltipActive) {
_this5.closeTooltip();
}
}, tooltipOpts.leaveDelay);
return false;
},
closeTooltip: function closeTooltip() {
var tooltipStore = this.tooltipStore;
var $tooltip = this.$refs.tooltip;
if (tooltipStore.visible) {
Object.assign(tooltipStore, {
item: null,
visible: false
});
if ($tooltip) {
$tooltip.close();
}
}
return this.$nextTick();
},
triggerHeaderHelpEvent: function triggerHeaderHelpEvent(evnt, params) {
var item = params.item;
var tooltipStore = this.tooltipStore;
var $tooltip = this.$refs.tooltip;
var overflowElem = evnt.currentTarget;
var content = (overflowElem.textContent || '').trim();
var isCellOverflow = overflowElem.scrollWidth > overflowElem.clientWidth;
clearTimeout(this.tooltipTimeout);
this.tooltipActive = true;
this.closeTooltip();
if (content && isCellOverflow) {
Object.assign(tooltipStore, {
item: item,
visible: true
});
if ($tooltip) {
$tooltip.open(overflowElem, content);
}
}
},
handleTargetLeaveEvent: function handleTargetLeaveEvent() {
var _this6 = this;
var tooltipOpts = this.tooltipOpts;
this.tooltipActive = false;
if (tooltipOpts.enterable) {
this.tooltipTimeout = setTimeout(function () {
var $tooltip = _this6.$refs.tooltip;
if ($tooltip && !$tooltip.isHover) {
_this6.closeTooltip();
}
}, tooltipOpts.leaveDelay);
} else {
this.closeTooltip();
}
},
clearValidate: function clearValidate(field) {
var itemList = this.getItems();
if (field) {
var item = itemList.find(function (item) {
return item.field === field;
});
if (item) {
item.showError = false;
}
} else {
itemList.forEach(function (item) {
item.showError = false;
});
}
return this.$nextTick();
},
validate: function validate(callback) {
return this.beginValidate('', callback);
},
beginValidate: function beginValidate(type, callback) {
var _this7 = this;
var data = this.data,
formRules = this.rules,
validOpts = this.validOpts;
var validRest = {};
var validFields = [];
var itemValids = [];
var itemList = this.getItems();
this.clearValidate();
clearTimeout(this.showErrTime);
if (data && formRules) {
itemList.forEach(function (item) {
var field = item.field;
if (field) {
itemValids.push(_this7.validItemRules(type || 'all', field).then(function () {
item.errRule = null;
}).catch(function (_ref2) {
var rule = _ref2.rule,
rules = _ref2.rules;
var rest = {
rule: rule,
rules: rules,
data: data,
property: field,
$form: _this7
};
if (!validRest[field]) {
validRest[field] = [];
}
validRest[field].push(rest);
validFields.push(field);
item.errRule = rule;
return Promise.reject(rest);
}));
}
});
return Promise.all(itemValids).then(function () {
if (callback) {
callback();
}
}).catch(function () {
_this7.showErrTime = setTimeout(function () {
itemList.forEach(function (item) {
if (item.errRule) {
item.showError = true;
}
});
}, 20);
if (callback) {
callback(validRest);
}
if (validOpts.autoPos) {
_this7.$nextTick(function () {
_this7.handleFocus(validFields);
});
}
return Promise.reject(validRest);
});
}
if (callback) {
callback();
}
return Promise.resolve();
},
/**
* 校验数据
* 按表格行、列顺序依次校验(同步或异步)
* 校验规则根据索引顺序依次校验,如果是异步则会等待校验完成才会继续校验下一列
* 如果校验失败则,触发回调或者 Promise<(ErrMap 校验不通过列的信息)>
* 如果是传回调方式这返回一个 (ErrMap 校验不通过列的信息)
*
* rule 配置:
* required=Boolean 是否必填
* min=Number 最小长度
* max=Number 最大长度
* validator=Function({ itemValue, rule, rules, data, property }) 自定义校验,接收一个 Promise
* trigger=change 触发方式
*/
validItemRules: function validItemRules(type, property, val) {
var _this8 = this;
var data = this.data,
formRules = this.rules;
var errorRules = [];
var syncVailds = [];
if (property && formRules) {
var rules = _xeUtils.default.get(formRules, property);
if (rules) {
var itemValue = _xeUtils.default.isUndefined(val) ? _xeUtils.default.get(data, property) : val;
rules.forEach(function (rule) {
if (type === 'all' || !rule.trigger || type === rule.trigger) {
if (_xeUtils.default.isFunction(rule.validator)) {
var customValid = rule.validator({
itemValue: itemValue,
rule: rule,
rules: rules,
data: data,
property: property,
$form: _this8
});
if (customValid) {
if (_xeUtils.default.isError(customValid)) {
errorRules.push(new Rule({
type: 'custom',
trigger: rule.trigger,
message: customValid.message,
rule: new Rule(rule)
}));
} else if (customValid.catch) {
// 如果为异步校验(注:异步校验是并发无序的)
syncVailds.push(customValid.catch(function (e) {
errorRules.push(new Rule({
type: 'custom',
trigger: rule.trigger,
message: e ? e.message : rule.message,
rule: new Rule(rule)
}));
}));
}
}
} else {
var isNumber = rule.type === 'number';
var numVal = isNumber ? _xeUtils.default.toNumber(itemValue) : _xeUtils.default.getSize(itemValue);
if (itemValue === null || itemValue === undefined || itemValue === '') {
if (rule.required) {
errorRules.push(new Rule(rule));
}
} else if (isNumber && isNaN(itemValue) || !isNaN(rule.min) && numVal < parseFloat(rule.min) || !isNaN(rule.max) && numVal > parseFloat(rule.max) || rule.pattern && !(rule.pattern.test ? rule.pattern : new RegExp(rule.pattern)).test(itemValue)) {
errorRules.push(new Rule(rule));
}
}
}
});
}
}
return Promise.all(syncVailds).then(function () {
if (errorRules.length) {
var rest = {
rules: errorRules,
rule: errorRules[0]
};
return Promise.reject(rest);
}
});
},
handleFocus: function handleFocus(fields) {
var $el = this.$el;
var itemList = this.getItems();
fields.some(function (property) {
var item = itemList.find(function (item) {
return item.field === property;
});
if (item && (0, _tools.isEnableConf)(item.itemRender)) {
var itemRender = item.itemRender;
var compConf = _vXETable.default.renderer.get(itemRender.name);
var inputElem; // 如果指定了聚焦 class
if (itemRender.autofocus) {
inputElem = $el.querySelector(".".concat(item.id, " ").concat(itemRender.autofocus));
} // 渲染器的聚焦处理
if (!inputElem && compConf && compConf.autofocus) {
inputElem = $el.querySelector(".".concat(item.id, " ").concat(compConf.autofocus));
}
if (inputElem) {
inputElem.focus(); // 保持一致行为,光标移到末端
if (_dom.browse.msie) {
var textRange = inputElem.createTextRange();
textRange.collapse(false);
textRange.select();
}
return true;
}
}
});
},
/**
* 更新项状态
* 如果组件值 v-model 发生 change 时,调用改函数用于更新某一项编辑状态
* 如果单元格配置了校验规则,则会进行校验
*/
updateStatus: function updateStatus(scope, itemValue) {
var _this9 = this;
var property = scope.property;
if (property) {
this.validItemRules('change', property, itemValue).then(function () {
_this9.clearValidate(property);
}).catch(function (_ref3) {
var rule = _ref3.rule;
var itemList = _this9.getItems();
var item = itemList.find(function (item) {
return item.field === property;
});
if (item) {
item.showError = true;
item.errRule = rule;
}
});
}
}
}
};
exports.default = _default2;