用jsx二次封装你的组件库
八月更文第六弹, 开始啦! 🍦
这是我参与8月更文挑战的第6天,目前我们在开发前端项目的时候大多都会使用各种UI库来增加我们的开发效率,但是偶尔也会出现组件与我们的预期不符合需要进行改造的情况。如果经历过这种场景,那么在开发项目之前我们就应该未雨绸缪,对我们的组件进行二次封装。
这种改造通常会提升我们的开发效率,增加可维护性。但是这种改造也有弊端,就是需要耗费一定的人力和时间,二次封装后的组件需要有开发文档。所以各位是否要采纳此种建议,就视自己的项目而定吧~
开发概述
本文案例采用对vantUI的form表单进行二次封装,其实在日常的开发中,table和form也是最需要进行封装的组件之一
所需技术,vue-render,vue-jsx,对jsx使用不了解的同学可以移步jsx查看。
创建
首先在根目录下创建base文件夹,目录如下:
封装输入框组件
在components文件夹中创建ra-field->index.js
这里在使用的时候注意,prop直接传过来的值是不可以被直接修改的,所以此处使用watch监听,用计算属性创建了新的变量,最后再返回给父级。
import { Field } from 'vant'
export default {
props: {
field: {},
value: ''
},
computed: {
val: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
// 使用emit或者sync均可
}
}
},
render(h) {
let { placeholder, label } = this.field
return (
<div>
<Field v-model={this.val} label={label} placeholder={placeholder}></Field>
</div>
)
}
}
封装form组件
在ra-form->index.js 中引入写好的ra-field组件和vantUI的form组件
import { Form } from 'vant'
import RaField from './components/ra-field'
const { model, ...restProps } = Form.props
export default {
components: {
RaField
},
props: {
// 表单默认属性
...restProps,
fields: {
type: Array,
default: () => []
},
// 表单值
value: {
type: Object,
default: () => null
}
},
data() {
return {
formData: {}
}
},
computed: {
model: {
get() {
return this.value || this.formData
},
set(val) {
this.formData = val
}
}
},
render(h) {
const { disabled, ...props } = this.$props
return (
<div>
<Form
ref="form"
{...{
props: {
...props,
model: this.model
}
}}
>
{this._renderCells(h)}
</Form>
</div>
)
},
methods: {
_renderCells() {
const { fields } = this
const fieldEls = fields.map(row => {
// 去除隐藏
const newRow = row.filter(field => field.visible !== false)
if (newRow.length === 0) {
return null
}
return (
<div>
{newRow.map(field => {
return <RaField v-model={this.model[field.prop]} field={field}></RaField>
})}
</div>
)
})
return fieldEls
},
// 获取表单数据
getFieldValues() {
return this.model
}
}
}
使用
注册
在main.js进行全局注册或者在单个page进行独立引入,此处测试为单独引入组件。
二次封装后的组件只需要进行简单的数据配置即可,省去了大量的dom模块。
<template>
<div>
<ra-form ref="form" :fields="fields" />
<van-button size="small" type="primary" @click="getVal">获取数据</van-button>
</div>
</template>
<script>
import RaForm from '@/base/ra-form/index'
export default {
components: {
RaForm
},
data() {
return {
fields: [
[
{
label: '姓名',
prop: 'name',
placeholder: '请填写姓名'
},
{
label: '电话',
prop: 'phone',
placeholder: '请填写电话'
}
]
]
}
},
methods: {
getVal() {
const res = this.$refs.form.getFieldValues()
console.log(res)
}
}
}
</script>
demo项目地址
总结
本文到此结束,希望对你有帮助 😉