用动态组件写个通用表单组件

本文介绍如何使用Vue.js的动态组件和`keep-alive`特性来创建一个通用表单组件。通过`is`属性接受组件名或组件选项对象,`keep-alive`用于缓存组件实例以提高性能。同时,讨论了非Prop属性的使用,允许传递任意attribute到组件根元素。并展示了具体的数据格式和表单组件代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基础

<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

currentTabComponent可以是

  • 已注册组件的名字,
  • 或 一个组件的选项对象
    换句话说is attribute 接受一个组件名字比如ElementUI的elInput
data() {
	return {
		currentTabComponent: elInput
	}
}

或者 组件的选项对象

currentTab: {
  name: "Home",
  component: {
    template: "<div>Home component</div>"
  }
},
currentTabComponent: currentTab.component

keep-alive

你每次切换新标签的时候,Vue 都创建了一个新的 currentTabComponent 实例。
而keep-alive可以避免反复重渲染导致的性能问题。我们更希望那些组件实例能够被在它们第一次被创建的时候缓存下来。

非 Prop 的 Attribute

一个非 prop 的 attribute 是指传向一个组件,但是该组件并没有相应 prop 定义的 attribute。

因为显式定义的 prop 适用于向一个子组件传入信息,然而组件库的作者并不总能预见组件会被用于怎样的场景。这也是为什么组件可以接受任意的 attribute,而这些 attribute 会被添加到这个组件的根元素上。

例如,想象一下你通过一个 Bootstrap 插件使用了一个第三方的 组件,这个插件需要在其 上用到一个 data-date-picker attribute。我们可以将这个 attribute 添加到你的组件实例上:

<bootstrap-date-input data-date-picker="activated"></bootstrap-date-input>

然后这个 data-date-picker=“activated” attribute 就会自动添加到 的根元素上。

实例

数据格式

const fields = [
    {
        field: "ID",
        display: "ID",
        type: "number",
        readonly: true
      },
      {
        field: "名称",
        display: "名称",
        type: "string",
        required: true
      },
      {
        field: "类型",
        display: "类型",
        type: "string",
        required: true,
        enum: [
          "类型1",
          "类型2",
          "类型3",
          "类型4",
          "类型5",
        ]
      },
        {
          field: '日期',
          display: '日期',
          type: 'date'
      },
      ...
]

说明:

  • readonly 不显示在form表单面板上
  • required 是form表单提交的规则
  • 根据type字段选择控件
  • 含有enum的用选择框控件显示

表单组件代码

/* generalPanel.vue */
<template>
...
  <div>
    <el-form
      ref="form"
      :model="form"
      label-width="156px"
      label-position="right"
      size="mini"
      :status-icon="true"
      :inline-message="true"
    >
      <el-form-item
        size="mini"
        v-for="(item, index) in fields"
        :key="index"
        :label="item.display"
        :prop="item.field"
        :rules="createRule(item)"
      >
        <component
          v-if="item.enum == null"
          :is="getComponentName(item.type)"
          v-model="form[item.field]"
          controls-position="right"
          checked
          :placeholder="getlaceholder(item.display, item.type)"
          style="width: 100%;"
          @change="(param) => {changeFn(param, item.display)}"
        ></component>
        <el-select
          v-model="form[item.field]"
          v-else
          :placeholder="isInfoState ? '' : item.display"
          @change="(param) => {changeFn(param, item.field)}"
        >
          <el-option
            v-for="(item,index) in item.enum"
            :key="index"
            :value="item"
          ></el-option>
        </el-select>
      </el-form-item>
    </el-form>
    <el-footer class="form-footer" height="60px">
      <el-button size="mini" @click="resetForm('form')" icon="el-icon-refresh-right">重 置</el-button>
      <el-button
        size="mini"
        type="primary"
        icon="el-icon-circle-plus"
        :loading="saving"
        @click="onSubmit('form')"
      >保 存</el-button>
    </el-footer>
  </div>
</template>
 ...
</template>

完成!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值