import { defineAsyncComponent } from 'vue' import defaultInputComponentConfig from '../cip-form-input/component-config' import defaultLayoutComponentConfig from '../cip-form-layout/component-config' const generateAppendKey = (append) => { return append ? `-${append}` : '' } const analyseComponents = (dictionary, append) => { const result = {} const appendKey = generateAppendKey(append) // append ? `-${append}` : '' const appendPath = append ? `/${append}` : '' const errorComponent = defineAsyncComponent(dictionary.default(appendPath)) Object.keys(dictionary).map(key => { const loader = dictionary[key](appendPath) || dictionary.default(appendPath) result[`${key}${appendKey}`] = defineAsyncComponent({ loader, errorComponent, onError (error, retry, fail, attempts) { console.log(error) console.warn(`${key}${appendKey}组件加载失败,加载默认组件`) fail() } }) }) return result } const getComponentDictionary = (componentConfig) => { const result = {} Object.keys(componentConfig).forEach(key => { const config = componentConfig[key] const component = typeof config === 'function' ? config : componentConfig[key].component result[key] = component }) return result } const getLayoutType = (componentConfig) => { const result = [] Object.keys(componentConfig).forEach(key => { if (componentConfig[key].layout) { result.push(key) } }) return result } /** * 贯穿整个数据渲染的单例对象 */ export class DRender { constructor () { if (!DRender.instance) { this.init() DRender.instance = this } return DRender.instance } defaultComponentConfig={} componentDictionary = {} layoutTypeList=[] // 初始化 init () { const defaultComponentConfig = { ...defaultInputComponentConfig, ...defaultLayoutComponentConfig } this.defaultComponentConfig = defaultComponentConfig this.componentDictionary = getComponentDictionary(defaultComponentConfig) this.layoutTypeList = getLayoutType(defaultComponentConfig) } setConfig (renderConfig = {}) { const { components, plugins } = renderConfig const customComponentConfig = {} if (components) Object.assign(customComponentConfig, components) if (plugins) Object.assign(customComponentConfig, ...plugins) this.setCustomComponents(customComponentConfig) } setCustomComponents (customComponentsConfig) { const componentConfig = { ...this.defaultComponentConfig, ...customComponentsConfig } const componentDictionary = getComponentDictionary(componentConfig) this.componentDictionary = componentDictionary this.layoutTypeList = getLayoutType(componentConfig) } // 获取组件 getComponent (type, append = '') { if (!this[`${append}Components`]) { // 如果是没有缓存过的组件组 分析一次 this[`${append}Components`] = analyseComponents(this.componentDictionary, append) } return this[`${append}Components`][`${type}${generateAppendKey(append)}`] } isLayoutType (type) { return this.layoutTypeList.includes(type) } } // 必须直接实例化以防止数据为初始化导致的错误 const dRender = new DRender() // 根据d-renderConfig let dRenderConfig try { dRenderConfig = require('../../../d-render.config').default dRender.setConfig(dRenderConfig) } catch (e) { process.env.NODE_ENV === 'development' && console.log(e) }