render.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { makeMap } from '@/utils/index'
  2. // 参考https://github.com/vuejs/vue/blob/v2.6.10/src/platforms/web/server/util.js
  3. const isAttr = makeMap(
  4. 'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,'
  5. + 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,'
  6. + 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,'
  7. + 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,'
  8. + 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,'
  9. + 'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,'
  10. + 'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,'
  11. + 'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,'
  12. + 'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,'
  13. + 'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,'
  14. + 'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,'
  15. + 'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,'
  16. + 'target,title,type,usemap,value,width,wrap'
  17. )
  18. function vModel(self, dataObject, defaultValue) {
  19. dataObject.props.value = defaultValue
  20. dataObject.on.input = val => {
  21. self.$emit('input', val)
  22. }
  23. }
  24. const componentChild = {
  25. 'el-button': {
  26. default(h, conf, key) {
  27. return conf[key]
  28. },
  29. },
  30. 'el-input': {
  31. prepend(h, conf, key) {
  32. return <template slot="prepend">{conf[key]}</template>
  33. },
  34. append(h, conf, key) {
  35. return <template slot="append">{conf[key]}</template>
  36. }
  37. },
  38. 'el-select': {
  39. options(h, conf, key) {
  40. const list = []
  41. conf.options.forEach(item => {
  42. list.push(<el-option label={item.label} value={item.value} disabled={item.disabled}></el-option>)
  43. })
  44. return list
  45. }
  46. },
  47. 'el-radio-group': {
  48. options(h, conf, key) {
  49. const list = []
  50. conf.options.forEach(item => {
  51. if (conf.optionType === 'button') list.push(<el-radio-button label={item.value}>{item.label}</el-radio-button>)
  52. else list.push(<el-radio label={item.value} border={conf.border}>{item.label}</el-radio>)
  53. })
  54. return list
  55. }
  56. },
  57. 'el-checkbox-group': {
  58. options(h, conf, key) {
  59. const list = []
  60. conf.options.forEach(item => {
  61. if (conf.optionType === 'button') {
  62. list.push(<el-checkbox-button label={item.value}>{item.label}</el-checkbox-button>)
  63. } else {
  64. list.push(<el-checkbox label={item.value} border={conf.border}>{item.label}</el-checkbox>)
  65. }
  66. })
  67. return list
  68. }
  69. },
  70. 'el-upload': {
  71. 'list-type': (h, conf, key) => {
  72. const list = []
  73. if (conf['list-type'] === 'picture-card') {
  74. list.push(<i class="el-icon-plus"></i>)
  75. } else {
  76. list.push(<el-button size="small" type="primary" icon="el-icon-upload">{conf.buttonText}</el-button>)
  77. }
  78. if (conf.showTip) {
  79. list.push(<div slot="tip" class="el-upload__tip">只能上传不超过 {conf.fileSize}{conf.sizeUnit} 的{conf.accept}文件</div>)
  80. }
  81. return list
  82. }
  83. }
  84. }
  85. export default {
  86. render(h) {
  87. const dataObject = {
  88. attrs: {},
  89. props: {},
  90. on: {},
  91. style: {}
  92. }
  93. const confClone = JSON.parse(JSON.stringify(this.conf))
  94. const children = []
  95. const childObjs = componentChild[confClone.tag]
  96. if (childObjs) {
  97. Object.keys(childObjs).forEach(key => {
  98. const childFunc = childObjs[key]
  99. if (confClone[key]) {
  100. children.push(childFunc(h, confClone, key))
  101. }
  102. })
  103. }
  104. Object.keys(confClone).forEach(key => {
  105. const val = confClone[key]
  106. if (key === 'vModel') {
  107. vModel(this, dataObject, confClone.defaultValue)
  108. } else if (dataObject[key]) {
  109. dataObject[key] = val
  110. } else if (!isAttr(key)) {
  111. dataObject.props[key] = val
  112. } else {
  113. dataObject.attrs[key] = val
  114. }
  115. })
  116. return h(this.conf.tag, dataObject, children)
  117. },
  118. props: ['conf']
  119. }