Vue给el-form支持分栏功能

1,658 阅读1分钟

常见的编辑页,就是一个form提交,

image.png

普通表单直接满足,在复杂表单的时候一个表单按功能区域划分,有2栏、3栏目、4栏目布局同时存在。可以给el-form-item增加col: number属性,常见布局是12等分,传递对应的数字给拆封

查看源码

import { defineComponent, cloneVNode, VNode, Slots } from "vue";
import { ElForm } from "element-plus";
import "./index.css";

function useChildren(slots: Slots) {
  return (
    slots &&
    slots.default &&
    slots.default().map((child: VNode) => {
      const pr = (100 * (child?.props?.col || 12)) / 12;
      return cloneVNode(child, {
        style: {
          maxWidth: `${pr}%`,
          flex: `0 0 ${pr}%`,
        },
      });
    })
  );
}

export default defineComponent({
  setup(props, { slots, attrs }) {
    const children = useChildren(slots);
    return () => (
      <ElForm {...attrs} class="el-pro-form">
        {children}
      </ElForm>
    );
  },
});
.el-pro-form {
  display: flex;
  flex-wrap: wrap;
}
.el-pro-form h3 {
  height: 32px;
  line-height: 32px;
  font-size: 16px;
  font-weight: 600;
  margin: 0 10px 16px;
  /* padding: 0 10px; */
  border-bottom: 1px solid rgb(239, 242, 247);
  position: relative;
}
.el-pro-form h3::before {
  position: absolute;
  content: "";
  top: 50%;
  transform: translateY(-50%);
  left: -10px;
  height: 14px;
  width: 4px;
  background-color: #1890FF;
  border-radius: 5px;
}
.el-pro-form .el-form-item__content {
  max-width: 436px;
}

页面调用

<script lang="ts" setup>
import ElProForm from "./components/el-pro-form";
import { reactive } from "vue";

// do not use same name with ref
const form = reactive({
  name: "",
  region: "",
  date1: "",
  date2: "",
  delivery: false,
  type: [],
  resource: "",
  desc: "",
});

const onSubmit = () => {
  console.log("submit!");
};
</script>

<template>
  <h2>普通表单展示(设置右边最宽436px)</h2>
  <el-pro-form :model="form" label-width="120px">
    <el-form-item label="Activity name">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item label="Activity zone">
      <el-select v-model="form.region" placeholder="please select your zone">
        <el-option label="Zone one" value="shanghai" />
        <el-option label="Zone two" value="beijing" />
      </el-select>
    </el-form-item>
    <el-form-item label="Activity time">
      <el-col :span="11">
        <el-date-picker
          v-model="form.date1"
          type="date"
          placeholder="Pick a date"
          style="width: 100%"
        />
      </el-col>
      <el-col :span="2" class="text-center">
        <span class="text-gray-500">-</span>
      </el-col>
      <el-col :span="11">
        <el-time-picker
          v-model="form.date2"
          placeholder="Pick a time"
          style="width: 100%"
        />
      </el-col>
    </el-form-item>
    <el-form-item label="Instant delivery">
      <el-switch v-model="form.delivery" />
    </el-form-item>
    <el-form-item label="Activity type">
      <el-checkbox-group v-model="form.type">
        <el-checkbox label="Online activities" name="type" />
        <el-checkbox label="Promotion activities" name="type" />
        <el-checkbox label="Offline activities" name="type" />
        <el-checkbox label="Simple brand exposure" name="type" />
      </el-checkbox-group>
    </el-form-item>
    <el-form-item label="Resources">
      <el-radio-group v-model="form.resource">
        <el-radio label="Sponsor" />
        <el-radio label="Venue" />
      </el-radio-group>
    </el-form-item>
    <el-form-item label="Activity form">
      <el-input v-model="form.desc" type="textarea" />
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="onSubmit">Create</el-button>
      <el-button>Cancel</el-button>
    </el-form-item>
  </el-pro-form>
  <h2>支持分栏 + 标题</h2>
  <el-pro-form :model="form" label-width="120px">
    <h3>基本信息(3栏目布局)</h3>
    <el-form-item label="Activity name" col="4">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item label="Activity name" col="4">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item label="Activity name" col="4">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item label="Activity name" col="4">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item label="Activity name" col="4">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item label="Activity name" col="4">
      <el-input v-model="form.name" />
    </el-form-item>
    <h3>扩展信息(4栏目布局)</h3>
    <el-form-item label="Activity name" col="3">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item label="Activity name" col="3">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item label="Activity name" col="3">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item label="Activity name" col="3">
      <el-input v-model="form.name" />
    </el-form-item>
    <h3>2等分(2栏布局)</h3>
    <el-form-item label="Activity name" col="6">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item label="Activity name" col="6">
      <el-input v-model="form.name" />
    </el-form-item>
  </el-pro-form>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
}
</style>

最终效果

image.png