需求


1.点击“添加”按钮,弹出录入数据的对话框窗口,并录入数据,如果数据有误则不允许提交。数据填写完毕后,点击“保存”按钮,调用http协议提交数据,提交完毕刷新页面数据。点击“取消”按钮关闭对话框。

2.点击列表中的“修改”按钮,弹出数据修改对话框窗口,功能同上。

3.点击列表中的“删除”按钮,弹出删除数据的询问窗口,功能以此类推。

一、添加


在“src\mock\member.js”中,增加模拟保存数据的方法:

  1. adapters.push(
  2. (mockAdapter) => mockAdapter.onPost('/api/member/save').reply(req => {
  3. let promise = new Promise((resolve, reject) => {
  4. let data = req.data ? JSON.parse(req.data) : {}
  5. let result = {}
  6. if (data.name) {
  7. result.success = true
  8. result.message = '保存成功'
  9. } else {
  10. result.success = false
  11. result.message = '姓名是必填参数'
  12. }
  13.  
  14. setTimeout(() => {
  15. resolve([200, result])
  16. }, 2000)
  17. })
  18. return promise
  19. })
  20. )

在src\pages\Member.vue中编写添加相关的代码:

对话框的布局:

  1. <!--对话框-->
  2. <el-dialog :title="form && form.id ? '编辑' : '新增' " :visible.sync="formVisible" :close-on-click-modal="false">
  3. <el-form :model="form" label-width="100px" :rules="rules" ref="form">
  4. <el-form-item label="姓名" prop="name">
  5. <el-input v-model="form.name" />
  6. </el-form-item>
  7. <el-form-item label="性别" prop="sex">
  8. <el-radio-group v-model="form.sex">
  9. <el-radio :label="1"></el-radio>
  10. <el-radio :label="2"></el-radio>
  11. </el-radio-group>
  12. </el-form-item>
  13. </el-form>
  14. <div slot="footer" class="dialog-footer">
  15. <el-button @click.native="formVisible = false">取消</el-button>
  16. <el-button type="primary" @click.native="handleSubmit" :loading="formLoading">提交</el-button>
  17. </div>
  18. </el-dialog>

保存按钮的代码:

  1. let handleSubmit = function() {
  2. if (this.formLoading)
  3. return
  4.  
  5. this.$refs.form.validate(valid => {
  6. if (!valid)
  7. return
  8.  
  9. this.formLoading = true
  10.  
  11. //调用http协议
  12. this.$axios.post('/api/member/save', this.form).then(res => {
  13. this.formLoading = false
  14. if (!res.data.success) {
  15. this.$message({
  16. showClose: true,
  17. message: res.data.message,
  18. type: 'error'
  19. });
  20. return
  21. }
  22. this.$message({
  23. type: 'success',
  24. message: '保存成功!'
  25. })
  26.  
  27. //重新载入数据
  28. this.page = 1
  29. this.getRows()
  30. this.formVisible = false
  31. }).catch(e => this.formLoading = false)
  32. })
  33. }

二、修改


如果完成添加功能,那么修改的功能就非常简单,只需要把handleEdit方法修改为:

  1. let handleEdit = function(index, row) {
  2. this.form = Object.assign({}, row)
  3. this.formVisible = true
  4. }

注意的是:千万不要直接给form赋row的值,因为这样做的话,如果修改了数据但没有保存,关闭窗口的时候,列表中的数据会被误修改。Object.assign是克隆row的值,这样,form对象就是一个副本,怎么修改都没问题。

三、删除


在“src\mock\member.js”中,增加模拟删除数据的方法:

  1. adapters.push(
  2. (mockAdapter) => mockAdapter.onGet(/\/api\/member\/remove\/\w+/).reply(req => {
  3. let promise = new Promise((resolve, reject) => {
  4. let result = {
  5. success: true,
  6. message: '删除成功'
  7. }
  8. setTimeout(() => {
  9. resolve([200, result])
  10. }, 2000)
  11. })
  12. return promise
  13. })
  14. )

handleDelete的方法修改为:

  1. let handleDelete = function(index, row) {
  2. if (this.pageLoading)
  3. return
  4.  
  5. this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
  6. confirmButtonText: '确定',
  7. cancelButtonText: '取消',
  8. type: 'warning'
  9. }).then(() => {
  10. this.pageLoading = true
  11. this.$axios.get('/api/member/remove/' + row.id).then(res => {
  12. this.pageLoading = false
  13. if (!res.data.success) {
  14. this.$message({
  15. type: 'error',
  16. message: res.data.message
  17. })
  18. return
  19. }
  20. this.$message({
  21. type: 'success',
  22. message: '删除成功!'
  23. })
  24. this.page = 1
  25. this.getRows()
  26. }).catch(e => this.pageLoading = false)
  27. }).catch(e => {})
  28. }

完整的代码如下:

  1. // The Vue build version to load with the `import` command
  2. // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
  3. import Vue from 'vue'
  4. import App from './App'
  5. import router from './router'
  6.  
  7. Vue.config.productionTip = false
  8.  
  9. import 'font-awesome/css/font-awesome.min.css'
  10.  
  11. import ElementUI from 'element-ui'
  12. import './assets/theme/element-#0b0a3e/index.css'
  13. Vue.use(ElementUI)
  14.  
  15. //开发模式开启mock.js
  16. if (process.env.NODE_ENV === 'development') {
  17. require('./mock')
  18. }
  19.  
  20. import axios from 'axios'
  21. Vue.prototype.$axios = axios
  22.  
  23. /* eslint-disable no-new */
  24. new Vue({
  25. el: '#app',
  26. router,
  27. components: {
  28. App
  29. },
  30. template: '<App/>'
  31. })

src\main.js

  1. import Mock from 'mockjs'
  2.  
  3. let adapters = []
  4. adapters.push(
  5. (mockAdapter) => mockAdapter.onPost('/api/member/loadPage').reply(req => {
  6. let promise = new Promise((resolve, reject) => {
  7. let data = req.data ? JSON.parse(req.data) : {
  8. size: 20
  9. }
  10. let result = {
  11. rows: [],
  12. total: 10000
  13. }
  14. for (let i = 0; i < data.size; i++) {
  15. let item = Mock.mock({
  16. id: Mock.Random.guid(),
  17. name: Mock.Random.cname(),
  18. sex: Mock.Random.integer(1, 2),
  19. 'age|18-30': 1,
  20. date: Mock.Random.date(),
  21. address: Mock.mock('@county(true)'),
  22. })
  23. result.rows.push(item)
  24. }
  25. setTimeout(() => {
  26. resolve([200, result])
  27. }, 2000)
  28. })
  29. return promise
  30. })
  31. )
  32.  
  33. adapters.push(
  34. (mockAdapter) => mockAdapter.onPost('/api/member/save').reply(req => {
  35. let promise = new Promise((resolve, reject) => {
  36. let data = req.data ? JSON.parse(req.data) : {}
  37. let result = {}
  38. if (data.name) {
  39. result.success = true
  40. result.message = '保存成功'
  41. } else {
  42. result.success = false
  43. result.message = '姓名是必填参数'
  44. }
  45.  
  46. setTimeout(() => {
  47. resolve([200, result])
  48. }, 2000)
  49. })
  50. return promise
  51. })
  52. )
  53.  
  54. adapters.push(
  55. (mockAdapter) => mockAdapter.onGet(/\/api\/member\/remove\/\w+/).reply(req => {
  56. let promise = new Promise((resolve, reject) => {
  57. let result = {
  58. success: true,
  59. message: '删除成功'
  60. }
  61. setTimeout(() => {
  62. resolve([200, result])
  63. }, 2000)
  64. })
  65. return promise
  66. })
  67. )
  68.  
  69. export {
  70. adapters
  71. }

src\mock\member.js

  1. <template>
  2. <section>
  3. <!--工具条-->
  4. <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
  5. <el-form :inline="true" :model="filters">
  6. <el-form-item>
  7. <el-input v-model="filters.query" placeholder="姓名/手机号等条件" />
  8. </el-form-item>
  9. <el-form-item>
  10. <el-button type="primary" v-on:click="handleQuery" icon="el-icon-search">查询</el-button>
  11. </el-form-item>
  12. <el-form-item>
  13. <el-button type="primary" v-on:click="handleAdd" icon="el-icon-plus">添加</el-button>
  14. </el-form-item>
  15. </el-form>
  16. </el-col>
  17. <el-table :data="rows" style="width: 100%;overflow: auto;" :height="clientHeight" stripe border highlight-current-row v-loading="pageLoading">
  18. <el-table-column label="注册日期" width="180">
  19. <template slot-scope="scope">
  20. <i class="el-icon-time"></i>
  21. <span style="margin-left: 10px">{{ scope.row.date }}</span>
  22. </template>
  23. </el-table-column>
  24. <el-table-column label="姓名" width="180" :show-overflow-tooltip="true">
  25. <template slot-scope="scope">
  26. <el-popover trigger="hover" placement="top">
  27. <p>姓名: {{ scope.row.name }}</p>
  28. <p>住址: {{ scope.row.address }}</p>
  29. <div slot="reference" class="name-wrapper">
  30. <el-tag size="medium">{{ scope.row.name }}</el-tag>
  31. </div>
  32. </el-popover>
  33. </template>
  34. </el-table-column>
  35. <el-table-column prop="sex" label="性别" width="100" align="center" :show-overflow-tooltip="true">
  36. <template slot-scope="scope">
  37. {{scope.row.sex===1?'男':'女'}}
  38. </template>
  39. </el-table-column>
  40. <el-table-column label="操作">
  41. <template slot-scope="scope">
  42. <el-button
  43. size="mini"
  44. type="primary"
  45. @click="handleEdit(scope.$index, scope.row)"><i class="el-icon-edit"></i>编辑</el-button>
  46. <el-button
  47. size="mini"
  48. type="danger"
  49. @click="handleDelete(scope.$index, scope.row)"><i class="el-icon-delete"></i>删除</el-button>
  50. </template>
  51. </el-table-column>
  52. </el-table>
  53. <!--底部-->
  54. <el-col :span="24" class="toolbar">
  55. <el-pagination layout="prev, pager, next" @current-change="handleCurrentChange" :page-size="20" :total="total" style="float:right;">
  56. </el-pagination>
  57. </el-col>
  58.  
  59. <!--对话框-->
  60. <el-dialog :title="form && form.id ? '编辑' : '新增' " :visible.sync="formVisible" :close-on-click-modal="false">
  61. <el-form :model="form" label-width="100px" :rules="rules" ref="form">
  62. <el-form-item label="姓名" prop="name">
  63. <el-input v-model="form.name" />
  64. </el-form-item>
  65. <el-form-item label="性别" prop="sex">
  66. <el-radio-group v-model="form.sex">
  67. <el-radio :label="1"></el-radio>
  68. <el-radio :label="2"></el-radio>
  69. </el-radio-group>
  70. </el-form-item>
  71. </el-form>
  72. <div slot="footer" class="dialog-footer">
  73. <el-button @click.native="formVisible = false">取消</el-button>
  74. <el-button type="primary" @click.native="handleSubmit" :loading="formLoading">提交</el-button>
  75. </div>
  76. </el-dialog>
  77.  
  78. </section>
  79. </template>
  80.  
  81. <script>
  82. const rules = {
  83. name: [{
  84. required: true,
  85. message: '请输入姓名',
  86. trigger: 'blur'
  87. }],
  88. sex: [{
  89. required: true,
  90. message: '请选择性别',
  91. trigger: 'change'
  92. }]
  93. }
  94.  
  95. let data = () => {
  96. return {
  97. //页码
  98. page: 1,
  99. //每页数量
  100. size: 20,
  101. //总数
  102. total: 0,
  103. //查询条件
  104. filters: {},
  105. //页面数据
  106. rows: [],
  107. //页面载入状态
  108. pageLoading: false,
  109. //列表高度
  110. clientHeight: '100%',
  111. //表单数据
  112. form: {},
  113. //验证规则
  114. rules: rules,
  115. //对话框隐藏状态
  116. formVisible: false,
  117. //表单提交状态
  118. formLoading: false
  119. }
  120. }
  121.  
  122. let handleAdd = function() {
  123. this.form = {}
  124. this.form.sex = 1
  125. this.formVisible = true
  126. }
  127.  
  128. let handleEdit = function(index, row) {
  129. this.form = Object.assign({}, row)
  130. this.formVisible = true
  131. }
  132.  
  133. let handleDelete = function(index, row) {
  134. if (this.pageLoading)
  135. return
  136.  
  137. this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
  138. confirmButtonText: '确定',
  139. cancelButtonText: '取消',
  140. type: 'warning'
  141. }).then(() => {
  142. this.pageLoading = true
  143. this.$axios.get('/api/member/remove/' + row.id).then(res => {
  144. this.pageLoading = false
  145. if (!res.data.success) {
  146. this.$message({
  147. type: 'error',
  148. message: res.data.message
  149. })
  150. return
  151. }
  152. this.$message({
  153. type: 'success',
  154. message: '删除成功!'
  155. })
  156. this.page = 1
  157. this.getRows()
  158. }).catch(e => this.pageLoading = false)
  159. }).catch(e => {})
  160. }
  161.  
  162. let getRows = function() {
  163. if (this.pageLoading)
  164. return
  165. this.pageLoading = true
  166.  
  167. let params = {
  168. page: this.page,
  169. size: this.size,
  170. query: this.filters.query
  171. }
  172. //调用post请求
  173. this.$axios.post('/api/member/loadPage', params).then(res => {
  174. this.pageLoading = false
  175. if (!res.data || !res.data.rows)
  176. return
  177. //总数赋值
  178. this.total = res.data.total
  179. this.page++;
  180. //页面元素赋值
  181. this.rows = res.data.rows
  182. }).catch(e => this.pageLoading = false)
  183. }
  184.  
  185. let handleSubmit = function() {
  186. if (this.formLoading)
  187. return
  188.  
  189. this.$refs.form.validate(valid => {
  190. if (!valid)
  191. return
  192.  
  193. this.formLoading = true
  194.  
  195. //调用http协议
  196. this.$axios.post('/api/member/save', this.form).then(res => {
  197. this.formLoading = false
  198. if (!res.data.success) {
  199. this.$message({
  200. showClose: true,
  201. message: res.data.message,
  202. type: 'error'
  203. });
  204. return
  205. }
  206. this.$message({
  207. type: 'success',
  208. message: '保存成功!'
  209. })
  210.  
  211. //重新载入数据
  212. this.page = 1
  213. this.getRows()
  214. this.formVisible = false
  215. }).catch(e => this.formLoading = false)
  216. })
  217. }
  218.  
  219. let handleQuery = function() {
  220. this.page = 1
  221. this.getRows()
  222. }
  223.  
  224. let handleCurrentChange = function(val) {
  225. this.page = val
  226. this.getRows()
  227. }
  228.  
  229. let initHeight = function() {
  230. this.clientHeight = (document.documentElement.clientHeight - 258) + 'px'
  231. }
  232.  
  233. export default {
  234. data: data,
  235. methods: {
  236. //查询
  237. handleQuery,
  238. //添加
  239. handleAdd,
  240. //修改
  241. handleEdit,
  242. //删除
  243. handleDelete,
  244. //页数改变
  245. handleCurrentChange,
  246. //获取分页
  247. getRows,
  248. //初始化高度
  249. initHeight,
  250. //提交数据
  251. handleSubmit
  252. },
  253. mounted: function() {
  254. window.addEventListener('resize', this.initHeight)
  255. this.initHeight()
  256. this.getRows()
  257. }
  258. }
  259. </script>
  260.  
  261. <style scoped>
  262. </style>

src\pages\Member.vue

运行效果如下图所示:

好了,到这里,整个前端的开发就结束了,请我们期待一起完成后端的开发。

返回目录

git代码地址:https://github.com/carter659/spring-boot-vue-element.git

如果你觉得我的博客对你有帮助,可以给我点儿打赏,左侧微信,右侧支付宝。

有可能就是你的一点打赏会让我的博客写的更好:)

spring boot + vue + element-ui全栈开发入门——前端编辑数据对话框的更多相关文章

  1. 分享一个自搭的框架,使用Spring boot+Vue+Element UI

    废弃,新的:https://www.cnblogs.com/hackyo/p/10453243.html 特点:前后端分离,可遵循restful 框架:后端使用Spring boot,整合了aop.a ...

  2. spring boot + vue + element-ui全栈开发入门——前端列表页面开发

     一.页面 1.布局 假设,我们要开发一个会员列表的页面. 首先,添加vue页面文件“src\pages\Member.vue” 参照文档http://element.eleme.io/#/zh-CN ...

  3. koa+mysql+vue+socket.io全栈开发之前端篇

    React 与 Vue 之间的对比,是前端的一大热门话题. vue 简易上手的脚手架,以及官方提供必备的基础组件,比如 vuex,vue-router,对新手真的比较友好:react 则把这些都交给社 ...

  4. spring boot + vue + element-ui全栈开发入门——开篇

    最近经常看到很多java程序员朋友还在使用Spring 3.x,Spring MVC(struts),JSP.jQuery等这样传统技术.其实,我并不认为这些传统技术不好,而我想表达的是,技术的新旧程 ...

  5. spring boot + vue + element-ui全栈开发入门

    今天想弄弄element-ui  然后就在网上找了个例子 感觉还是可以用的  第一步是完成了  果断 拿过来  放到我这里这  下面直接是连接  点进去 就可以用啊 本想着不用vue   直接导入连接 ...

  6. spring boot + vue + element-ui全栈开发入门——基于Electron桌面应用开发

     前言 Electron是由Github开发,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库. Electron通过将Chromium和Node.js合并到同一个运行时环 ...

  7. spring boot + vue + element-ui全栈开发入门——spring boot后端开发

    前言 本文讲解作为后端的spring boot项目开发流程,如果您还不会配置spring boot环境,就请点击<玩转spring boot——快速开始>,如果您对spring boot还 ...

  8. koa+mysql+vue+socket.io全栈开发之数据访问篇

    后端搭起大体的框架后,接着涉及到的就是如何将数据持久化的问题,也就是对数据库进行 CURD 操作. 关于数据库方案, mongodb 和 mysql 都使用过,但我选用的是 mysql,原因: 目前为 ...

  9. 实习模块vue+java小型全栈开发(三)

    实习模块vue+java小型全栈开发(三) --dx 背景 首先,先给自己一个答案:这篇博客我定义为(三),因为之前的两个模块页面,内容都是一样的,但是被改了几次需求,就一直拖着没有上传. 今天是真正 ...

随机推荐

  1. Tomcat 本地运行正常,服务器部署后乱码问题

    Tomcat 在本地运行项目没啥问题,可是部署到服务器后就会发现有乱码的问题,这问题还是一半一半的,有些有,有些没有,这不是接收数据的时候会出现的乱码,是后台管理的页面中文乱码,我也是醉了, 把解决方 ...

  2. XVIII Open Cup named after E.V. Pankratiev. Grand Prix of SPb

    A. Base $i - 1$ Notation 两个性质: $2=1100$ $122=0$ 利用这两条性质实现高精度加法即可. 时间复杂度$O(n)$. #include<stdio.h&g ...

  3. NOIP-玩具谜题

    题目描述 小南有一套可爱的玩具小人,它们各有不同的职业. 有一天,这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外,如下图: 这时 `singer` 告 ...

  4. CSS3_扇形导航_transitionend 事件

    扇形导航 圆形按钮,切换一系列图片导航的显示与隐藏. 如果涉及过渡动画,定位的 top 和 left 必须写 Math.sin(弧度) 一圈弧度 = 2π,一圈角度 = 360 弧度 = (deg*2 ...

  5. Java课程2019年3月开学测试

    一.登录界面 模板的验证方式已经写在了function里面,我们只需要在提交的过程中进行验证. 我们这里需要注意到的是在login文件夹中,有一个randcode的验证码生成文件,打开代码我们可以看到 ...

  6. mongodb聚合命令

    聚合aggregate 聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成管道,可以对每个阶段的管道进行分组.过滤等功能,然后经过一系列的处理,输出相应的 ...

  7. Sum It Up---(DFS)

    Sum It Up Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  8. python学习-01

    1.编程语言分类: 编译型:(由编译器将代码编译成计算机识别的二进制文件)C \C++ \C#    运行速度较解释型语言快 解释型:(在运行时进行编译)python.php.sheel.ruby.j ...

  9. react-native-Cocoapods-Swift-Project

    https://reactnative.cn/docs/integration-with-existing-apps/ 1.创建一个xcode工程,single View就行,项目语言选择swift, ...

  10. hdfs常用的命令

    查看hadoop的状态hdfs haadmin -getServiceState nn1切换主从 hdfs haadmin -failover nn1 nn2查看hdfs是否安全模式hdfs dfsa ...