@oiij/naive-ui
Version:
Some Composable Functions And Components for Vue 3
375 lines (373 loc) • 11.9 kB
JavaScript
import { useDataRequest } from "../../composables/useDataRequest.js";
import MageArrowUp_default from "../icons/MageArrowUp.js";
import SearchInput_default from "../search-input/SearchInput.js";
import "../search-input/index.js";
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, guardReactiveProps, mergeProps, normalizeProps, openBlock, reactive, ref, renderSlot, toDisplayString, toRaw, toValue, unref, useTemplateRef, withCtx } from "vue";
import { NButton, NDataTable, NFlex, NPagination } from "naive-ui";
//#region src/components/data-table-plus/DataTablePlus.vue
const _hoisted_1 = { style: {
height: "100%",
display: "flex",
alignItems: "center"
} };
const _hoisted_2 = {
key: 0,
style: { fontSize: "16px" }
};
const _hoisted_3 = { style: {
flex: 1,
position: "relative"
} };
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "DataTablePlus",
props: {
api: { type: Function },
defaultParams: {},
manual: { type: Boolean },
fields: {},
requestOptions: {},
requestPlugins: {},
title: {},
scrollTop: { type: [
Number,
Boolean,
Object
] },
columns: {},
search: { type: [Object, Boolean] },
pagination: { type: [Object, Boolean] },
columnsFilterOptions: { type: Function },
columnsSorterOptions: { type: Function },
dataTableProps: {}
},
emits: [
"before",
"success",
"error",
"finally",
"clickRow",
"contextMenuRow",
"load",
"scroll",
"scrollBottom",
"update:checkedRowKeys",
"update:expandedRowKeys",
"update:filters",
"update:sorter",
"update:page",
"update:pageSize"
],
setup(__props, { expose: __expose, emit: __emit }) {
const emit = __emit;
const columnsReactive = reactive(__props.columns ?? []);
const dataTableRef = useTemplateRef("data-table-ref");
const _fields = {
page: "page",
pageSize: "pageSize",
filter: "filter",
sorter: "sorter",
list: "list",
count: "count",
rowKey: "id",
search: "search",
children: "children",
...__props.fields
};
const searchProps = { ...__props.search && typeof __props.search === "boolean" ? {} : __props.search };
const paginationProps = reactive({
showSizePicker: true,
pageSizes: [
10,
20,
30
],
pageSlot: 5,
prefix: (info) => {
return `共${info.itemCount}条数据`;
},
...__props.pagination && typeof __props.pagination === "boolean" ? {} : __props.pagination
});
const scrollTopProps = { ...typeof __props.scrollTop === "boolean" ? {
top: 180,
buttonProps: void 0
} : typeof __props.scrollTop === "number" ? {
top: __props.scrollTop,
buttonProps: void 0
} : typeof __props.scrollTop === "object" ? {
top: __props.scrollTop.top ?? 180,
buttonProps: __props.scrollTop.buttonProps ?? {}
} : {
top: 180,
buttonProps: void 0
} };
const filtersRef = ref();
const sortersRef = ref();
const _dataCache = [];
const { loading, data, error, params, list, pagination: paginationRef, run, runAsync, refresh, refreshAsync, cancel, mutate, setParams, runParams, runParamsAsync, onBefore, onSuccess, onError, onFinally } = useDataRequest(__props.api, {
defaultParams: {
[_fields.search]: null,
...__props.defaultParams
},
manual: __props.manual,
fields: _fields,
requestOptions: __props.requestOptions,
requestPlugins: __props.requestPlugins
});
onBefore((params$1) => {
emit("before", params$1);
});
onSuccess((data$1, params$1) => {
emit("success", data$1, params$1);
onSuccessEffect(data$1, params$1);
});
onError((err, params$1) => {
emit("error", err, params$1);
});
onFinally((params$1, data$1, err) => {
emit("finally", params$1, data$1, err);
});
const scrollX = computed(() => {
return __props.columns?.reduce((pre, cur) => {
return pre + Number(cur.width ?? 100);
}, 0);
});
function onSuccessEffect(data$1, _params) {
data$1[_fields.list]?.forEach((f) => {
if (!_dataCache.some((s) => s?.[_fields.rowKey] === f?.[_fields.rowKey])) _dataCache.push(f);
});
if (columnsReactive) {
for (const item of columnsReactive) if ("key" in item) {
if (filtersRef.value && item.key in filtersRef.value) {
const filterValues = filtersRef.value[item.key];
if (filterValues && "filter" in item && item.filter) if (item.filterMultiple) if (Array.isArray(filterValues)) item.filterOptionValues = filterValues;
else item.filterOptionValues = [filterValues];
else if (Array.isArray(filterValues)) item.filterOptionValue = filterValues[0];
else item.filterOptionValue = filterValues;
}
if ("sorter" in item) {
if (typeof item.sorter === "boolean") item.sortOrder = false;
}
if (sortersRef.value && item.key in sortersRef.value) {
const sorterValue = sortersRef.value[item.key];
if (sorterValue && "sorter" in item && item.sorter) item.sortOrder = sorterValue.order;
}
}
}
}
const _scrollTop = ref(0);
const vOn = {
onUpdatePage: (page) => {
emit("update:page", page);
if (loading.value) return;
runParams({ [_fields.page]: page });
},
onUpdatePageSize: (pageSize) => {
emit("update:pageSize", pageSize);
if (loading.value) return;
runParams({ [_fields.pageSize]: pageSize });
},
onUpdateFilters: (filters, initiatorColumn) => {
emit("update:filters", filters, initiatorColumn);
filtersRef.value = filters;
runParams({
[_fields.page]: 1,
...__props.columnsFilterOptions ? __props.columnsFilterOptions(filters) : { [_fields.filter]: filters }
});
},
onUpdateSorter: (options) => {
emit("update:sorter", options);
const sorter = {};
if (Array.isArray(options)) for (const item of options) sorter[item.columnKey] = item;
else if (options) sorter[options.columnKey] = options;
sortersRef.value = sorter;
runParams({
[_fields.page]: 1,
...__props.columnsSorterOptions ? __props.columnsSorterOptions(sorter) : { [_fields.sorter]: sorter }
});
},
onLoad: (row) => {
return emit("load", row);
},
onScroll: (ev) => {
if (__props.scrollTop && ev.target && "scrollTop" in ev.target && typeof ev.target.scrollTop === "number") _scrollTop.value = ev.target.scrollTop;
emit("scroll", ev);
},
onUpdateCheckedRowKeys: (keys, _rows, meta) => {
emit("update:checkedRowKeys", keys, keys.map((m) => _dataCache.find((f) => f?.[_fields.rowKey] === m)), {
row: toRaw(meta.row),
action: meta.action
}, toRaw(list.value));
},
onUpdateExpandedRowKeys: (keys) => {
emit("update:expandedRowKeys", keys, toRaw(list.value));
}
};
function rowProps(row, index) {
return {
onClick: (event) => {
emit("clickRow", toRaw(row), index, event, toRaw(list.value));
},
onContextmenu: (event) => {
emit("contextMenuRow", toRaw(row), index, event, toRaw(list.value));
}
};
}
function onSearch(val) {
if (loading.value) return;
runParams({
[_fields.page]: 1,
[_fields.search]: val
});
}
function handleScrollTop() {
dataTableRef.value?.scrollTo({
left: 0,
top: 0,
behavior: "smooth"
});
}
const expose = {
loading,
data,
error,
params,
list,
pagination: paginationRef,
run,
runAsync,
refresh,
refreshAsync,
cancel,
mutate,
setParams,
runParams,
runParamsAsync,
onBefore,
onSuccess,
onError,
onFinally,
filters: filtersRef,
sorters: sortersRef,
dataTableRef
};
const templateBind = computed(() => {
return {
...expose,
loading: toValue(loading),
data: toValue(data),
error: toValue(error),
params: toValue(params),
list: toValue(list),
paginationRef: toValue(paginationRef),
filters: toValue(filtersRef),
sorters: toValue(sortersRef),
dataTableRef: toValue(dataTableRef)
};
});
__expose(expose);
return (_ctx, _cache) => {
return openBlock(), createBlock(unref(NFlex), {
style: {
width: "100%",
height: "100%"
},
vertical: ""
}, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "header", normalizeProps(guardReactiveProps(templateBind.value)), () => [createVNode(unref(NFlex), null, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "title", {}, () => [createElementVNode("div", _hoisted_1, [__props.title ? (openBlock(), createElementBlock("span", _hoisted_2, toDisplayString(__props.title), 1)) : createCommentVNode("v-if", true)])]),
__props.search ? (openBlock(), createBlock(unref(SearchInput_default), mergeProps({
key: 0,
style: {
marginLeft: "auto",
width: "280px"
},
value: unref(params)?.[0]?.[_fields.search],
loading: unref(loading)
}, searchProps, { "onUpdate:value": _cache[0] || (_cache[0] = (val) => onSearch(val)) }), null, 16, ["value", "loading"])) : createCommentVNode("v-if", true),
renderSlot(_ctx.$slots, "header-extra", normalizeProps(guardReactiveProps(templateBind.value)))
]),
_: 3
})]),
renderSlot(_ctx.$slots, "filter", normalizeProps(guardReactiveProps(templateBind.value))),
createElementVNode("div", _hoisted_3, [createVNode(unref(NDataTable), mergeProps({
ref: "data-table-ref",
remote: "",
"flex-height": "",
"single-line": false,
"scroll-x": scrollX.value,
style: {
width: "100%",
height: "100%"
},
"row-key": (row) => row?.[_fields.rowKey],
"children-key": _fields.children,
loading: unref(loading),
columns: columnsReactive,
data: unref(list),
"row-props": rowProps
}, __props.dataTableProps, {
"onUpdate:filters": vOn.onUpdateFilters,
"onUpdate:sorter": vOn.onUpdateSorter,
onLoad: vOn.onLoad,
onScroll: vOn.onScroll,
"onUpdate:checkedRowKeys": vOn.onUpdateCheckedRowKeys,
"onUpdate:expandedRowKeys": vOn.onUpdateExpandedRowKeys
}), {
empty: withCtx(() => [renderSlot(_ctx.$slots, "empty", normalizeProps(guardReactiveProps(templateBind.value)))]),
loading: withCtx(() => [renderSlot(_ctx.$slots, "loading", normalizeProps(guardReactiveProps(templateBind.value)))]),
_: 3
}, 16, [
"scroll-x",
"row-key",
"children-key",
"loading",
"columns",
"data",
"onUpdate:filters",
"onUpdate:sorter",
"onLoad",
"onScroll",
"onUpdate:checkedRowKeys",
"onUpdate:expandedRowKeys"
]), __props.scrollTop && _scrollTop.value > scrollTopProps.top ? (openBlock(), createBlock(unref(NButton), mergeProps({
key: 0,
secondary: "",
circle: "",
style: {
position: "absolute",
right: "20px",
bottom: "20px"
}
}, scrollTopProps.buttonProps, { onClick: handleScrollTop }), {
icon: withCtx(() => [createVNode(MageArrowUp_default)]),
_: 1
}, 16)) : createCommentVNode("v-if", true)]),
renderSlot(_ctx.$slots, "footer", normalizeProps(guardReactiveProps(templateBind.value)), () => [createVNode(unref(NFlex), null, {
default: withCtx(() => [renderSlot(_ctx.$slots, "footer-extra", normalizeProps(guardReactiveProps(templateBind.value))), __props.pagination ? (openBlock(), createBlock(unref(NPagination), mergeProps({
key: 0,
style: { marginLeft: "auto" },
disabled: unref(loading)
}, {
...paginationProps,
...unref(paginationRef)
}, {
"onUpdate:page": vOn.onUpdatePage,
"onUpdate:pageSize": vOn.onUpdatePageSize
}), null, 16, [
"disabled",
"onUpdate:page",
"onUpdate:pageSize"
])) : createCommentVNode("v-if", true)]),
_: 3
})])
]),
_: 3
});
};
}
});
var DataTablePlus_default = _sfc_main;
//#endregion
export { DataTablePlus_default as default };