一、组件化封装

1.首先创建一个form文件夹,将搜索框组件的内容全部写在这个里面,然后再在需要的页面直接引入相应的组件即可

2.首先先在goods.vue文件里面写对应的文本数组formItems,将所定义的类型IFormItem引用进去,这个里面写的字段都是对应goods.vue文件里面的文本数组formItems里面所拥有的字段

 const formItems: IFormItem[] = [{field: "id",type: "input",label: "id",placeholder: "请输入账号"},{field: "realname",type: "input",label: "姓名",placeholder: "请输入姓名"},{field: "cellphone",type: "input",label: "电话号码",placeholder: "请输入电话号码"}]

3.然后在form.vue文件里面去判断获取到的prop的数据,也就是父组件goods.vue传给子组件form.vue的formItems,根据里面写的type的类型去进行组件的匹配

form.vue

form.vue

  <el-form label-width="100px"><el-row><!--  :key="item.label"动态匹配--><template v-for="item in formItems" :key="item.label"><el-col :span="8"><!-- 动态匹配label值 --><el-form-item :label="item.label"><!-- 动态判断文本框类型,从而去使用对应的element组件 --><templatev-if="item.type === 'input' || item.type === 'password'"><!-- type是文本框 --><el-input:placeholder="item.placeholder":show-password="item.type === 'password'"/></template><template v-else-if="item.type === 'select'"><!-- type是下拉框 --><el-select :placeholder="item.placeholder" style="width: 100%"><el-optionv-for="option in item.options":key="option.value":value="option.value">{{ option.title }}</el-option></el-select></template></el-form-item></el-col></template></el-row></el-form>

4.可以选择在form.vue里面接收相应的样式itemStyle和labelWidth,或者直接在form.vue里面给他们默认值,然后绑定到上面对应的组件上,就能进行响应

5.一开始可以将所有的itemLayout、formItems、lableWidth和colLayout全部由父组件传给子组件,但是这样的话hy-form组件里面要传的东西就太多了,所以可以考虑把上面这些数据全部放在一个新变量里面,然后给这个新变量定义一个类型,这个类型里面就包括了这些变量值

6.虽然这样一定程度上简化了代码,但是goods.vue文件里面的代码还是太多了,为了更加简便,我们可以把formConfig单独抽离到一个文件里面,然后再在goods.vue里面去引用

search.config.ts

import { IForm } from '@/base-ui/form'
export const searchformConfig: IForm = {labelWidth: '120px',itemStyle: {padding: '10px 40px'},colLayout: {span: 8},formItems: [{field: "id",type: "input",label: "id",placeholder: "请输入商品id"},{field: "realname",type: "input",label: "商品名称",placeholder: "请输入商品名称"},{field: "cellphone",type: "input",label: "商品编号",placeholder: "请输入商品编号"}]
}

goods.vue

<template><div class="main"><div class="search"><!-- <hy-form:formItems="formItems":collayout="collayout":lableWidth="lableWith":itemLayout="itemLayout"></hy-form> --><!-- <hy-form v-bind="formConfig"></hy-form> --><hy-form v-bind="searchformConfig"></hy-form></div></div>
</template>
<script lang="ts">
import { defineComponent } from "vue"
// import HyForm, { IFormItem, IForm } from "@/base-ui/form"
import HyForm from "@/base-ui/form"
import { searchformConfig } from "./config/search.config"export default defineComponent({name: "goods",components: {HyForm},setup() {// const formItems: IFormItem[] = [//   {//     field: "id",//     type: "input",//     label: "id",//     placeholder: "请输入账号"//   },//   {//     field: "realname",//     type: "input",//     label: "姓名",//     placeholder: "请输入姓名"//   },//   {//     field: "cellphone",//     type: "input",//     label: "电话号码",//     placeholder: "请输入电话号码"//   }// ]// const labelWidth = "120px"// const itemStyle = { padding: "10px 40px" }// const collayout = { span: 8 }// 简化后的变量// const formConfig: IForm = {//   formItems: [//     {//       field: "id",//       type: "input",//       label: "id",//       placeholder: "请输入商品id"//     },//     {//       field: "realname",//       type: "input",//       label: "商品名称",//       placeholder: "请输入商品名称"//     },//     {//       field: "cellphone",//       type: "input",//       label: "商品编号",//       placeholder: "请输入商品编号"//     }//   ],//   labelWidth: "120px",//   itemStyle: { padding: "10px 40px" },//   collayout: { span: 8 }// }return {// formItems,// labelWidth,// itemStyle,// collayout// formConfigsearchformConfig}}
})
</script>

二、解决文本框的双向绑定问题

1.可以使用父组件向子组件传参数的办法,首先在一开始封装的formItem里面定义一个字段field,然后再在goods组件上去双向绑定

2.然后在form.vue文件里面,给文本框或下拉框这些动态匹配绑定V-model

goods.vue

search.config.ts

form.vue

3.但是这样做的话会有一个弊端,就是直接修改从父组件传过来的数据,一定程度上不是很严谨,所以可以选择将从父组件获取到的数据变量赋值拷贝给另一个变量,然后在form.vue里面去动态监听这个变量是否发生变化,从而去发送监听事件

goods.vue

form.vue

三、给搜索框动态绑定一个title标题

1.可以先给form.vue组件一个自定义的插槽

2.然后在之前的formItem数组中再多定义一个字段title

3.最后在引用form.vue组件对应的地方加入一个插槽template,然后动态匹配对应的title字段

四、增加搜索和重置按钮

1、跟前面增加title标题一样的道理,先给form.vue增加一个底部插槽

2.在goods.vue组件对应的位置加一个template,里面对应相应的按钮

五、组件的封装简化

1.为了使搜索组件能够多次使用,不用重复写代码,可以创建一个page-search文件夹,专门编写搜索组件的代码,这样方便之后直接引用这个组件到相应的页面即可

简化后的goods.vue

<template><div class="goods"><page-search :searchformConfig="searchformConfig"></page-search></div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue"
import { searchformConfig } from "./config/search.config"
import PageSearch from "@/components/page-search"export default defineComponent({name: "goods",components: {PageSearch},setup() {return {searchformConfig}}
})
</script>
<style scoped></style>

简化后的page-search.vue

<template><div class="page-search"><div class="search"><!-- <hy-form v-bind="formConfig"></hy-form> --><!-- <hy-form v-bind="searchformConfig" :formData="formData"></hy-form> --><hy-form v-bind="searchformConfig" v-model="formData"><!-- 插槽对应form.vue组件里面定义的一个插槽slot,这里的title可以自定义,从serch.config.ts传过来 --><!-- 头部标题插槽 --><template #header><h1>{{ searchformConfig.title }}</h1></template><!-- 底部按钮插槽 --><template #footer><div class="handle-btns"><el-button @click="handleResetClick"><el-icon> <Refresh /> </el-icon>重置</el-button><el-button type="primary" @click="handleQueryClick"><el-icon> <Search /> </el-icon>搜索</el-button><slot></slot></div></template></hy-form></div></div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue"
import HyForm from "@/base-ui/form"
// import { searchformConfig } from './config/search.config'
import { Search, Refresh } from "@element-plus/icons"export default defineComponent({props: {searchformConfig: {type: Object,required: true}},components: {HyForm,Search,Refresh},setup(props, { emit }) {const formData = ref({id: "",realname: "",cellphone: ""})return {formData}}
})
</script>
<style scoped>
.handle-btns {text-align: right;padding: 0 50px 20px 0;
}
</style>

form.vue文件跟之前的一样

<template><div class="hy-form"><div class="header"><slot name="header"></slot></div><el-form :label-width="labelWidth"><el-row><!--  :key="item.label"动态匹配--><template v-for="item in formItems" :key="item.label"><el-col v-bind="collayout"><!-- 动态匹配label值 --><el-form-item :label="item.label" :style="itemStyle"><!-- 动态判断文本框类型,从而去使用对应的element组件 --><templatev-if="item.type === 'input' || item.type === 'password'"><!-- type是文本框 --><el-input:placeholder="item.placeholder":show-password="item.type === 'password'"v-model="formData[`${item.field}`]"/></template><template v-else-if="item.type === 'select'"><!-- type是下拉框 --><el-select:placeholder="item.placeholder"style="width: 100%"v-model="formData[`${item.field}`]"><el-optionv-for="option in item.options":key="option.value":value="option.value">{{ option.title }}</el-option></el-select></template></el-form-item></el-col></template></el-row></el-form><div class="footer"><slot name="footer"></slot></div></div>
</template><script lang="ts">
import { defineComponent, PropType, ref, watch } from "vue"
import { IFormItem } from "../types"export default defineComponent({props: {// 改进之后的formDatamodelValue: {type: Object,required: true},// 这是子组件接收父组件传过来的数组数据formItems: {// 默认传过来的数据是IFormItem类型type: Array as PropType<IFormItem[]>,// 如果默认数据是数组或者对象时需要用箭头函数表示default: () => []},labelWidth: {type: String,default: "100px"},title: {type: String,default: ""},itemStyle: {type: Object,default: () => ({ padding: "10px 40px" })},collayout: {type: Object,default: () => ({xl: 6, //>1920 显示4个lg: 8,md: 12,sm: 24,xs: 24})}},emits: ["update:modelValue"],setup(props, { emit }) {// 这里是将获取到的props.modelValue重新拷贝一份放在formDataconst formData = ref({ ...props.modelValue })// 深度监听,当formData发生变化,就发送事件给父组件watch(formData,(newValue: any) => {console.log(newValue)emit("update:modelValue", newValue)},{deep: true})return {formData}}
})
</script><style scoped lang="less">
.hy-form {padding-top: 22px;
}
</style>

通用vue组件化搜索组件页面相关推荐

  1. 谈谈我对前端组件化中“组件”的理解,顺带写个Vue与React的demo

    谈谈我对前端组件化中"组件"的理解,顺带写个Vue与React的demo 前言 前端已经过了单兵作战的时代了,现在一个稍微复杂一点的项目都需要几个人协同开发,一个战略级别的APP的 ...

  2. Vue第二天学习总结—— Vue全家桶之组件化开发(组件化开发思想、组件注册、Vue调试工具用法、组件间数据交互传递、组件插槽、基于组件的案例——购物车)

    (一) 组件化开发思想 1. 现实中的组件化思想体现 组件化即是对某些可以进行复用的功能进行封装的标准化工作 标准:要想组件能够成功组合在一起,每个组件必须要有标准 分治:将不同的功能封装到不同的组件 ...

  3. vue的组件化+父子组件的通信

    文章目录 1.注册组件的基本步骤 1.1 原始的创建方法 1.2语法糖创建方法 2.全局组件与局部组件 2.1 全局组件 2.2 局部组件 2.3语法糖局部组件(最简写法) 3. 父子组件 4.组件中 ...

  4. Vue组件化开发--组件通信方式-父传子、子传父、非父子组件传值

    一.概述 以脚手架搭建的Vue项目为笔记背景. 如果将所有的代码逻辑全部放到一个组件中,代码是非常的臃肿和难以维护的. 并且在真实开发中,可能会有更多的内容和代码逻辑,对于扩展性和可维护性来说都是非常 ...

  5. Reac组件化以及组件通信

    一.模块与组件以及模块化与组件化慨念 模块:向外提供特定功能的JS文件,便于复用JS,简化JS,提升JS效率数据.对数据的操作(函数).将想暴露的私有的函数向外暴露(暴露的数据类型是对象) 2. 模块 ...

  6. Android组件化专题 - 组件化配置

    demo地址 Android组件化专题,详细讲解组件化的使用及配置,以及实现的原理. 本文章讲解了组件化的由来及配置,下期讲解页面路由跳转及路由原理与apt 1. 组件化的由来 模块化.组件化和插件化 ...

  7. mysql组件化_组件化开发和模块化开发概念辨析

    网上有许多讲组件化开发.模块化开发的文章,但大家一般都是将这两个概念混为一谈的,并没有加以区分.而且实际上许多人对于组件.模块的区别也不甚明了,甚至于许多博客文章专门解说这几个概念都有些谬误. 想分清 ...

  8. android 组件化_Android 组件化路由框架设计(仿Arouter)

    前言 在组件化开发中一个必须要面对的问题就是组件间页面跳转,实现的方法有很多,简单的可以通过反射获取,但是比较耗费性能,也可以通过隐式跳转,但是随着页面的增多,过滤条件会随之增多,后期维护麻烦.那还有 ...

  9. android 多态如何组件化,Android组件化之子模块之间通信方案

    1 背景 Android开发中你的模块(Module)一般只有一个app主模块,随着功能不断扩展你会发现一个模块的缺点就是各种业务高度耦合,你就想测试登录模块,那么你可能会把支付模块也编译进去了,代价 ...

最新文章

  1. 基于CNN目标检测方法(RCNN,Fast-RCNN,Faster-RCNN,Mask-RCNN,YOLO,SSD)行人检测,目标追踪,卷积神经网络
  2. php中js代码放在哪,JavaScript
  3. 怎样写 OpenStack Neutron 的 Extension (四)
  4. tomcat域名绑定设置
  5. js中的Java式继承
  6. 命令查看mysql端口映射_【转载】烂泥:如何利用telnet命令检测端口映射是否成功...
  7. 定时重启群晖 SurveillanceStation NVR服务
  8. 如何关闭AutoCAD2016上的“开始”界面、打开CAD就自动新建一个drawing1、“文件”选项卡?
  9. 最小二乘估计与卡尔曼滤波公式推导
  10. mp3处理工具(mp3agic)
  11. C语言 四种不同方法来判断闰年
  12. 利用CHARMM-GUI来建立膜双层结构的具体步骤
  13. IDEA 插件开发 向主菜单注册菜单项目
  14. 数字图像处理学习总结(1):灰度变换与空间滤波
  15. 英语水平测试项目(黄军威、殷乐乐、张益维20180531)
  16. [渝粤教育] 重庆城市管理职业学院 脑洞大开背后的创新思维 参考 资料
  17. AI 投资探索路上的一些感受
  18. 【Python】文件选择框选择文件
  19. Ray在蚂蚁大规模生成落地中的优化与实践
  20. 单相交流调压电路matlab仿真,单相斩控式交流调压电路

热门文章

  1. 游戏的轻度、中度、重度是什么意思
  2. 安装moodle的方法及遇到的问题
  3. 《Linux多线程服务端编程:使用muduoC++网络库》学习笔记
  4. 关于在Linux下无法查看caj文档的解决方案
  5. 征服账号服务器,最新中文征服服务端(带架设教程+客户端补丁+需要的工具)10.13日更新...
  6. 【多线程编程学习笔记6】终止线程执行,千万别踩这个坑!
  7. JavaRIM实现(PRC的其中一种方案)
  8. IAR环境 HandFault定位
  9. 新氧服务C端、赋能B端,驱动医美行业健康发展
  10. SlowFast复现