element plus el-form双列布局及拓展任意布局

1 场景

一般表单我们直接默认布局,也就是单列布局,突然有个人员信息表单,需要双列布局的需求,简单实现并拓展下

2 思路

直接无脑div+flex布局实现

3 代码

<template>
  <el-form ref="formRef" :model="formData" label-width="80px">
    <div class="form-top">
      <div class="form-top--left">
        <el-form-item label="姓名" prop="name">
          <el-input v-model="formData.name" placeholder="请输入姓名" />
        </el-form-item>
        <el-form-item label="年龄" prop="age">
          <el-input v-model="formData.age" placeholder="请输入年龄" />
        </el-form-item>
        <el-form-item label="性别" prop="sex">
          <el-radio-group v-model="formData.sex">
            <el-radio :label="1"></el-radio>
            <el-radio :label="2"></el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="formData.email" placeholder="请输入邮箱" />
        </el-form-item>

        <el-form-item label="排序" prop="sort" placeholder="请输入排序号">
          <el-input-number v-model="formData.sort" :min="1" />
        </el-form-item>
      </div>
      <div class="form-top--right">
        <el-form-item label="备注" prop="remark">
          <el-input
            v-model="formData.remark"
            type="textarea"
            placeholder="请输入备注"
            maxlength="100"
            show-word-limit
            resize="none"
          />
        </el-form-item>
        <el-form-item label="说明" prop="config">
          <el-input
            v-model="formData.config"
            placeholder="请输入说明"
            type="textarea"
            show-word-limit
            maxlength="200"
            :autosize="{ minRows: 6, maxRows: 6 }"
          />
        </el-form-item>
      </div>
    </div>
    <div class="form-bottom">
      <el-form-item>
        <el-button type="primary" @click="handleSubmit">确 定</el-button>
        <el-button type="warning" @click="handleClose">取 消</el-button>
      </el-form-item>
    </div>
  </el-form>
</template>

<script setup lang="ts">
const formRef = ref();

const formData = reactive({
  remark: "",
  age: 10,
  config: "",
  email: "",
  sex: "",
  id: null,
  name: "",
  sort: 0,
});

const handleClose = () => {};
const handleSubmit = () => {};
</script>
<style lang="scss" scoped>
.container {
  width: 600px;
  margin-top: 100px;
  .form-top {
    display: flex;
    justify-content: space-between;
    .form-top--right {
      flex: 1;
    }
  }
  .form-bottom {
    display: flex;
    justify-content: flex-end;
  }
}
</style>

在这里插入图片描述

这样的无脑实现实在是对不起付出的时间,不嫩复用是最大问题

4 拓展

封装el-form,增加slot

// Form.vue

<template>
  <el-form>
    <slot></slot>
    <div class="form-top" v-if="!slot.default">
      <div class="form-top--left" v-if="slot.left">
        <slot name="left"></slot>
      </div>
      <div class="form-top--right" v-if="slot.right">
        <slot name="right"></slot>
      </div>
    </div>
    <div class="form-bottom" v-if="slot.bottom">
      <slot name="bottom"></slot>
    </div>
  </el-form>
</template>

<script setup lang="ts">
const slot = useSlots();
</script>
<style lang="scss" scoped>
.form-top {
  display: flex;
  justify-content: space-between;
  .form-top--left {
    flex: 1;
  }
  .form-top--right {
    flex: 1;
  }
}
.form-bottom {
  display: flex;
  justify-content: flex-end;
}
</style>

// index.vue

<template>
  <Form ref="formRef" :model="formData" label-width="80px">
    <template #left>
      <el-form-item label="姓名" prop="name">
        <el-input v-model="formData.name" placeholder="请输入姓名" />
      </el-form-item>
      <el-form-item label="年龄" prop="age">
        <el-input v-model="formData.age" placeholder="请输入年龄" />
      </el-form-item>
      <el-form-item label="性别" prop="sex">
        <el-radio-group v-model="formData.sex">
          <el-radio :label="1"></el-radio>
          <el-radio :label="2"></el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="邮箱" prop="email">
        <el-input v-model="formData.email" placeholder="请输入邮箱" />
      </el-form-item>

      <el-form-item label="排序" prop="sort" placeholder="请输入排序号">
        <el-input-number v-model="formData.sort" :min="1" />
      </el-form-item>
    </template>
    <template #right>
      <el-form-item label="备注" prop="remark">
        <el-input
          v-model="formData.remark"
          type="textarea"
          placeholder="请输入备注"
          maxlength="100"
          show-word-limit
          resize="none"
        />
      </el-form-item>
      <el-form-item label="说明" prop="config">
        <el-input
          v-model="formData.config"
          placeholder="请输入说明"
          type="textarea"
          show-word-limit
          maxlength="200"
          :autosize="{ minRows: 6, maxRows: 6 }"
        />
      </el-form-item>
    </template>
    <template #bottom>
      <el-form-item>
        <el-button type="primary" @click="handleSubmit">确 定</el-button>
        <el-button type="warning" @click="handleClose">取 消</el-button>
      </el-form-item>
    </template>
  </Form>
</template>

<script setup lang="ts">
import Form from "./Form.vue";
const formRef = ref();

//添加人员表单
const formData = reactive({
  remark: "",
  age: 10,
  config: "",
  email: "",
  sex: "",
  id: null,
  name: "",
  sort: 0,
});

const handleClose = () => {};
const handleSubmit = () => {};
</script>
<style lang="scss" scoped>
.form-top {
  display: flex;
  justify-content: space-between;
  .form-top--right {
    flex: 1;
  }
}
.form-bottom {
  display: flex;
  justify-content: flex-end;
}
</style>

依然不够通用,因为布局是固定的,如果想要其他布局,要么修改Form.vue,要么重新封装

5 继续拓展

抽出layout,形成Layout.vue组件,拿出祖传技艺slot传递
// Layout.vue

<template>
  <div>
    <slot></slot>
    <div class="form-top" v-if="!slot.default">
      <div class="form-top--left" v-if="slot.left">
        <slot name="left"></slot>
      </div>
      <div class="form-top--right" v-if="slot.right">
        <slot name="right"></slot>
      </div>
    </div>
    <div class="form-bottom" v-if="slot.bottom">
      <slot name="bottom"></slot>
    </div>
  </div>
</template>

<script setup lang="ts">
const slot = useSlots();
</script>
<style lang="scss" scoped>
.form-top {
  display: flex;
  justify-content: space-between;
  .form-top--left {
    flex: 1;
  }
  .form-top--right {
    flex: 1;
  }
}
.form-bottom {
  display: flex;
  justify-content: flex-end;
}
</style>

// Form.vue

<template>
  <el-form>
    <Layout>
      <template v-for="item in Object.keys(slot)" :key="item" #[item]>
        <slot :name="item"></slot>
      </template>
    </Layout>
  </el-form>
</template>

<script setup lang="ts">
import Layout from "./Layout.vue";
const slot = useSlots();
</script>
<style lang="scss" scoped></style>

// index.vue

<template>
  <Form ref="formRef" :model="formData" label-width="80px">
    <template #left>
      <el-form-item label="姓名" prop="name">
        <el-input v-model="formData.name" placeholder="请输入姓名" />
      </el-form-item>
      <el-form-item label="年龄" prop="age">
        <el-input v-model="formData.age" placeholder="请输入年龄" />
      </el-form-item>
      <el-form-item label="性别" prop="sex">
        <el-radio-group v-model="formData.sex">
          <el-radio :label="1"></el-radio>
          <el-radio :label="2"></el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="邮箱" prop="email">
        <el-input v-model="formData.email" placeholder="请输入邮箱" />
      </el-form-item>

      <el-form-item label="排序" prop="sort" placeholder="请输入排序号">
        <el-input-number v-model="formData.sort" :min="1" />
      </el-form-item>
    </template>
    <template #right>
      <el-form-item label="备注" prop="remark">
        <el-input
          v-model="formData.remark"
          type="textarea"
          placeholder="请输入备注"
          maxlength="100"
          show-word-limit
          resize="none"
        />
      </el-form-item>
      <el-form-item label="说明" prop="config">
        <el-input
          v-model="formData.config"
          placeholder="请输入说明"
          type="textarea"
          show-word-limit
          maxlength="200"
          :autosize="{ minRows: 6, maxRows: 6 }"
        />
      </el-form-item>
    </template>
    <template #bottom>
      <el-form-item>
        <el-button type="primary" @click="handleSubmit">确 定</el-button>
        <el-button type="warning" @click="handleClose">取 消</el-button>
      </el-form-item>
    </template>
  </Form>
</template>

<script setup lang="ts">
import Form from "./Form.vue";
const formRef = ref();

//添加人员表单
const formData = reactive({
  remark: "",
  age: 10,
  config: "",
  email: "",
  sex: "",
  id: null,
  name: "",
  sort: 0,
});

const handleClose = () => {};
const handleSubmit = () => {};
</script>
<style lang="scss" scoped>
.form-top {
  display: flex;
  justify-content: space-between;
  .form-top--right {
    flex: 1;
  }
}
.form-bottom {
  display: flex;
  justify-content: flex-end;
}
</style>

6 总结

  1. 布局和数据分离

  2. 灵活扩展layout

    2.1 可以建立多个layout文件,批量引入(或动态引入)Form.vue中 ,Form.vue中利用动态组件component加载各个layout文件

    2.2 可以建立多个layout文件,批量引入(或动态引入)LayoutIndex.vue文件中,LayoutIndex.vue文件利用动态组件component加载各个layout文件,然后Form.vue中只渲染LayoutIndex,同时通过传参决定渲染那个layout

  3. 新增layout时,只需要新增文件(所有layout文件已经被批量引入<或动态引入>),符合“开闭”原则

tip:

批量引入(vite):import.meta.glob(‘./layout/**/*.vue’);

动态引入:defineAsyncComponent(() => import(./components/${layoutName}.vue));

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/308511.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024--Django平台开发-Django知识点(五)

day05 django知识点 今日概要&#xff1a; 中间件 【使用】【源码】cookie 【使用】【源码 - Django底层请求本质】session【使用】【源码 - 数据库请求周期中间件】 1.中间件 1.1 使用 编写类&#xff0c;在类型定义&#xff1a;process_request、process_view、process_…

基于JavaWeb+BS架构+SpringBoot+Vue校园一卡通系统的设计和实现

基于JavaWebBS架构SpringBootVue校园一卡通系统的设计和实现 文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 文末获取源码 Lun文目录 第一章 概述 4 1.1 研究背景 4 1.2研究目的及意义 4 1.3国内外发展现状 4 1…

最新出炉!知乎最牛最全JMeter+Ant+Jenkins接口自动化测试框架(Windows)

一:简介 大致思路&#xff1a;Jmeter可以做接口测试&#xff0c;也能做压力测试&#xff0c;而且是开源软件&#xff1b;Ant是基于Java的构建工具&#xff0c;完成脚本执行并收集结果生成报告&#xff0c;可以跨平台&#xff0c;Jenkins是持续集成工具。将这三者结合起来可以搭…

数据结构及单链表例题(下)

上次我们已经了解了单链表的数据结构定义以及创建单链表的两种方法,这节介绍几道例题. 文章目录 前言 一、已知L为带头结点的单链表,请依照递归思想实现下列运算 二、单链表访问第i个数据节点 三、在第i个元素前插入元素e 四、删除第i个结点 五、查找带头结点单链表倒数第…

C++学习笔记(三十二):c++ 堆内存与栈内存比较

本节对堆和栈内存进行描述。 应用程序启动后&#xff0c;操作系统将整个程序加载到内存&#xff0c;分配相应的物理ram&#xff0c;确保程序可以正常运行。堆和栈是ram中存在的两个区域。栈通常是一个预定义大小的内存区域&#xff0c;一般是2M字节左右。堆也是预定了默认值的…

固乔快递查询助手:批量、快速、全面的快递信息查询软件

在快递行业飞速发展的今天&#xff0c;如何高效、准确地掌握快递信息成为了很多人的需求。而固乔快递查询助手正是解决这一难题的利器。 固乔快递查询助手是一款专注于快递信息查询的软件&#xff0c;支持多家主流快递公司查询。用户只需输入单号&#xff0c;即可快速查询到实时…

RIP复习实验

条件: R1为外网&#xff0c;R8和r9的环回分别是172.16.1.0/24和172.16.2.0/24 中间使用78.1.1.0/24 剩下的路由器2-6使用172.16.0.0/16 要求: R1为运营商 r1远程登录r2实际登录r7 R2访问r7要求走r5去访问 全网可达 实现流程: 首先配置好各接口ip address 然后r2-r7使用rip…

vue2使用文件上传读取本地照片并转化base64格式进行展示

创建个vue2项目,直接把代码放到一个vue2页面内运行就好,下面代码拿来即用 <template><div><div class"replace_menu_mask" click"closeMenu"><img :src"replaceImg" alt"" style"width: 100%;">&l…

PandoraNext—一个让你呼吸顺畅的ChatGPT

博客地址 PandoraNext—一个让你呼吸顺畅的ChatGPT-雪饼 (xue6ing.cn)https://xue6ing.cn/archives/pandora--yi-ge-rang-ni-hu-xi-shun-chang-de-chatgpt 项目 项目地址 pandora-next/deploy 项目介绍 支持多种登录方式&#xff1a; 账号/密码 Access Token Session To…

探索Shadowsocks-Android:保护你的网络隐私

探索Shadowsocks-Android&#xff1a;保护你的网络隐私 I. 引言 在数字时代&#xff0c;网络隐私和安全变得愈发重要。我们越来越依赖互联网&#xff0c;但同时也面临着各种网络限制和监控。在这个背景下&#xff0c;Shadowsocks-Android应用程序应运而生&#xff0c;为用户提…

文心大模型融入荣耀MagicOS!打造大模型“端云协同”创新样板

2024年1月10日&#xff0c;在荣耀MagicOS 8.0发布会及开发者大会上&#xff0c;荣耀终端有限公司CEO赵明宣布了“百模生态计划”&#xff0c;并与百度集团执行副总裁、百度智能云事业群总裁沈抖共同宣布&#xff0c;百度智能云成为荣耀大模型生态战略合作伙伴。 沈抖在现场演讲…

前端导出Excel文件,部分数字前面0消失处理办法

详细导出可以看之前的文章 js实现导出Excel文档_js 通过 接口 导出 xlsx 代码-CSDN博客 今天的问题是导出一些数据时&#xff0c;有些字段是前面带有0的字符串&#xff0c;而导出后再excel中就被识别成了数字 如图本来字符串前面的0 都没了 解决方案 1. 导出的时候在前面加单…

第86讲:MySQLDump与Binlog日志实现企业级数据备份恢复案例

文章目录 1.企业级数据备份恢复案例描述2.第一环节&#xff1a;周三凌晨进行数据全量备份3.第二环节&#xff1a;模拟周三凌晨备份完之后到下午3点前的业务操作4.第三环节&#xff1a;模拟数据库异常数据丢失导致平台无法使用5.第四环节&#xff1a;发布停服公告全员进入数据恢…

PCL 计算异面直线的距离

目录 一、算法原理二、代码实现三、结果展示四、相关链接本文由CSDN点云侠原创,PCL 计算异面直线的距离,爬虫自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 设置直线 A B AB A

【Linux】通过两台linux主机配置ssh实现互相免密登陆

以下是通过两台Linux主机配置SSH实现互相免密登录的代码及操作流程&#xff1a; node1主机IP&#xff1a;192.168.48.129 server主机IP&#xff1a;192.168.48.130 1、在node1主机上生成密钥对&#xff1a; ssh-keygen -t rsa 2、将node1主机的公钥发送到server主机&#x…

Visual Studio 新特性:对 include 指令进行智能诊断

今天&#xff0c;我们很高兴地宣布新功能&#xff1a;#include 语言智能诊断。 此功能自 Visual Studio 2022 v17.9 预览版2 中可用。通过此新功能&#xff0c;您可以获取到有关每个 include 的引用和生成时间的详细信息&#xff0c;从而更好地了解 #include 指令的行为。 &g…

docker 部署项目的操作文档,安装nginx

目录 1 部署环境检查2 相关知识点2.1 docker默认镜像存放地址2.2 docker 的镜像都是tar 包&#xff1f;2.3 Docker-compose 是直接使用镜像创建容器&#xff1f;2.4 Docker Compose down 就是将容器删除&#xff1f;2.5 删除&#xff0c;会删除挂载嘛2.6 DockerFile 和 docker …

什么是线程?

线程 1. 线程概述 线程是计算机科学中的基本概念&#xff0c;指的是在一个进程中执行的独立指令流。通常&#xff0c;一个进程可以包含多个线程&#xff0c;它们共享进程的资源&#xff0c;如内存空间、文件句柄等&#xff0c;但每个线程有自己的独立执行流。线程是操作系统进…

计算机毕业设计 基于Java的流浪动物救助平台的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

使用Windbg动态调试目标进程的一般步骤详解

目录 1、概述 2、将Windbg附加到已经启动起来的目标进程上&#xff0c;或者用Windbg启动目标程序 2.1、将Windbg附加到已经启动起来的目标进程上 2.2、用Windbg启动目标程序 2.3、Windbg关联到目标进程上会中断下来&#xff0c;输入g命令将该中断跳过去 3、分析实例说明 …