封装一个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. stand up meeting 12/01/2015

    part 组员 今日工作 工作耗时/h 明日计划 工作耗时/h UI 冯晓云   赶工sprint3,各部分要合在一起时出现各种问题,各种修改测试:UI本身的功能继续实现完善    6 UWP对控件的 ...

  2. Python程序设计实验报告四:循环结构程序设计(设计型实验)

    安徽工程大学 Python程序设计 实验报告 班级   物流191   姓名  姚彩琴  学号3190505129 成绩 日期     2020.4.8     指导老师       修宇 [实验名称 ...

  3. B - Cow Marathon DFS+vector存图

    After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to get more exerc ...

  4. mysql 创建表 索引 主键 引擎 自增 注释 编码等

    CREATE TABLE text(id INT(20) COMMENT '主键',NAME VARCHAR(20) COMMENT '姓名',PASSWORD VARCHAR(20) COMMENT ...

  5. cmd 文件/文件夹的一切操作

    dir // 列出目录下所有文件夹 rd dirname // 删除dirname文件夹(空文件夹) rd /s/q dirname // 删除dirname文件夹(非空)

  6. MySQL优化之COUNT(*)效率(部分转载与个人亲测)

    说到MySQL的COUNT(*)的效率,发现越说越说不清楚,干脆写下来,分享给大家. COUNT(*)与COUNT(COL)网上搜索了下,发现各种说法都有:比如认为COUNT(COL)比COUNT(* ...

  7. Python pandas库159个常用方法使用说明

    Pandas库专为数据分析而设计,它是使Python成为强大而高效的数据分析环境的重要因素. 一.Pandas数据结构 1.import pandas as pd import numpy as np ...

  8. zookeeper笔记(二)

    title: zookeeper笔记(二) zookeeper ALC权限控制 getAcl path 可以查看某个node的权限 设置权限: 2. world方式 setAcl <path&g ...

  9. Linux系统管理第六次作业 进程和计划任务管理

    1.通过ps命令的两种选项形式查看进程信息 [root@localhost ~]# ps aux USER        PID %CPU %MEM    VSZ   RSS TTY      STA ...

  10. 腾讯视频怎么转成mp4模式 软件 工具 方法 最新【已解决】

    1.搜索: 小白兔视频格式在线转换 2.转换好后视频已经是MP4格式了. 转载于:https://blog.51cto.com/14204019/2396896