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

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

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

原文地址:https://www.cnblogs.com/GoodHelper/p/8432693.html

时间: 2024-10-04 00:40:39

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

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

最近经常看到很多java程序员朋友还在使用Spring 3.x,Spring MVC(struts),JSP.jQuery等这样传统技术.其实,我并不认为这些传统技术不好,而我想表达的是,技术的新旧程度体现了做项目时的生产力.生产力低了,项目的开发成本就高.反之,生产力高,则成本低.笔者写本系列的目的是让使用“前后端不分离”的老技术的开发者做一个入门级的过度.因为目前流行的“前后端分离”技术足够简单,足够方便,足够易学,也足够完善. 项目所使用的前端技术是:element-ui,文档地址是:ht

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

 前言 Electron是由Github开发,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库. Electron通过将Chromium和Node.js合并到同一个运行时环境中,并将其打包为Mac,Windows和Linux系统下的应用来实现这一目的. Electron于2013年作为构建Github上可编程的文本编辑器Atom的框架而被开发出来.这两个项目在2014春季开源. 目前它已成为开源开发者.初创企业和老牌公司常用的开发工具. 看看谁在使用Electron

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

实习模块vue+java小型全栈开发(三) --dx 背景 首先,先给自己一个答案:这篇博客我定义为(三),因为之前的两个模块页面,内容都是一样的,但是被改了几次需求,就一直拖着没有上传. 今天是真正意义上的全栈开发,用的都是当前市面上的最新的框架前端是vuejs,后端springBoot全家桶,知识点很全,而我正好勉强的把前端知识赶完,然后进行的这次模块开发,并且这次模块开发给了我很大的惊喜. 全栈果然很神奇. 模块简介:点击考勤之后,调到一个页面,完成这个页面的所用功能. 完成之后的页面:我

spring boot + vue + element-ui全栈开发入门——前后端整合开发

一.配置 思路是通过node的跨域配置来调用spring boot的rest api. 修改config\index.js文件,设置跨域配置proxyTable: proxyTable: { '/api': { target: 'http://localhost:18080/', changeOrigin: true, pathRewrite: { '^/api': '/' } } } 完整的config\index.js代码如下: 'use strict' // Template versio

spring boot + vue + element-ui全栈开发入门——项目部署

 前言 常用的部署方式有两种: 1.是把生成好的静态页面放到spring boot的static目录下,与打包后的spring boot项目一起发布,当spring boot运行起来后,自然而然就能访问到静态页面文件了. 这种方法比较简单,适用于非常小型的系统.优点是:不需要复杂的配置.而缺点也很明显:需要两者一同发布.我在这里就不做赘述了. 2.是通过http服务器发布,本文以nginx为例,重点介绍这种方式. 一.生成静态页面 运行npm run build 生成的页面文件在dist目录下:

20天Python全栈开发入门到精通视频

免费报名链接:https://ke.qq.com/course/206831 本次课程知识点:带你了解python目前带给我们的机遇和挑战. 全面系统的学习python编程语言,从容应对企业中各式 各样的开发任务.让你具备独立开发能力的同时,还要授之于渔,学好python的同时,还可以进行别的语言的学习和开发 ,只需要很小的学习成本便可掌握更多编程语言. 机构特色. 讲师介绍: 老男孩IT教育python资深讲师,曾任某上市公司云计算架构师,对分布式存储,SDN,爬虫等有深入研究 国内Pytho

3.ASP.NET全栈开发之前端校验(基于Vue的自定义校验)自实现小型验证框架

前面分享了两篇关于.NET的服务端校验的文章,在系统里光有服务端校验虽然能够勉强使用,但会出现许多不愉快的体验,如上一章我在最后提交的时候填写了3个表单,在仅有最后一个表单出现了错误的时候,虽然达到了校验功能,表明了错误,但我前面三个表单的数据都被干掉了啊.再则比如注册的时候我填了那么多东西,我提交后你却告诉我已经被注册了,如果不是真爱,大概会毫不留情的Alt+F4 再也不见啦. 为了解决这个问题,我们必须在系统中采用双校验,前端校验那么多,咱们ASP.NET MVC创建时默认会引入jquery

巨蟒python全栈开发数据库前端8:jQuery框架2

1.事件 2.批量操作 3.事件冒泡 4.事件委托 1.事件 常用事件 click(function(){...}) hover(function(){...}) blur(function(){...}) focus(function(){...}) change(function(){...}) //内容发生变化,input,select等 keyup(function(){...}) mouseover 和 mouseenter的区别是:mouseover事件只要你在绑定该事件的对象上移动

Python 全栈开发【第一篇】:目录

Python 全栈开发[第0篇]:目录 第一阶段:Python 开发入门 Python 全栈开发[第一篇]:计算机原理&Linux系统入门 Python 全栈开发[第二篇]:Python基础语法入门 Python 全栈开发[第三篇]:数据类型.字符编码.文件操作 第二阶段:函数编程&常用标准库 Python 全栈开发[第四篇]:函数.递归.生成器.迭代器 Pyhton 全栈开发[第五篇]:常用模块学习 第三阶段:面向对象编程&网络编程基础 Python 全栈开发[第六篇]:面向对象