@arco-vue-pro-components/pro-components
Version:
基于@arco-design/web-vue组件的高级组件,包括pro-table
653 lines (652 loc) • 17.7 kB
JavaScript
;
var vue = require("vue");
var webVue = require("@arco-design/web-vue");
var useFilterSorter = require("./hooks/useFilterSorter.js");
var formSearch = require("./form/form-search.js");
var useFetchData = require("./form/use-fetch-data.js");
var index$1 = require("./tool-bar/index.js");
var index$2 = require("./alert/index.js");
var index = require("./utils/index.js");
var useRowSelection = require("./hooks/useRowSelection.js");
var lightFormSearch = require("./form/light-form-search.js");
var index$3 = require("../_utils/index.js");
var is = require("../_utils/is.js");
var context$1 = require("./form/context.js");
var usePureProp = require("../_hooks/use-pure-prop.js");
var context = require("../_utils/context.js");
var useState = require("../_hooks/use-state.js");
webVue.Table.inheritAttrs = false;
var _ProTable = vue.defineComponent({
name: "ProTable",
inheritAttrs: false,
props: {
columns: {
type: Array,
default: () => []
},
rowKey: {
type: String,
default: "id"
},
params: Object,
request: {
type: Function
},
defaultData: Array,
beforeSearchSubmit: {
type: Function,
default: (searchParams) => searchParams
},
search: {
type: [Boolean, Object],
default: true
},
type: {
type: String,
default: "table"
},
toolBarRender: {
type: [Boolean, Function],
default: void 0
},
optionsRender: {
type: [Boolean, Function],
default: false
},
options: {
type: [Object, Boolean],
default: false
},
headerTitle: {
type: [String, Boolean, Object, Function],
default: "\u5217\u8868\u6570\u636E"
},
defaultFormData: {
type: Object
},
searchType: {
type: String,
default: "query"
},
lightSearchConfig: {
type: Object
},
formRef: {
type: Function
},
actionRef: {
type: Function
},
columnEmptyText: {
type: [String, Boolean],
default: "-"
},
selected: {
type: Array
},
defaultSelected: {
type: Array
},
loading: {
type: Boolean,
default: void 0
},
data: {
type: Array,
default: () => []
},
bordered: {
type: [Boolean, Object],
default: true
},
hoverable: {
type: Boolean,
default: true
},
stripe: {
type: Boolean,
default: false
},
tableLayoutFixed: {
type: Boolean,
default: false
},
rowSelection: {
type: Object
},
expandable: {
type: Object
},
scroll: {
type: Object
},
pagination: {
type: [Boolean, Object],
default: true
},
pagePosition: {
type: String,
default: "br"
},
indentSize: {
type: Number,
default: 16
},
showHeader: {
type: Boolean,
default: true
},
virtualListProps: {
type: Object
},
spanMethod: {
type: Function
},
spanAll: {
type: Boolean,
default: false
},
components: {
type: Object
},
loadMore: {
type: Function
},
filterIconAlignLeft: {
type: Boolean,
default: false
},
hideExpandButtonOnEmpty: {
type: Boolean,
default: false
},
rowClass: {
type: [String, Array, Object, Function]
},
draggable: {
type: Object
},
rowNumber: {
type: [Boolean, Object]
},
columnResizable: {
type: Boolean
},
summary: {
type: [Boolean, Function]
},
summaryText: {
type: String,
default: "Summary"
},
summarySpanMethod: {
type: Function
},
selectedKeys: {
type: Array
},
defaultSelectedKeys: {
type: Array
},
expandedKeys: {
type: Array
},
defaultExpandedKeys: {
type: Array
},
defaultExpandAllRows: {
type: Boolean,
default: false
},
stickyHeader: {
type: [Boolean, Number],
default: false
},
scrollbar: {
type: [Object, Boolean],
default: true
},
size: {
type: String,
default: () => {
var _a, _b;
return (_b = (_a = vue.inject(context.configProviderInjectionKey, void 0)) == null ? void 0 : _a.size) != null ? _b : "large";
}
},
onChange: {
type: Function
},
onSubmit: {
type: Function
},
onReset: {
type: Function
},
onLoad: {
type: Function
},
onPageChange: {
type: Function
},
onPageSizeChange: {
type: Function
},
onExpand: {
type: Function
},
onExpandedChange: {
type: Function
},
onSelect: {
type: Function
},
onSelectAll: {
type: Function
},
onSelectionChange: {
type: Function
},
onSorterChange: {
type: Function
},
onFilterChange: {
type: Function
},
onCellClick: {
type: Function
},
onRowClick: {
type: Function
},
onHeaderClick: {
type: Function
},
onColumnResize: {
type: Function
},
columnsState: {
type: Object
},
alertRender: {
type: [Function, Boolean],
default: void 0
}
},
setup(props, {
attrs,
emit,
slots
}) {
const {
rowSelection,
selectedKeys,
selected,
defaultSelectedKeys,
defaultSelected,
pagination: propsPagination
} = vue.toRefs(props);
const tableSize = usePureProp.usePureProp(props, "size");
const columnsState = vue.toRef(props, "columnsState");
const columnsMap = vue.ref({});
const setColumnsMap = (data) => {
columnsMap.value = data;
};
initStorageColumnsMap();
const setTableSize = (size) => {
tableSize.value = size;
};
const prefixCls = index$3.getPrefixCls("pro-table");
const tableRef = vue.ref();
const formRef = vue.ref();
const setFormRef = (ref) => {
formRef.value = ref;
if (typeof props.formRef === "function") {
props.formRef(ref);
}
};
const {
selectedRowKeys,
selectedRows
} = useRowSelection.useRowSelection({
selectedKeys,
defaultSelectedKeys,
selected,
defaultSelected,
rowSelection
});
const actionRef = vue.ref();
const formSearch$1 = vue.ref({});
const renderIndex = (data) => {
if (slots.index) {
return slots.index(data);
}
let text;
let hasPage = false;
if (pagination.value && pagination.value.current && pagination.value.pageSize) {
hasPage = true;
text = data.rowIndex + 1 + (pagination.value.current - 1) * pagination.value.pageSize;
} else {
text = data.rowIndex + 1;
}
if (data.column.valueType === "indexBorder") {
return vue.createVNode("div", {
"class": [`${prefixCls}-column-indexBorder`, {
[`${prefixCls}-column-indexBorder--top-three`]: hasPage ? pagination.value && pagination.value.current === 1 && data.rowIndex < 3 : data.rowIndex < 3
}]
}, [text]);
}
return text;
};
const [fullscreen, setFullscreen] = useState(false);
const rootRef = vue.ref();
const popupContainer = vue.ref();
const setPopupContainer = (container) => {
popupContainer.value = container;
};
const tableColumns = vue.computed(() => {
return index.genProColumnToColumn({
columns: props.columns,
type: props.type,
columnEmptyText: props.columnEmptyText,
action: actionRef,
slots: {
...slots,
index: renderIndex
}
});
});
const {
_filters,
_sorter,
_sorters
} = useFilterSorter.useFilterSorter({
columns: tableColumns
});
const columns = vue.computed(() => {
if (Object.keys(columnsMap.value).length === 0) {
return tableColumns.value;
}
return index.loopFilter(tableColumns.value, void 0, columnsMap);
});
const fetchData = vue.computed(() => {
if (!props.request) {
return void 0;
}
return async (pageParams) => {
var _a;
const actionParams = {
...pageParams || {},
...formSearch$1.value,
...props.params
};
delete actionParams._timestamp;
const response = await ((_a = props.request) == null ? void 0 : _a.call(props, actionParams, _sorters.value, _filters.value));
return response;
};
});
const fetchPagination = vue.computed(() => typeof propsPagination.value === "object" ? propsPagination.value : {
defaultCurrent: 1,
defaultPageSize: 20,
pageSize: 20,
current: 1
});
const options = vue.reactive({
pageInfo: fetchPagination.value,
effects: [props.params, formSearch$1, _sorter, _filters],
getPopupContainer: () => popupContainer.value
});
const action = useFetchData(fetchData.value, props, emit, options);
const dataSource = vue.computed(() => {
return props.request ? action.data.value : props.data || [];
});
const noRowSelection = vue.computed(() => !rowSelection.value);
const dataSourceMap = vue.computed(() => {
return noRowSelection.value ? {} : index.flattenChildren(dataSource.value, props.rowKey);
});
const selectedRowsMap = vue.computed(() => {
return noRowSelection.value ? {} : index.flattenChildren(selectedRows.value, props.rowKey);
});
function initStorageColumnsMap() {
const {
persistenceType,
persistenceKey
} = columnsState.value || {};
if (persistenceKey && persistenceType && typeof window !== "undefined") {
const storage = window[persistenceType];
try {
const storageValue = storage == null ? void 0 : storage.getItem(persistenceKey);
if (storageValue) {
setColumnsMap(JSON.parse(storageValue));
} else {
setColumnsMap({});
}
} catch (error) {
console.warn(error);
}
}
}
vue.watch([columnsState], () => {
initStorageColumnsMap();
});
vue.watch([columnsState, columnsMap], ([columnsState2, columnsMap2]) => {
if (!(columnsState2 == null ? void 0 : columnsState2.persistenceKey) || !(columnsState2 == null ? void 0 : columnsState2.persistenceType)) {
return;
}
if (typeof window === "undefined")
return;
const {
persistenceType,
persistenceKey
} = columnsState2;
const storage = window[persistenceType];
try {
storage == null ? void 0 : storage.setItem(persistenceKey, JSON.stringify(columnsMap2));
} catch (error) {
console.warn(error);
storage == null ? void 0 : storage.removeItem(persistenceKey);
}
}, {
deep: true
});
vue.watch([selectedRowKeys, dataSourceMap, noRowSelection, action.loading], ([selectedRowKeys2, dataSourceMap2, noRowSelection2, loading]) => {
if (loading || noRowSelection2) {
return;
}
if (is.isArray(selectedRowKeys2) && selectedRowKeys2.length) {
const rows = selectedRowKeys2.map((item) => {
return dataSourceMap2[item] || selectedRowsMap.value[item];
});
selectedRows.value = rows;
return;
} else {
selectedRows.value = [];
}
}, {
immediate: true
});
const onCleanSelected = () => {
selectedRowKeys.value = [];
selectedRows.value = [];
emit("update:selectedKeys", []);
};
const getSelected = () => {
return {
selectedKeys: selectedRowKeys.value,
selectedRows: selectedRows.value
};
};
index.useActionType(actionRef, action, {
fullScreen: () => {
if (!rootRef.value || !document.fullscreenEnabled) {
return;
}
if (document.fullscreenElement) {
document.exitFullscreen();
setFullscreen(false);
setPopupContainer(null);
} else {
rootRef.value.requestFullscreen();
setFullscreen(true);
setPopupContainer(rootRef.value);
}
},
getSelected,
onCleanSelected: () => {
onCleanSelected();
},
resetAll: () => {
var _a;
onCleanSelected();
action.setPageInfo({
current: 1
});
_filters.value = {};
_sorters.value = {};
_sorter.value = void 0;
(_a = formRef == null ? void 0 : formRef.value) == null ? void 0 : _a.reset();
formSearch$1.value = {};
}
});
vue.provide(context$1.proTableInjectionKey, vue.reactive({
tableSize,
setTableSize,
columns: tableColumns,
action: actionRef,
selectedRowKeys,
selectedRows,
fullscreen,
popupContainer,
setPopupContainer,
columnsMap,
setColumnsMap
}));
vue.watchEffect(() => {
if (typeof props.actionRef === "function" && actionRef.value) {
props.actionRef(actionRef.value);
}
});
const pagination = vue.computed(() => {
return props.pagination !== false && index.mergePagination(props.pagination, action.pageInfo, action.setPageInfo, emit);
});
const handleChange = (data, extra, currentData) => {
var _a, _b, _c;
_sorter.value = extra.sorter;
if ((_a = extra.sorter) == null ? void 0 : _a.field) {
_sorters.value = {
[(_b = extra.sorter) == null ? void 0 : _b.field]: (_c = extra.sorter) == null ? void 0 : _c.direction
};
} else {
_sorters.value = {};
}
_filters.value = extra.filters || {};
emit("change", data, extra, currentData);
};
const onSubmit = (formData2, firstLoad = false) => {
var _a;
formSearch$1.value = props.beforeSearchSubmit({
...formData2,
_timestamp: Date.now()
});
if (!firstLoad) {
(_a = action.setPageInfo) == null ? void 0 : _a.call(action, {
current: 1
});
}
emit("submit", formData2);
};
const onReset = (formData2 = {}) => {
var _a;
formSearch$1.value = props.beforeSearchSubmit({
...formData2,
_timestamp: Date.now()
});
(_a = action.setPageInfo) == null ? void 0 : _a.call(action, {
current: 1
});
emit("reset");
};
const formData = {
onSubmit: (values) => {
onSubmit({
...formSearch$1.value,
...values
});
},
onReset
};
const render = () => {
return vue.createVNode("div", {
"ref": rootRef,
"class": `${prefixCls}`
}, [vue.createVNode(webVue.Card, {
"bordered": false
}, {
default: () => {
var _a, _b;
return [(_a = slots["form-search"]) == null ? void 0 : _a.call(slots, formData), !slots["form-search"] && props.search && props.searchType === "light" && vue.createVNode(lightFormSearch, {
"columns": props.columns,
"onSubmit": (values, firstLoad = false) => {
onSubmit({
...formSearch$1.value,
...values
}, firstLoad);
},
"onReset": onReset,
"onSearch": (value) => {
formSearch$1.value = {
...formSearch$1.value,
...value
};
},
"type": props.type,
"formSearch": formSearch$1.value,
"formRef": setFormRef,
"search": props.lightSearchConfig,
"defaultFormData": props.defaultFormData
}, slots), !slots["form-search"] && (props.search && props.searchType === "query" || props.type === "form") && vue.createVNode(formSearch["default"], {
"columns": props.columns,
"onSubmit": onSubmit,
"onReset": onReset,
"type": props.type,
"search": props.search,
"formRef": setFormRef,
"submitButtonLoading": props.loading || action.loading.value,
"defaultFormData": props.defaultFormData
}, slots), props.type !== "form" && vue.createVNode("div", null, [props.toolBarRender !== false && (props.headerTitle || props.toolBarRender) && vue.createVNode(index$1, {
"headerTitle": props.headerTitle,
"toolBarRender": props.toolBarRender,
"optionsRender": props.optionsRender,
"options": props.options
}, slots), !noRowSelection.value ? vue.createVNode(index$2, {
"alertRender": props.alertRender,
"alwaysShowAlert": (_b = rowSelection.value) == null ? void 0 : _b.alwaysShowAlert
}, slots) : null, vue.createVNode(webVue.Table, vue.mergeProps({
"ref": tableRef
}, props, attrs, {
"size": tableSize.value,
"columns": columns.value,
"loading": props.loading || action.loading.value,
"data": dataSource.value,
"onChange": handleChange,
"pagination": pagination.value,
"selectedKeys": selectedRowKeys.value,
"onUpdate:selectedKeys": ($event) => selectedRowKeys.value = $event
}), {
...slots,
index: renderIndex
})])];
}
})]);
};
return {
render,
selectedRowKeys,
selectedRows,
getSelected
};
},
render() {
return this.render();
}
});
module.exports = _ProTable;