jsx + element-ui 表单查询简单封装
前言
入职现在这家公司有几个月的时间了,前期主要做公司的业务,顺手给上一位前端老哥的代码做了一些优化,与其说是优化,其实这就是自己本身比较懒,至于上一个前端老哥代码写得咋样就不做讨论了,贴出来了我怕被找到被打,况且自己本身也是一个小菜鸟~,随心所欲的写代码并不是一件好事,也许你当时效率是拿捏了,可是到头来如果自己维护的话,大概率会感叹这*写的什么玩意。有点跑题了,写这篇文章的目的主要是记录一下自己根据项目的业务组成,对原有的重复代码(表单查询)进行封装,同时也为一些同学提供一下自己的封装思路。项目采用 Vue2 + element-ui + Jsx
安装JSX插件 Element-ui
npm install @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props babel-plugin-jsx-v-model element-ui -S 复制代码
配置 .babelrc
{ "plugins": ["transform-vue-jsx", "transform-runtime", "jsx-v-model"] } 复制代码
首先看一下Jsx代码是啥样的
render() { return ( //动态绑定样式 <div class={ 1 + 1 === 2 ? 'active' : ''}> //循环生成多个元a素 {[1,2,3].map(elment=> <a> {element} </a> )} </div> ) } 复制代码
关于Jsx的语法,可以自行去官网了解。
大致了解完Jsx之后,开始分析应该怎么封装。
看看需要封装的页面长什么样,这种很常规的查询表格页面,也是后台管理类项目中用得最多的,非常建议进行封装,为接下来的开发节省时间,同时也让项目不那么臃肿。
页面中包含两个部分,表单+表格,我们先将表单查询抽离出来做成一个组件。
表单组件封装分析
一个表单可能会包含的input、select、time等各种输入组件,所以输入类型可配置。
根据不同的输入类型,传入不同的参数。
提交查询时,后台提供的键名valueKey可配置。
综合我们的最基本的配置参数长这样:
{ type: 'input', label: '消息标题:', width: '200', placeholder: '请输入标题', valueKey: 'title' } 复制代码
表单组件内部具体实现
结合上面的配置参数,编写组件代码QueryComponent.vue:
<script> export default { name: "QueryComponent", //接收option props: { option: { type: Object, required: true } }, data: () => ({ queryData: {} //定义queryData用来保存表单输入后的键值对 }), //渲染函数 render() { return <div>{this.renderHtml(this.option)}</div>; }, methods: { //接收参数,返回相应的Jsx renderHtml(option) { if (option.type === "input") { return ( <el-form inline> <el-form-item label={option.label} label-position="right"> <el-input style={{ width: option.width + "px" }} v-model={this.queryData[option.valueKey]} placeholder={option.placeholder} ></el-input> </el-form-item> </el-form> ); } } } }; </script> 复制代码
在页面引入组件
<template> <div> <QueryComponent :option="option" /> </div> </template> <script> import QueryComponent from "@/components/QueryComponent.vue"; export default { components: { QueryComponent }, data: () => ({ option: { type: "input", label: "消息标题:", width: "260", placeholder: "请输入标题", valueKey: "title" } }) }; </script> 复制代码
到这里我们实现了一个input框的创建,效果:
显然,这样子实现肯定时满足不了我们的需求的,要考虑到表单查询一定是多个的,所以 option 参数应该是一个数组才合理:
<template> <div> <QueryComponent :options="options" @submit="submit" :reset="reset" /> </div> </template> <script> import QueryComponent from "@/components/QueryComponent.vue"; export default { components: { QueryComponent }, data() { return { options: [ { type: "input", label: "消息标题:", width: "260", placeholder: "请输入标题", valueKey: "title" }, { type: "select", label: "消息类型:", width: "260", placeholder: "请选择类型", valueKey: "messageType", // select的options 一般是从后台获取的 selectOptions: [ { label: "系统消息1", value: "1" }, { label: "系统消息2", value: "2" } ] } ] }; }, methods: { submit(queryData) { console.log("submit", queryData); //拿到queryData 进行查询 // await this.$http.get("/api/message/query", { // params: this.queryData // }); }, reset() { console.log("reset", this.queryData); } } }; </script> 复制代码
接下来在组件内部处理传进来的数组
<script> export default { name: "QueryComponent", //接收option props: { options: { type: Array, default: () => [] } }, data: () => ({ queryData: {}, //定义queryData用来保存表单输入后的键值对 title: "" }), //渲染函数 render() { return ( // 遍历options 根据option的type属性来渲染不同的组件 再加两个按钮 一个查询 一个重置 <div> <el-form inline> {this.options.map(option => this.renderHtml(option))} <el-form-item> <el-button type="primary" on-click={this.handleSubmit}> 查询 </el-button> </el-form-item> <el-form-item> <el-button on-click={this.handleReset}>重置</el-button> </el-form-item> </el-form> </div> ); }, methods: { //接收参数,返回相应的Jsx renderHtml(option) { // 这里不使用if else来判断 我怕太多了看不清代码 用对象配置(策略模式)实现不同输入框的渲染 const renderResult = { input: () => ( <el-form-item label={option.label} label-position="right"> <el-input style={{ width: option.width + "px" }} v-model={this.queryData[option.valueKey]} ></el-input> </el-form-item> ), select: () => ( <el-form-item label={option.label} label-position="right"> <el-select style={{ width: option.width + "px" }} v-model={this.queryData[option.valueKey]} > {option.selectOptions.map(item => ( <el-option label={item.label} value={item.value}></el-option> ))} </el-select> </el-form-item> ) }; return renderResult[option.type](); }, // 点击查询按钮的时候触发父组件submit事件 handleSubmit() { this.$emit("submit", this.queryData); }, // 清空表单 handleReset() { this.queryData = {}; this.$emit("reset"); } } }; </script> 复制代码
于是有了以下的渲染结果:
结语
其实到这里也只是在涉及到了jsx在vue当中的一些简单使用,写这篇文章也只是记录一下自己一开始的思路,这也只是自己做封装的时的一个最基本的骨架,在项目中肯定还会有很多东西需要扩展,比如说后台给你的数据永远不是你想要的,ui大婶动不动就给页面加朵花等等,要考虑到的东西还有挺多的,不过都可以以此为基础做扩展,最后如果大家觉得这样封装可行的话,接下来我会把表格的封装也整理一下。
作者:小小小小---柏
链接:https://juejin.cn/post/7068894386993659912