spring boot + vue + element-ui全栈开发入门——前端编辑数据对话框
需求
1.点击“添加”按钮,弹出录入数据的对话框窗口,并录入数据,如果数据有误则不允许提交。数据填写完毕后,点击“保存”按钮,调用http协议提交数据,提交完毕刷新页面数据。点击“取消”按钮关闭对话框。
2.点击列表中的“修改”按钮,弹出数据修改对话框窗口,功能同上。
3.点击列表中的“删除”按钮,弹出删除数据的询问窗口,功能以此类推。
一、添加
在“src\mock\member.js”中,增加模拟保存数据的方法:
adapters.push(
(mockAdapter) => mockAdapter.onPost('/api/member/save').reply(req => {
let promise = new Promise((resolve, reject) => {
let data = req.data ? JSON.parse(req.data) : {}
let result = {}
if (data.name) {
result.success = true
result.message = '保存成功'
} else {
result.success = false
result.message = '姓名是必填参数'
} setTimeout(() => {
resolve([200, result])
}, 2000)
})
return promise
})
)
在src\pages\Member.vue中编写添加相关的代码:
对话框的布局:
<!--对话框-->
<el-dialog :title="form && form.id ? '编辑' : '新增' " :visible.sync="formVisible" :close-on-click-modal="false">
<el-form :model="form" label-width="100px" :rules="rules" ref="form">
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="form.sex">
<el-radio :label="1">男</el-radio>
<el-radio :label="2">女</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click.native="formVisible = false">取消</el-button>
<el-button type="primary" @click.native="handleSubmit" :loading="formLoading">提交</el-button>
</div>
</el-dialog>
保存按钮的代码:
let handleSubmit = function() {
if (this.formLoading)
return this.$refs.form.validate(valid => {
if (!valid)
return this.formLoading = true //调用http协议
this.$axios.post('/api/member/save', this.form).then(res => {
this.formLoading = false
if (!res.data.success) {
this.$message({
showClose: true,
message: res.data.message,
type: 'error'
});
return
}
this.$message({
type: 'success',
message: '保存成功!'
}) //重新载入数据
this.page = 1
this.getRows()
this.formVisible = false
}).catch(e => this.formLoading = false)
})
}
二、修改
如果完成添加功能,那么修改的功能就非常简单,只需要把handleEdit方法修改为:
let handleEdit = function(index, row) {
this.form = Object.assign({}, row)
this.formVisible = true
}
注意的是:千万不要直接给form赋row的值,因为这样做的话,如果修改了数据但没有保存,关闭窗口的时候,列表中的数据会被误修改。Object.assign是克隆row的值,这样,form对象就是一个副本,怎么修改都没问题。
三、删除
在“src\mock\member.js”中,增加模拟删除数据的方法:
adapters.push(
(mockAdapter) => mockAdapter.onGet(/\/api\/member\/remove\/\w+/).reply(req => {
let promise = new Promise((resolve, reject) => {
let result = {
success: true,
message: '删除成功'
}
setTimeout(() => {
resolve([200, result])
}, 2000)
})
return promise
})
)
handleDelete的方法修改为:
let handleDelete = function(index, row) {
if (this.pageLoading)
return this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.pageLoading = true
this.$axios.get('/api/member/remove/' + row.id).then(res => {
this.pageLoading = false
if (!res.data.success) {
this.$message({
type: 'error',
message: res.data.message
})
return
}
this.$message({
type: 'success',
message: '删除成功!'
})
this.page = 1
this.getRows()
}).catch(e => this.pageLoading = false)
}).catch(e => {})
}
完整的代码如下:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router' Vue.config.productionTip = false import 'font-awesome/css/font-awesome.min.css' import ElementUI from 'element-ui'
import './assets/theme/element-#0b0a3e/index.css'
Vue.use(ElementUI) //开发模式开启mock.js
if (process.env.NODE_ENV === 'development') {
require('./mock')
} import axios from 'axios'
Vue.prototype.$axios = axios /* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: {
App
},
template: '<App/>'
})
src\main.js
import Mock from 'mockjs' let adapters = []
adapters.push(
(mockAdapter) => mockAdapter.onPost('/api/member/loadPage').reply(req => {
let promise = new Promise((resolve, reject) => {
let data = req.data ? JSON.parse(req.data) : {
size: 20
}
let result = {
rows: [],
total: 10000
}
for (let i = 0; i < data.size; i++) {
let item = Mock.mock({
id: Mock.Random.guid(),
name: Mock.Random.cname(),
sex: Mock.Random.integer(1, 2),
'age|18-30': 1,
date: Mock.Random.date(),
address: Mock.mock('@county(true)'),
})
result.rows.push(item)
}
setTimeout(() => {
resolve([200, result])
}, 2000)
})
return promise
})
) adapters.push(
(mockAdapter) => mockAdapter.onPost('/api/member/save').reply(req => {
let promise = new Promise((resolve, reject) => {
let data = req.data ? JSON.parse(req.data) : {}
let result = {}
if (data.name) {
result.success = true
result.message = '保存成功'
} else {
result.success = false
result.message = '姓名是必填参数'
} setTimeout(() => {
resolve([200, result])
}, 2000)
})
return promise
})
) adapters.push(
(mockAdapter) => mockAdapter.onGet(/\/api\/member\/remove\/\w+/).reply(req => {
let promise = new Promise((resolve, reject) => {
let result = {
success: true,
message: '删除成功'
}
setTimeout(() => {
resolve([200, result])
}, 2000)
})
return promise
})
) export {
adapters
}
src\mock\member.js
<template>
<section>
<!--工具条-->
<el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
<el-form :inline="true" :model="filters">
<el-form-item>
<el-input v-model="filters.query" placeholder="姓名/手机号等条件" />
</el-form-item>
<el-form-item>
<el-button type="primary" v-on:click="handleQuery" icon="el-icon-search">查询</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" v-on:click="handleAdd" icon="el-icon-plus">添加</el-button>
</el-form-item>
</el-form>
</el-col>
<el-table :data="rows" style="width: 100%;overflow: auto;" :height="clientHeight" stripe border highlight-current-row v-loading="pageLoading">
<el-table-column label="注册日期" width="180">
<template slot-scope="scope">
<i class="el-icon-time"></i>
<span style="margin-left: 10px">{{ scope.row.date }}</span>
</template>
</el-table-column>
<el-table-column label="姓名" width="180" :show-overflow-tooltip="true">
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>姓名: {{ scope.row.name }}</p>
<p>住址: {{ scope.row.address }}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{ scope.row.name }}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="sex" label="性别" width="100" align="center" :show-overflow-tooltip="true">
<template slot-scope="scope">
{{scope.row.sex===1?'男':'女'}}
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
size="mini"
type="primary"
@click="handleEdit(scope.$index, scope.row)"><i class="el-icon-edit"></i>编辑</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)"><i class="el-icon-delete"></i>删除</el-button>
</template>
</el-table-column>
</el-table>
<!--底部-->
<el-col :span="24" class="toolbar">
<el-pagination layout="prev, pager, next" @current-change="handleCurrentChange" :page-size="20" :total="total" style="float:right;">
</el-pagination>
</el-col> <!--对话框-->
<el-dialog :title="form && form.id ? '编辑' : '新增' " :visible.sync="formVisible" :close-on-click-modal="false">
<el-form :model="form" label-width="100px" :rules="rules" ref="form">
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="form.sex">
<el-radio :label="1">男</el-radio>
<el-radio :label="2">女</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click.native="formVisible = false">取消</el-button>
<el-button type="primary" @click.native="handleSubmit" :loading="formLoading">提交</el-button>
</div>
</el-dialog> </section>
</template> <script>
const rules = {
name: [{
required: true,
message: '请输入姓名',
trigger: 'blur'
}],
sex: [{
required: true,
message: '请选择性别',
trigger: 'change'
}]
} let data = () => {
return {
//页码
page: 1,
//每页数量
size: 20,
//总数
total: 0,
//查询条件
filters: {},
//页面数据
rows: [],
//页面载入状态
pageLoading: false,
//列表高度
clientHeight: '100%',
//表单数据
form: {},
//验证规则
rules: rules,
//对话框隐藏状态
formVisible: false,
//表单提交状态
formLoading: false
}
} let handleAdd = function() {
this.form = {}
this.form.sex = 1
this.formVisible = true
} let handleEdit = function(index, row) {
this.form = Object.assign({}, row)
this.formVisible = true
} let handleDelete = function(index, row) {
if (this.pageLoading)
return this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.pageLoading = true
this.$axios.get('/api/member/remove/' + row.id).then(res => {
this.pageLoading = false
if (!res.data.success) {
this.$message({
type: 'error',
message: res.data.message
})
return
}
this.$message({
type: 'success',
message: '删除成功!'
})
this.page = 1
this.getRows()
}).catch(e => this.pageLoading = false)
}).catch(e => {})
} let getRows = function() {
if (this.pageLoading)
return
this.pageLoading = true let params = {
page: this.page,
size: this.size,
query: this.filters.query
}
//调用post请求
this.$axios.post('/api/member/loadPage', params).then(res => {
this.pageLoading = false
if (!res.data || !res.data.rows)
return
//总数赋值
this.total = res.data.total
this.page++;
//页面元素赋值
this.rows = res.data.rows
}).catch(e => this.pageLoading = false)
} let handleSubmit = function() {
if (this.formLoading)
return this.$refs.form.validate(valid => {
if (!valid)
return this.formLoading = true //调用http协议
this.$axios.post('/api/member/save', this.form).then(res => {
this.formLoading = false
if (!res.data.success) {
this.$message({
showClose: true,
message: res.data.message,
type: 'error'
});
return
}
this.$message({
type: 'success',
message: '保存成功!'
}) //重新载入数据
this.page = 1
this.getRows()
this.formVisible = false
}).catch(e => this.formLoading = false)
})
} let handleQuery = function() {
this.page = 1
this.getRows()
} let handleCurrentChange = function(val) {
this.page = val
this.getRows()
} let initHeight = function() {
this.clientHeight = (document.documentElement.clientHeight - 258) + 'px'
} export default {
data: data,
methods: {
//查询
handleQuery,
//添加
handleAdd,
//修改
handleEdit,
//删除
handleDelete,
//页数改变
handleCurrentChange,
//获取分页
getRows,
//初始化高度
initHeight,
//提交数据
handleSubmit
},
mounted: function() {
window.addEventListener('resize', this.initHeight)
this.initHeight()
this.getRows()
}
}
</script> <style scoped>
</style>
src\pages\Member.vue
运行效果如下图所示:
好了,到这里,整个前端的开发就结束了,请我们期待一起完成后端的开发。
git代码地址:https://github.com/carter659/spring-boot-vue-element.git
如果你觉得我的博客对你有帮助,可以给我点儿打赏,左侧微信,右侧支付宝。
有可能就是你的一点打赏会让我的博客写的更好:)
spring boot + vue + element-ui全栈开发入门——前端编辑数据对话框的更多相关文章
- 分享一个自搭的框架,使用Spring boot+Vue+Element UI
废弃,新的:https://www.cnblogs.com/hackyo/p/10453243.html 特点:前后端分离,可遵循restful 框架:后端使用Spring boot,整合了aop.a ...
- spring boot + vue + element-ui全栈开发入门——前端列表页面开发
一.页面 1.布局 假设,我们要开发一个会员列表的页面. 首先,添加vue页面文件“src\pages\Member.vue” 参照文档http://element.eleme.io/#/zh-CN ...
- koa+mysql+vue+socket.io全栈开发之前端篇
React 与 Vue 之间的对比,是前端的一大热门话题. vue 简易上手的脚手架,以及官方提供必备的基础组件,比如 vuex,vue-router,对新手真的比较友好:react 则把这些都交给社 ...
- spring boot + vue + element-ui全栈开发入门——开篇
最近经常看到很多java程序员朋友还在使用Spring 3.x,Spring MVC(struts),JSP.jQuery等这样传统技术.其实,我并不认为这些传统技术不好,而我想表达的是,技术的新旧程 ...
- spring boot + vue + element-ui全栈开发入门
今天想弄弄element-ui 然后就在网上找了个例子 感觉还是可以用的 第一步是完成了 果断 拿过来 放到我这里这 下面直接是连接 点进去 就可以用啊 本想着不用vue 直接导入连接 ...
- spring boot + vue + element-ui全栈开发入门——基于Electron桌面应用开发
前言 Electron是由Github开发,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库. Electron通过将Chromium和Node.js合并到同一个运行时环 ...
- spring boot + vue + element-ui全栈开发入门——spring boot后端开发
前言 本文讲解作为后端的spring boot项目开发流程,如果您还不会配置spring boot环境,就请点击<玩转spring boot——快速开始>,如果您对spring boot还 ...
- koa+mysql+vue+socket.io全栈开发之数据访问篇
后端搭起大体的框架后,接着涉及到的就是如何将数据持久化的问题,也就是对数据库进行 CURD 操作. 关于数据库方案, mongodb 和 mysql 都使用过,但我选用的是 mysql,原因: 目前为 ...
- 实习模块vue+java小型全栈开发(三)
实习模块vue+java小型全栈开发(三) --dx 背景 首先,先给自己一个答案:这篇博客我定义为(三),因为之前的两个模块页面,内容都是一样的,但是被改了几次需求,就一直拖着没有上传. 今天是真正 ...
随机推荐
- BZOJ.4009.[HNOI2015]接水果(整体二分 扫描线)
LOJ BZOJ 洛谷 又是一个三OJ rank1!=w= \(Description\) (还是感觉,为啥非要出那种题目背景啊=-=直接说不好么) 给定一棵树和一个路径集合(每条路径有一个权值).\ ...
- Django——在线教育项目总结
项目简介 在线教育平台 软件依赖: WEB框架:Django(1.11.7).Django REST framework 前端框架:Vue(2.5.16) 数据库: MySql.redis 支付平台: ...
- BSUIR Open Finals
A. Game with chocolates 因为差值必须是$P$的幂,故首先可以$O(\log n)$枚举出先手第一步所有取法,判断之后的游戏是否先手必败. 对于判断,首先特判非法的情况,并假设$ ...
- (89)Wangdao.com第二十二天_JavaScript DocumentFragment 节点
DocumentFragment 节点 代表一个文档的片段,本身就是一个完整的 DOM 树形结构. 它没有父节点,.parentNode 返回 null 可以插入任意数量的子节点. 不属于当前文档,操 ...
- C# int[,] 和 int[][]
int[] 一维数组 int[,] 二维数组 int[] [] 交错数组 又称“数组的数组” 一维数组声明与初始化 声明: int[] a = new int[]; 声明与初始化: int arr ...
- Nginx配置:nginx如何配置跳转fpm
location ~ \.php(.*)$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_split_path_inf ...
- css-不固定宽高定位
position: fixed; top:50%; left: 50%; transform: translate(-50%, -50%);
- monkey Test 环境配置
Android Monkey压力测试学习笔记 步骤:下载SDK -> 解压进入SDK Manager下载系统 -> 配置环境变量 -> 创建虚拟设备或连接真机 -> 进入命令模 ...
- 不让浏览器缓存index.html
参考文档:https://www.2cto.com/ask/question/4598 location = /index.html { add_header Cache-Control " ...
- IEnumerable、IEnumerator、ICollection、IList、List的继承关系及简单使用
IEnumerable和IEnumerable<T>接口在.NET中是非常重要的接口,它允许开发人员定义foreach语句功能的实现并支持非泛型方法的简单的迭代,IEnumerable和I ...