spring boot + vue + element-ui全棧開發入門——前端編輯資料對話方塊

冬子哥發表於2018-02-09

 需求


 

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

 

如果你覺得我的部落格對你有幫助,可以給我點兒打賞,左側微信,右側支付寶。

有可能就是你的一點打賞會讓我的部落格寫的更好:)

相關文章