d-render.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { defineAsyncComponent } from 'vue'
  2. import defaultInputComponentConfig from '../cip-form-input/component-config'
  3. import defaultLayoutComponentConfig from '../cip-form-layout/component-config'
  4. const generateAppendKey = (append) => {
  5. return append ? `-${append}` : ''
  6. }
  7. const analyseComponents = (dictionary, append) => {
  8. const result = {}
  9. const appendKey = generateAppendKey(append) // append ? `-${append}` : ''
  10. const appendPath = append ? `/${append}` : ''
  11. const errorComponent = defineAsyncComponent(dictionary.default(appendPath))
  12. Object.keys(dictionary).map(key => {
  13. const loader = dictionary[key](appendPath) || dictionary.default(appendPath)
  14. result[`${key}${appendKey}`] = defineAsyncComponent({
  15. loader,
  16. errorComponent,
  17. onError (error, retry, fail, attempts) {
  18. console.log(error)
  19. console.warn(`${key}${appendKey}组件加载失败,加载默认组件`)
  20. fail()
  21. }
  22. })
  23. })
  24. return result
  25. }
  26. const getComponentDictionary = (componentConfig) => {
  27. const result = {}
  28. Object.keys(componentConfig).forEach(key => {
  29. const config = componentConfig[key]
  30. const component = typeof config === 'function' ? config : componentConfig[key].component
  31. result[key] = component
  32. })
  33. return result
  34. }
  35. const getLayoutType = (componentConfig) => {
  36. const result = []
  37. Object.keys(componentConfig).forEach(key => {
  38. if (componentConfig[key].layout) {
  39. result.push(key)
  40. }
  41. })
  42. return result
  43. }
  44. /**
  45. * 贯穿整个数据渲染的单例对象
  46. */
  47. export class DRender {
  48. constructor () {
  49. if (!DRender.instance) {
  50. this.init()
  51. DRender.instance = this
  52. }
  53. return DRender.instance
  54. }
  55. defaultComponentConfig={}
  56. componentDictionary = {}
  57. layoutTypeList=[]
  58. // 初始化
  59. init () {
  60. const defaultComponentConfig = { ...defaultInputComponentConfig, ...defaultLayoutComponentConfig }
  61. this.defaultComponentConfig = defaultComponentConfig
  62. this.componentDictionary = getComponentDictionary(defaultComponentConfig)
  63. this.layoutTypeList = getLayoutType(defaultComponentConfig)
  64. }
  65. setConfig (renderConfig = {}) {
  66. const { components, plugins } = renderConfig
  67. const customComponentConfig = {}
  68. if (components) Object.assign(customComponentConfig, components)
  69. if (plugins) Object.assign(customComponentConfig, ...plugins)
  70. this.setCustomComponents(customComponentConfig)
  71. }
  72. setCustomComponents (customComponentsConfig) {
  73. const componentConfig = { ...this.defaultComponentConfig, ...customComponentsConfig }
  74. const componentDictionary = getComponentDictionary(componentConfig)
  75. this.componentDictionary = componentDictionary
  76. this.layoutTypeList = getLayoutType(componentConfig)
  77. }
  78. // 获取组件
  79. getComponent (type, append = '') {
  80. if (!this[`${append}Components`]) {
  81. // 如果是没有缓存过的组件组 分析一次
  82. this[`${append}Components`] = analyseComponents(this.componentDictionary, append)
  83. }
  84. return this[`${append}Components`][`${type}${generateAppendKey(append)}`]
  85. }
  86. isLayoutType (type) {
  87. return this.layoutTypeList.includes(type)
  88. }
  89. }
  90. // 必须直接实例化以防止数据为初始化导致的错误
  91. const dRender = new DRender()
  92. // 根据d-renderConfig
  93. let dRenderConfig
  94. try {
  95. dRenderConfig = require('../../../d-render.config').default
  96. dRender.setConfig(dRenderConfig)
  97. } catch (e) {
  98. process.env.NODE_ENV === 'development' && console.log(e)
  99. }