封装一个Form表单组件和Table组件

有关后台管理系统之前写过四遍博客,看这篇之前最好先看下这四篇博客。另外这里只展示关键部分代码,项目代码放在github上: mall-manage-system

1、Vue + Element-ui实现后台管理系统(1) --- 总述

2、Vue + Element-ui实现后台管理系统(2) --- 项目搭建 + ⾸⻚布局实现

3、Vue + Element-ui实现后台管理系统(3) --- 面包屑 + Tag标签切换功能

4、Vue + Element-ui实现后台管理系统(4)---封装一个ECharts组件的一点思路

这篇主要讲解实现图表的功能:

整体效果

图片效果

一、封装一个Form表单组件

1、封装思路

我们需要看下一个基础form组件,需要哪些数据。我们看下官网一个示例 Form 表单

<template>
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="姓名" >
<el-input v-model="form.name" style="width: 195px"></el-input>
</el-form-item>
<el-form-item label="国籍">
<el-select v-model="form.region" placeholder="请选择国籍">
<el-option label="中国" value="china"></el-option>
<el-option label="美国" value="America"></el-option>
</el-select>
</el-form-item>
<el-form-item label="爱好">
<el-checkbox-group v-model="form.type">
<el-checkbox label="画画" name="type" ></el-checkbox>
<el-checkbox label="吹泡泡" name="type"></el-checkbox>
<el-checkbox label="放风筝" name="type"></el-checkbox>
<el-checkbox label="看佩琦" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit" size="small">立即创建</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
form: {
name: '',
region: '',
type: []
}
}
},
methods: {
onSubmit() {
console.log('提交 -> ' + this.form.name + " " + this.form.region + " " + this.form.type );
}
}
}
</script>

运行结果

从这个简单的示例,至少有两份数据是需要父组件传入到表单组件中的:

1、v-model对应的数据,这份数据是用户选择好后给父组件的,所以是双向绑定的。

2、label 对应的数据,这里是写死的,既然要封装成一个控件那么这份数据也需要父组件传过来。

注意 这里需要注意的一点就是标签的类型是input 还是select是需要外面传来过来的数据告知的。同时如果是select那么还需要把option下面的数据返回。

2、封装Form组件

新建一个CommonForm.vue,作为封装Form的组件

<template>
<!--是否行内表单-->
<el-form :inline="inline" :model="form" ref="form" label-width="100px">
<!--标签显示名称-->
<el-form-item v-for="item in formLabel" :key="item.model" :label="item.label">
<!--根据type来显示是什么标签-->
<el-input v-model="form[item.model]" :placeholder="'请输入' + item.label" v-if="item.type==='input'"></el-input>
<el-select v-model="form[item.model]" placeholder="请选择" v-if="item.type === 'select'">
<!--如果是select或者checkbox 、Radio就还需要选项信息-->
<el-option v-for="item in item.opts" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
<el-switch v-model="form[item.model]" v-if="item.type === 'switch'"></el-switch>
<el-date-picker v-model="form[item.model]" type="date" placeholder="选择日期" v-if="item.type === 'date'" value-format="yyyy-MM-dd"> </el-date-picker>
</el-form-item>
<!--留一个插槽-->
<el-form-item><slot></slot></el-form-item>
</el-form>
</template> <script>
export default {
//inline 属性可以让表单域变为行内的表单域
//form 表单数据 formLabel 是标签数据
props: {
inline: Boolean,
form: Object,
formLabel: Array
}
}
</script>

这样一个简单的表单公共组件就完成了。

一、封装一个Table组件

1、封装思路

同样我们需要去看下element有关表格最简单的示例。Table 表格

代码示例

<template>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</template> <script>
export default {
data() {
return {
tableData: [{
date: '2017-05-04',
name: '小小',
address: '浙江省杭州市千岛湖镇 阳光路'
}, {
date: '1956-05-04',
name: '爷爷',
address: '浙江省杭州市千岛湖镇 清波花园'
}, {
date: '1958-05-04',
name: '奶奶',
address: '浙江省杭州市千岛湖镇 冬瓜乌'
}]
}
}
}
</script>

运行结果

从这个简单的示例,至少也是两份数据是需要父组件传入到表格组件中的:

1、v-model对应的数据,这份数据是用户选择好后给父组件的。

2、label 对应的数据,这里是写死的,既然要封装成一个控件那么这份数据也需要外面传过来。

注意 这里除了上面这两份数据外,还有一份数据在实际开发中也是需要的,那就是分页信息,因为一般table数据都会比较多所以分页还是非常需要的。

2、封装Table组件

新建一个CommonTable.vue,作为封装Table的组件

<template>
<div class="common-table">
<!--stripe 是否为斑马纹 v-loading在请求数据未返回的时间有个加载的图案,提高用户体验-->
<el-table :data="tableData" height="90%" stripe v-loading="config.loading">
<!--第一行为序号 默认写死-->
<el-table-column label="序号" width="85">
<!--slot-scope="scope" 这里取到当前单元格,scope.$index就是索引 默认从0开始这里从1开始-->
<template slot-scope="scope">
<span style="margin-left: 10px">{{ (config.page - 1) * 20 + scope.$index + 1 }}</span>
</template>
</el-table-column>
<!--show-overflow-tooltip 当内容过长被隐藏时显示 tooltip-->
<el-table-column show-overflow-tooltip v-for="item in tableLabel" :key="item.prop" :label="item.label" :width="item.width ? item.width : 125">
<!--其实可以在上面:prop="item.prop"就可以显示表单数据 这里设置插槽的方式话更加灵活 我们可以写样式-->
<template slot-scope="scope">
<span style="margin-left: 10px">{{ scope.row[item.prop] }}</span>
</template>
</el-table-column>
<!--操作-->
<el-table-column label="操作" min-width="180">
<template slot-scope="scope">
<el-button size="min" @click="handleEdit(scope.row)">编辑</el-button>
<el-button size="min" type="danger" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--分页-->
<el-pagination class="pager" layout="prev, pager, next" :total="config.total" :current-page.sync="config.page" @current-change="changePage" :page-size="20"></el-pagination>
</div>
</template> <script>
// config分页数据,这里面至少包括当前页码 总数量
export default {
props: {
tableData: Array,
tableLabel: Array,
config: Object
},
methods: {
//更新
handleEdit(row) {
this.$emit('edit', row)
},
//删除
handleDelete(row) {
this.$emit('del', row)
},
//分页
changePage(page) {
this.$emit('changePage', page)
}
}
}
</script>

三、示例

这里展示用户管理组件(UserManage.vue),它使用了上面两个封装后的组件。

<template>
<div class="manage">
<el-dialog :title="operateType === 'add' ? '新增用户' : '更新用户'" :visible.sync="isShow">
<common-form :formLabel="operateFormLabel" :form="operateForm" ref="form"></common-form>
<div slot="footer" class="dialog-footer">
<el-button @click="isShow = false">取 消</el-button>
<el-button type="primary" @click="confirm">确 定</el-button>
</div>
</el-dialog>
<div class="manage-header">
<el-button type="primary" @click="addUser">+ 新增</el-button>
<common-form inline :formLabel="formLabel" :form="searchFrom">
<el-button type="primary" @click="getList(searchFrom.keyword)">搜索</el-button>
</common-form>
</div>
<!--依次是: 表格数据 表格标签数据 分页数据 列表方法 更新方法 删除方法-->
<common-table :tableData="tableData" :tableLabel="tableLabel" :config="config" @changePage="getList()" @edit="editUser" @del="delUser"></common-table>
</div>
</template> <script>
import CommonForm from '../../components/CommonForm'
import CommonTable from '../../components/CommonTable'
export default {
components: {
CommonForm,
CommonTable
},
data() {
return {
operateType: 'add',
isShow: false,
tableData: [],
tableLabel: [
{
prop: 'name',
label: '姓名'
},
{
prop: 'age',
label: '年龄'
},
{
prop: 'sexLabel',
label: '性别'
},
{
prop: 'birth',
label: '出生日期',
width: 200
},
{
prop: 'addr',
label: '地址',
width: 320
}
],
config: {
page: 1,
total: 30,
loading: false
},
operateForm: {
name: '',
addr: '',
age: '',
birth: '',
sex: ''
},
operateFormLabel: [
{
model: 'name',
label: '姓名',
type: 'input'
},
{
model: 'age',
label: '年龄',
type: 'input'
},
{
model: 'sex',
label: '性别',
type: 'select',
opts: [
{
label: '男',
value: 1
},
{
label: '女',
value: 0
}
]
},
{
model: 'birth',
label: '出生日期',
type: 'date'
},
{
model: 'addr',
label: '地址',
type: 'input'
}
],
searchFrom: {
keyword: ''
},
formLabel: [
{
model: 'keyword',
label: '',
type: 'input'
}
]
}
},
methods: {
getList(name = '') {
this.config.loading = true
// 搜索时,页码需要设置为1,才能正确返回数据,因为数据是从第一页开始返回的
name ? (this.config.page = 1) : ''
this.$http
.get('/api/user/getUser', {
params: {
page: this.config.page,
name
}
})
.then(res => {
this.tableData = res.data.list.map(item => {
item.sexLabel = item.sex === 0 ? '女' : '男'
return item
})
this.config.total = res.data.count
this.config.loading = false
})
},
addUser() {
this.operateForm = {}
this.operateType = 'add'
this.isShow = true
},
editUser(row) {
this.operateType = 'edit'
this.isShow = true
this.operateForm = row
},
confirm() {
if (this.operateType === 'edit') {
console.log(this.operateForm)
this.$http.post('/api/user/edit', this.operateForm).then(res => {
console.log(res.data)
this.isShow = false
this.getList()
})
} else {
this.$http.post('/api/user/add', this.operateForm).then(res => {
console.log(res.data)
this.isShow = false
this.getList()
})
}
},
delUser(row) {
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
let id = row.id
this.$http
.get('/api/user/del', {
params: {
id
}
})
.then(res => {
console.log(res.data)
this.$message({
type: 'success',
message: '删除成功!'
})
this.getList()
})
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
}
},
created() {
this.getList()
}
}
</script> <style lang="scss" scoped>
@import '@/assets/scss/common';
</style>
别人骂我胖,我会生气,因为我心里承认了我胖。别人说我矮,我就会觉得好笑,因为我心里知道我不可能矮。这就是我们为什么会对别人的攻击生气。
攻我盾者,乃我内心之矛(15)

Vue + Element-ui实现后台管理系统(5)---封装一个Form表单组件和Table表格组件的更多相关文章

  1. 获取html 中的内容 将前台的数据获取到后台 用 jquery 生成一个 form表单 提交数据

    使用js创建一个form表单 ,使用post上传到后台中 下面是代码.在获取html内容的时候使用了js节点来获取内容. parent:父节点.上一级的节点 siblings:兄弟节点.同一级别的节点 ...

  2. Vue + Element UI 实现权限管理系统

    Vue + Element UI 实现权限管理系统 前端篇(一):搭建开发环境 https://www.cnblogs.com/xifengxiaoma/p/9533018.html

  3. 直接提交一个form表单后台返回一个新页面通过target属性可以放到iframe当中

    问题描述: 我想提交一个form表单后台直接返回一个新页面,但是当前页面还不想被替换掉: 解决方案: 在页面中添加一个iframe将form表单的target属性设置为iframe的id这样的话返回的 ...

  4. Vue + Element-ui实现后台管理系统(4)---封装一个ECharts组件的一点思路

    封装一个ECharts组件的一点思路 有关后台管理系统之前写过三遍博客,看这篇之前最好先看下这三篇博客.另外这里只展示关键部分代码,项目代码放在github上: mall-manage-system ...

  5. Vue + Element UI 实现权限管理系统 (管理应用状态)

    使用 Vuex 管理应用状态 1. 引入背景 像先前我们是有导航菜单栏收缩和展开功能的,但是因为组件封装的原因,隐藏按钮在头部组件,而导航菜单在导航菜单组件,这样就涉及到了组件收缩状态的共享问题.收缩 ...

  6. Vue + Element UI 实现权限管理系统 前端篇(八):管理应用状态

    使用 Vuex 管理应用状态 1. 引入背景 像先前我们是有导航菜单栏收缩和展开功能的,但是因为组件封装的原因,隐藏按钮在头部组件,而导航菜单在导航菜单组件,这样就涉及到了组件收缩状态的共享问题.收缩 ...

  7. Vue + Element UI 实现权限管理系统 前端篇(十四):菜单功能实现

    菜单功能实现 菜单接口封装 菜单管理是一个对菜单树结构的增删改查操作. 提供一个菜单查询接口,查询整颗菜单树形结构. http/modules/menu.js 添加 findMenuTree 接口. ...

  8. Vue + Element UI 实现权限管理系统 前端篇(十二):用户管理模块

    用户管理模块 添加接口 在 http/moduls/user.js 中添加用户管理相关接口. import axios from '../axios' /* * 用户管理模块 */ // 保存 exp ...

  9. Vue + Element UI 实现权限管理系统 前端篇(十一):第三方图标库

    使用第三方图标库 用过Elment的同鞋都知道,Element UI提供的字体图符少之又少,实在是不够用啊,幸好现在有不少丰富的第三方图标库可用,引入也不会很麻烦. Font Awesome Font ...

随机推荐

  1. [WEB前置技能]HTTP协议

    HTTP概述 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送 ...

  2. Windows 上安装msql库安装(基于8.0.19免安装版)

    一.进入官网进行下载mysql程序包: https://dev.mysql.com/downloads/mysql/ 二.解压缩 解压文件夹到指定目录,我放在 D:\mysql-8.0.19-winx ...

  3. Docker 安装 Jenkins , 并解决初始安装插件失败

    安装 Jenkins 后,初始化下载插件总是失败,导致安装不成功,重试好几次都是卡在安装插件那. 这里记录下 Docker 下怎么安装 Jenkins ,并解决初始安装插件失败问题. 安装插件失败,其 ...

  4. 漫谈LiteOS-端云互通组件-MQTT开发指南(下)

    1.介绍 SDK简介 Agent Tiny是部署在具备广域网能力.对功耗/存储/计算资源有苛刻限制的终端设备上的轻量级互联互通中间件,您只需调用API接口,便可实现设备快速接入到物联网平台以及数据上报 ...

  5. linux内核第一宏 container_of

    内核第一宏 list_entry()有着内核第一宏的美称,它被设计用来通过结构体成员的指针来返回结构体的指针.现在就让我们通过一步步的分析,来揭开它的神秘面纱,感受内核第一宏设计的精妙之处. 整理分析 ...

  6. Istio架构详解

    Istio架构及其组件概述 Istio 架构总体来说分为控制面和数据面两部分.控制面是 Istio 的核心,管理 Istio 的所有功能,主要包括Pilot.Mixer.Citadel等服务组件;数据 ...

  7. ajax发送时禁用按钮

    css /*div无法点击*/ .div-cant-click { pointer-events: none; } 发送ajax实例 $.ajax({ url:'url', type:'post', ...

  8. 20199326《Linux内核原理与分析》第十一周作业

    Shellsock攻击实验 实验背景 2014年9月24日,Bash中发现了一个严重漏洞shellshock,该漏洞可用于许多系统,并且既可以远程也可以在本地触发. Shellshock,又称Bash ...

  9. 2019-2020-1 20199329《Linux内核原理与分析》第七周作业

    <Linux内核原理与分析>第七周作业 一.本周内容概述: 对Linux系统如何创建一个新进程进行追踪 分析Linux内核创建一个新进程的过程 二.本周学习内容: 1.学习进程的描述 操作 ...

  10. 查看现有的 cipher suite

    openssl ciphers [-v] [-ssl2] [-ssl3] [-tls1] [cipherlist]