用jsx二次封装你的组件库

1,645 阅读2分钟

用jsx二次封装你的组件库

八月更文第六弹, 开始啦! 🍦

这是我参与8月更文挑战的第6天,目前我们在开发前端项目的时候大多都会使用各种UI库来增加我们的开发效率,但是偶尔也会出现组件与我们的预期不符合需要进行改造的情况。如果经历过这种场景,那么在开发项目之前我们就应该未雨绸缪,对我们的组件进行二次封装。
这种改造通常会提升我们的开发效率,增加可维护性。但是这种改造也有弊端,就是需要耗费一定的人力和时间,二次封装后的组件需要有开发文档。所以各位是否要采纳此种建议,就视自己的项目而定吧~

开发概述

本文案例采用对vantUI的form表单进行二次封装,其实在日常的开发中,table和form也是最需要进行封装的组件之一 所需技术,vue-rendervue-jsx,对jsx使用不了解的同学可以移步jsx查看。

创建

首先在根目录下创建base文件夹,目录如下:

e737a1f39aefb7d09b1d6232500112d.png

封装输入框组件

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项目地址

gitee.com/koukaile/vu…

总结

本文到此结束,希望对你有帮助 😉