zoukankan      html  css  js  c++  java
  • spring boot + vue + element-ui全栈开发入门——前端编辑数据对话框

     需求


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

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

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

    一、添加


    在“srcmockmember.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
      })
    )

    在srcpagesMember.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对象就是一个副本,怎么修改都没问题。

    三、删除


    在“srcmockmember.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/>'
    })
    srcmain.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
    }
    srcmockmember.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=" 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>
    srcpagesMember.vue

    运行效果如下图所示:

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

    返回目录

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

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

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

  • 相关阅读:
    python threading acquire release
    .net支付宝调试
    C#获取微信openid
    KindeEditor图片上传插件用法
    .net Repeater内部的按钮事件代码demo(Repeater内button的删除事件)
    .net 执行页面跳转弹窗提示,刷新代码
    .net验证控件
    上传图片
    数据库写入时间
    数据库读取
  • 原文地址:https://www.cnblogs.com/GoodHelper/p/8432693.html
Copyright © 2011-2022 走看看