vxe-pc-ui
Version:
A vue based PC component library
314 lines (313 loc) • 11.5 kB
JavaScript
import { defineComponent, ref, h, reactive, nextTick, provide, watch } from 'vue';
import XEUtils from 'xe-utils';
import { toCssUnit } from '../../ui/src/dom';
import { getConfig, createEvent, renderer, useSize } from '../../ui';
import { createListDesignActionButton } from '../render/util';
import { getDefaultSettingFormData } from './default-setting-data';
import LayoutPreviewComponent from './layout-preview';
import LayoutSettingComponent from './layout-setting';
export default defineComponent({
name: 'VxeListDesign',
props: {
size: {
type: String,
default: () => getConfig().listDesign.size || getConfig().size
},
height: {
type: [String, Number],
default: () => getConfig().listDesign.height
},
config: Object,
showPc: {
type: Boolean,
default: () => getConfig().listDesign.showPc
},
showMobile: {
type: Boolean,
default: () => getConfig().listDesign.showMobile
},
actionCodes: Array,
formRender: Object
},
emits: [],
setup(props, context) {
const { emit, slots } = context;
const xID = XEUtils.uniqueId();
const refElem = ref();
const { computeSize } = useSize(props);
const reactData = reactive({
formData: {},
searchFormData: {},
searchFormItems: [],
listTableColumns: []
});
const refMaps = {
refElem
};
const computeMaps = {
computeSize
};
const $xeListDesign = {
xID,
props,
context,
reactData,
getRefMaps: () => refMaps,
getComputeMaps: () => computeMaps
};
const systemConfigList = [];
const customConfigList = [];
renderer.forEach((item, name) => {
const { createListDesignSettingActionButtonConfig } = item;
if (createListDesignSettingActionButtonConfig) {
const params = { name };
const btnConfig = Object.assign(createListDesignActionButton({ code: name }), createListDesignSettingActionButtonConfig(params));
if (btnConfig.type === 'custom') {
customConfigList.push(btnConfig);
}
else {
systemConfigList.push(btnConfig);
}
}
});
const parseWidgetColumn = (widget) => {
return {
title: widget.title,
field: widget.field,
visible: !widget.hidden,
width: '',
cellRender: {
name: widget.name,
props: widget.options
}
};
};
/**
* 解析表单设计 JSON
*/
const parseFormDesignColumns = (config) => {
const tableColumns = [];
if (config) {
const { widgetData } = config;
if (widgetData) {
widgetData.forEach(item => {
const { name } = item;
if (name) {
// 如果是行列
if (name === 'row') {
item.children.forEach(childItem => {
if (childItem.name) {
tableColumns.push(parseWidgetColumn(childItem));
}
});
}
else if (name === 'subtable') {
// 如果是子表
}
else {
tableColumns.push(parseWidgetColumn(item));
}
}
});
}
}
return tableColumns;
};
const configToSearchItems = (searchItems) => {
if (searchItems) {
const data = {};
const items = searchItems.map(item => {
data[item.field] = null;
return {
field: item.field,
title: item.title,
folding: item.folding,
itemRender: item.itemRender
};
});
return {
items,
data
};
}
return { items: [], data: {} };
};
const configToListColumns = (listColumns) => {
if (listColumns) {
return listColumns.map(item => {
return {
field: item.field,
title: item.title,
visible: !!item.visible,
width: item.width,
cellRender: XEUtils.clone(item.cellRender)
};
});
}
return [];
};
const loadConfig = (config) => {
const { formConfig, searchItems, listColumns } = config;
if (formConfig) {
loadFormConfig(formConfig);
}
if (searchItems) {
setSearchItems(searchItems);
}
if (listColumns) {
reactData.listTableColumns = parseColumnConfigs(listColumns);
}
return nextTick();
};
const parseColumnConfigs = (listColumns) => {
return configToListColumns(listColumns);
};
const loadFormConfig = (data) => {
reactData.formData = Object.assign({}, createSettingForm(), data);
return nextTick();
};
const getSearchItems = () => {
return reactData.searchFormItems;
};
const setSearchItems = (searchItems) => {
const { data, items } = configToSearchItems(searchItems);
reactData.searchFormData = data;
reactData.searchFormItems = items;
return nextTick();
};
const getListColumns = () => {
return reactData.listTableColumns;
};
const setListColumns = (listColumns) => {
reactData.listTableColumns = parseColumnConfigs(listColumns);
return nextTick();
};
const createSettingForm = () => {
const { actionCodes, formRender } = props;
let conf = getDefaultSettingFormData();
// 处理默认按钮
if (actionCodes && actionCodes.length) {
if (!conf.actionButtonList || !conf.actionButtonList.length) {
const defActionBtnList = [];
actionCodes.forEach(item => {
if (XEUtils.isObject(item) && item.default) {
const sysItem = systemConfigList.find(obj => obj.code === item.code);
if (sysItem) {
defActionBtnList.push(createListDesignActionButton({
type: sysItem.type,
code: sysItem.code
}));
}
}
});
conf.actionButtonList = defActionBtnList;
}
}
// 如果为自定义渲染
if (formRender && formRender.name) {
const compConf = renderer.get(formRender.name);
const createFormConfig = compConf ? compConf.createListDesignSettingFormConfig : null;
const params = { name: formRender.name };
conf = ((createFormConfig ? createFormConfig(params) : {}) || {});
}
return conf;
};
const initSettingForm = () => {
reactData.formData = createSettingForm();
};
const clearConfig = () => {
loadConfig({
searchItems: [],
listColumns: []
});
initSettingForm();
return nextTick();
};
const listDesignMethods = {
dispatchEvent(type, params, evnt) {
emit(type, createEvent(evnt, { $listDesign: $xeListDesign }, params));
},
loadFormDesignConfig(config) {
const { listTableColumns } = reactData;
const oldMaps = {};
XEUtils.eachTree(listTableColumns, item => {
oldMaps[item.field] = item;
}, { children: 'children' });
const columns = parseFormDesignColumns(config);
XEUtils.eachTree(columns, item => {
const oldItem = oldMaps[item.field];
if (oldItem) {
if (oldItem.width) {
item.width = oldItem.width;
}
item.visible = oldItem.visible;
}
}, { children: 'children' });
reactData.listTableColumns = columns;
return nextTick();
},
reloadFormDesignConfig(config) {
reactData.listTableColumns = parseFormDesignColumns(config);
return nextTick();
},
getSearchItems,
setSearchItems,
getListColumns,
setListColumns,
getConfig() {
return {
formConfig: reactData.formData,
searchItems: getSearchItems(),
listColumns: getListColumns()
};
},
loadConfig,
reloadConfig(config) {
clearConfig();
return loadConfig(config);
},
clearConfig
};
const listDesignPrivateMethods = {};
Object.assign($xeListDesign, listDesignMethods, listDesignPrivateMethods);
const renderVN = () => {
const { height } = props;
const vSize = computeSize.value;
const headerSlot = slots.header;
return h('div', {
ref: refElem,
class: ['vxe-list-design', {
[`size--${vSize}`]: vSize
}],
style: height
? {
height: toCssUnit(height)
}
: null
}, [
h('div', {
class: 'vxe-list-design--header'
}, headerSlot ? headerSlot({}) : []),
h('div', {
class: 'vxe-list-design--body'
}, [
h(LayoutPreviewComponent),
h(LayoutSettingComponent)
])
]);
};
provide('$xeListDesign', $xeListDesign);
watch(() => props.config, (value) => {
loadConfig(value || {});
});
initSettingForm();
if (props.config) {
loadConfig(props.config);
}
$xeListDesign.renderVN = renderVN;
return $xeListDesign;
},
render() {
return this.renderVN();
}
});