定义
import { createVNode, h, markRaw, reactive, resolveComponent, SetupContext, VNode } from 'vue'
interface StyleItemPropType {
label: string
className?: string
contentClassName?: string
isLine?: boolean
}
export const StyleItem = <T extends StyleItemPropType, E extends Partial<SetupContext>> (props: T, ctx: E): VNode => {
return h('div', { class: `style-item ${ props.className ?? '' }`.trim() }, [
h('div', { class: 'label', innerText: props.label }),
h('div', { class: `content ${ props.contentClassName ?? '' }`.trim() }, ctx.slots)
])
}
interface SelectPxPropType {
modelValue: string
}
export const SelectPx = <T extends SelectPxPropType, E extends Partial<SetupContext>> (props: T, ctx: E): VNode => {
const options: Array<string> = markRaw(['10px', '20px', '30px', '40px', '50px'])
return createVNode(resolveComponent('el-select'), {
modelValue: props.modelValue,
clearable: true,
filterable: true,
class: 'style-class',
filterMethod: (value: string): void => {
!options.includes(value) && ctx.emit?.('update:modelValue', value)
},
onVisibleChange: () => {
props.modelValue && !options.includes(props.modelValue) && ctx.emit?.('update:modelValue', px(props.modelValue))
},
'onUpdate:modelValue': (value: string): void => {
ctx.emit?.('update:modelValue', value)
},
}, {
default: () => options.map((option: string) =>
createVNode(resolveComponent('el-option'), {
label: option,
value: option,
valueKey: option
}))
})
}
使用
<template>
<StyleItem label="文本" className="bottom-border">
这里可以随便填写内容,会被渲染到 .content div 中
</StyleItem>
<!-- 下拉框 -->
<SelectPx v-model="value"></SelectPx>
</template>
import { StyleItem, SelectPx } from '@mixins/useStyleAttr'
export default defineComponent({
....
components: {
StyleItem,
SelectPx,
}
})