156 lines
4.7 KiB
JavaScript
Executable File
156 lines
4.7 KiB
JavaScript
Executable File
import { defineComponent, h } from 'vue'
|
|
import { makeMap } from '@/utils/index'
|
|
|
|
const isAttr = makeMap(
|
|
'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,' +
|
|
'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,' +
|
|
'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,' +
|
|
'name,contenteditable,contextmenu,controls,coords,data,datetime,default,' +
|
|
'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,' +
|
|
'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,' +
|
|
'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,' +
|
|
'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,' +
|
|
'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,' +
|
|
'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,' +
|
|
'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,' +
|
|
'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,' +
|
|
'target,title,type,usemap,value,width,wrap' + 'prefix-icon'
|
|
)
|
|
const isNotProps = makeMap(
|
|
'layout,prepend,regList,tag,document,changeTag,defaultValue'
|
|
)
|
|
|
|
function useVModel(props, emit) {
|
|
return {
|
|
modelValue: props.defaultValue,
|
|
'onUpdate:modelValue': (val) => emit('update:modelValue', val),
|
|
}
|
|
}
|
|
const componentChild = {
|
|
'el-button': {
|
|
default(h, conf, key) {
|
|
return conf[key]
|
|
},
|
|
},
|
|
'el-select': {
|
|
options(h, conf, key) {
|
|
return conf.options.map(item => h(resolveComponent('el-option'), {
|
|
label: item.label,
|
|
value: item.value,
|
|
}))
|
|
}
|
|
},
|
|
'el-radio-group': {
|
|
options(h, conf, key) {
|
|
return conf.optionType === 'button' ? conf.options.map(item => h(resolveComponent('el-checkbox-button'), {
|
|
label: item.value,
|
|
}, () => item.label)) : conf.options.map(item => h(resolveComponent('el-radio'), {
|
|
label: item.value,
|
|
border: conf.border,
|
|
}, () => item.label))
|
|
}
|
|
},
|
|
'el-checkbox-group': {
|
|
options(h, conf, key) {
|
|
return conf.optionType === 'button' ? conf.options.map(item => h(resolveComponent('el-checkbox-button'), {
|
|
label: item.value,
|
|
}, () => item.label)) : conf.options.map(item => h(resolveComponent('el-checkbox'), {
|
|
label: item.value,
|
|
border: conf.border,
|
|
}, () => item.label))
|
|
}
|
|
},
|
|
'el-upload': {
|
|
'list-type': (h, conf, key) => {
|
|
const option = {}
|
|
// if (conf.showTip) {
|
|
// tip = h('div', {
|
|
// class: "el-upload__tip"
|
|
// }, () => '只能上传不超过' + conf.fileSize + conf.sizeUnit + '的' + conf.accept + '文件')
|
|
// }
|
|
if (conf['list-type'] === 'picture-card') {
|
|
return h(resolveComponent('el-icon'), option, () => h(resolveComponent('Plus')))
|
|
} else {
|
|
// option.size = "small"
|
|
option.type = "primary"
|
|
option.icon = "Upload"
|
|
return h(resolveComponent('el-button'), option, () => conf.buttonText)
|
|
}
|
|
},
|
|
|
|
}
|
|
}
|
|
const componentSlot = {
|
|
'el-upload': {
|
|
'tip': (h, conf, key) => {
|
|
if (conf.showTip) {
|
|
return () => h('div', {
|
|
class: "el-upload__tip"
|
|
}, '只能上传不超过' + conf.fileSize + conf.sizeUnit + '的' + conf.accept + '文件')
|
|
}
|
|
},
|
|
}
|
|
}
|
|
export default defineComponent({
|
|
|
|
// 使用 render 函数
|
|
render() {
|
|
const dataObject = {
|
|
attrs: {},
|
|
props: {},
|
|
on: {},
|
|
style: {}
|
|
}
|
|
const confClone = JSON.parse(JSON.stringify(this.conf))
|
|
const children = []
|
|
const slot = {}
|
|
const childObjs = componentChild[confClone.tag]
|
|
if (childObjs) {
|
|
Object.keys(childObjs).forEach(key => {
|
|
const childFunc = childObjs[key]
|
|
if (confClone[key]) {
|
|
children.push(childFunc(h, confClone, key))
|
|
}
|
|
})
|
|
}
|
|
const slotObjs = componentSlot[confClone.tag]
|
|
if (slotObjs) {
|
|
Object.keys(slotObjs).forEach(key => {
|
|
const childFunc = slotObjs[key]
|
|
if (confClone[key]) {
|
|
slot[key] = childFunc(h, confClone, key)
|
|
}
|
|
})
|
|
}
|
|
Object.keys(confClone).forEach(key => {
|
|
const val = confClone[key]
|
|
if (dataObject[key]) {
|
|
dataObject[key] = val
|
|
} else if (isAttr(key)) {
|
|
dataObject.attrs[key] = val
|
|
} else if (!isNotProps(key)) {
|
|
dataObject.props[key] = val
|
|
}
|
|
})
|
|
if(children.length > 0){
|
|
slot.default = () => children
|
|
}
|
|
|
|
return h(resolveComponent(this.conf.tag),
|
|
{
|
|
modelValue: this.$attrs.modelValue,
|
|
...dataObject.props,
|
|
...dataObject.attrs,
|
|
style: {
|
|
...dataObject.style
|
|
},
|
|
}
|
|
, slot ?? null)
|
|
},
|
|
props: {
|
|
conf: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
}
|
|
}) |