render.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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-input': {
  26. prepend(h, conf, key) {
  27. return <template slot="prepend">{conf[key]}</template>
  28. },
  29. append(h, conf, key) {
  30. return <template slot="append">{conf[key]}</template>
  31. }
  32. },
  33. 'el-select': {
  34. options(h, conf, key) {
  35. const list = []
  36. conf.options.forEach(item => {
  37. list.push(<el-option label={item.label} value={item.value} disabled={item.disabled}></el-option>)
  38. })
  39. return list
  40. }
  41. },
  42. 'el-radio-group': {
  43. options(h, conf, key) {
  44. const list = []
  45. conf.options.forEach(item => {
  46. if (conf.optionType === 'button') list.push(<el-radio-button label={item.value}>{item.label}</el-radio-button>)
  47. else list.push(<el-radio label={item.value} border={conf.border}>{item.label}</el-radio>)
  48. })
  49. return list
  50. }
  51. },
  52. 'el-checkbox-group': {
  53. options(h, conf, key) {
  54. const list = []
  55. conf.options.forEach(item => {
  56. if (conf.optionType === 'button') {
  57. list.push(<el-checkbox-button label={item.value}>{item.label}</el-checkbox-button>)
  58. } else {
  59. list.push(<el-checkbox label={item.value} border={conf.border}>{item.label}</el-checkbox>)
  60. }
  61. })
  62. return list
  63. }
  64. },
  65. 'el-upload': {
  66. 'list-type': (h, conf, key) => {
  67. const list = []
  68. if (conf['list-type'] === 'picture-card') {
  69. list.push(<i class="el-icon-plus"></i>)
  70. } else {
  71. list.push(<el-button size="small" type="primary" icon="el-icon-upload">{conf.buttonText}</el-button>)
  72. }
  73. if (conf.showTip) {
  74. list.push(<div slot="tip" class="el-upload__tip">只能上传不超过 {conf.fileSize}{conf.sizeUnit} 的{conf.accept}文件</div>)
  75. }
  76. return list
  77. }
  78. }
  79. }
  80. export default {
  81. render(h) {
  82. const dataObject = {
  83. attrs: {},
  84. props: {},
  85. on: {},
  86. style: {}
  87. }
  88. const confClone = JSON.parse(JSON.stringify(this.conf))
  89. const children = []
  90. const childObjs = componentChild[confClone.tag]
  91. if (childObjs) {
  92. Object.keys(childObjs).forEach(key => {
  93. const childFunc = childObjs[key]
  94. if (confClone[key]) {
  95. children.push(childFunc(h, confClone, key))
  96. }
  97. })
  98. }
  99. Object.keys(confClone).forEach(key => {
  100. const val = confClone[key]
  101. if (key === 'vModel') {
  102. vModel(this, dataObject, confClone.defaultValue)
  103. } else if (dataObject[key]) {
  104. dataObject[key] = val
  105. } else if (!isAttr(key)) {
  106. dataObject.props[key] = val
  107. } else {
  108. dataObject.attrs[key] = val
  109. }
  110. })
  111. return h(this.conf.tag, dataObject, children)
  112. },
  113. props: ['conf']
  114. }