本文主要是基于之前写过的一片博客-mock模拟分页list的基础上,用mock模拟对表格的操作
首先回顾一下mock模拟分页操作(mock引入以及安装不再赘述)
mock模拟分页list
// 引入mockjs
const Mock = require('mockjs')
// 获取 mock.Random 对象
const Random = Mock.Random
// 使用mockjs模拟数据
// 用于接受生成数据的数组
let tableList = []
for (let i = 0; i < 100; i++) {
let newObject = {
id: Random.guid(), // 获取全局唯一标识符
title: Random.csentence(5, 10), // Random.csentence( min, max )
name: Random.cname(), // Random.cname() 随机生成一个常见的中文姓名
score: Random.float(1, 100), // 随机生成1-100的浮点数
stars: Random.natural(1, 5), // 随机生成1-5的数字
url: Random.url(), // 生成web地址
city: Random.city(), // 随机生成一个城市
date: Random.date() // Random.date()指示生成的日期字符串的格式,默认为yyyy-MM-dd
// date: Random.date() + ' ' + Random.time() // Random.date()指示生成的日期字符串的格式,默认为yyyy-MM-dd;Random.time() 返回一个随机的时间字符串
}
tableList.push(newObject)
}
/** post请求分页 */
Mock.mock('/api/pageList', 'post', (params) => {
// console.log(params, '分页params')
const [index, size, total] = [JSON.parse(params.body).page, JSON.parse(params.body).size, tableList.length]
let len = total / size
// console.log(index, size, total, 'index, size, total')
const totalPages = len - parseInt(len) > 0 ? parseInt(len) + 1 : len
// 截取list
// const newProduceNewsData = tableList.slice(index * size, (index + 1) * size)
const newProduceNewsData = tableList.slice((index - 1) * size, index * size)
// console.log(newProduceNewsData, 'newProduceNewsData')
return {
code: '0',
message: 'success',
data: {
page: index,
size: size,
list: newProduceNewsData,
total: total,
totalPages: totalPages
}
}
})
前端绑定
<template>
<div>
<el-button style="margin: 0 10px 10px 10px;float: right" @click="handleBatchDelete">批量删除</el-button>
<el-button type="primary" style="margin-bottom: 10px;float: right" @click="handleAdd">添加</el-button>
<el-table :data="listData" ref="multipleTable" border :height="tableHeightCalc" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="55"></el-table-column>
<!-- 序号 -->
<el-table-column label="序号" width="50" align="center">
<template slot-scope="scope">
<span>{{( searchForm.page -1 ) * searchForm.size + scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column prop="name" label="操作人" show-overflow-tooltip>
<template slot-scope="scope">
<span class="blue_txt" @click="handleDetail(scope.row)">{{scope.row.name}}</span>
<!-- <el-button type="text" size="mini" @click="handleDetail(scope.row)">{{scope.row.name}}</el-button> -->
</template>
</el-table-column>
<el-table-column prop="score" label="分数" show-overflow-tooltip>
<template slot-scope="scope">
<span>{{scope.row.score | scoreFilter}}</span>
</template>
</el-table-column>
<el-table-column prop="stars" label="星级" show-overflow-tooltip>
<template slot-scope="scope">
<span>{{scope.row.stars | starsFilter}}</span>
</template>
</el-table-column>
<el-table-column prop="city" label="所在城市" show-overflow-tooltip></el-table-column>
<el-table-column prop="date" label="新增时间" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" show-overflow-tooltip>
<template slot-scope="scope">
<el-button type="text" size="mini" @click="handleSend(scope.row)">发送</el-button>
<el-button type="text" size="mini" @click="handleEdit(scope.row)">编辑</el-button>
<el-button type="text" size="mini" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
<el-table-column label="下拉操作">
<template slot-scope="scope">
<el-dropdown>
<span class="el-dropdown-link">下拉菜单</span>
<el-dropdown-menu slot="dropdown">
<el-row>
<el-col :span="12">
<el-dropdown-item>
<span @click="handleCheck(scope.row)">检查</span>
</el-dropdown-item>
</el-col>
<el-col :span="12">
<el-dropdown-item>
<span @click="handleLock(scope.row)">锁定</span>
</el-dropdown-item>
</el-col>
</el-row>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<el-row style="background-color: #f8f8f9;">
<el-col :span="6">
<p>累积分数:{{totalScore}}</p>
</el-col>
<el-col :span="18">
<div class="paginationBox">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="searchForm.page"
:page-sizes="[15, 30, 50]"
:page-size="searchForm.size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
</el-col>
</el-row>
<!-- 发送人员组件 -->
<member-send ref="sendDialog" :member-list="listData" @memSend="afterSend"></member-send>
<!-- 添加数据组件 -->
<add-data ref="addDialog" @addData="afterAdd"></add-data>
<!-- 编辑数据组件 -->
<edit-data ref="editDialog" :edit-data="rowData" @editData="afterEdit"></edit-data>
</div>
</template>
调用接口获取list
注意axios引用
import axios from 'axios'
/** 获取表格list */
getList () {
axios.post('/api/pageList', this.searchForm)
.then(res => {
// console.log(res, 'res')
this.listData = res.data.data.list
this.total = res.data.data.total
console.log(this.listData, 'list')
})
.catch(err => {
console.log(err)
})
},
效果
下面是list操作部分,具体来说就是增、删、改、批量删除,其实我这里就是主要对列表数组进行操作,然后通过模拟接口返回
mock模拟添加数据
mock部分
/** post请求增加表格数据 */
Mock.mock('/api/pageList/add', 'post', (params) => {
// console.log(params, '增加数据params')
let time1 = new Date()
time1.setTime(time1.getTime())
let Y1 = time1.getFullYear()
let M1 = ((time1.getMonth() + 1) >= 10 ? (time1.getMonth() + 1) : '0' + (time1.getMonth() + 1))
let D1 = (time1.getDate() >= 10 ? time1.getDate() : '0' + time1.getDate())
let timer1 = Y1 + '-' + M1 + '-' + D1 // 当前时间
let newData = JSON.parse(params.body)
newData.id = Random.guid()
newData.date = timer1
// console.log(newData, 'newData')
tableList.push(newData)
return {
code: '0',
message: 'success',
data: []
}
})
主要是将页面传来的数据推入当前列表数组,然后添加了当前的时间
vue部分
这部分用的组件
<!-- 添加数据组件 -->
<add-data ref="addDialog" @addData="afterAdd"></add-data>
/** 添加数据 */
handleAdd () {
this.$refs.addDialog.addVisible = true
},
/** 添加数据后的回调 */
afterAdd () {
this.getList()
},
添加数据组件
<template>
<div>
<el-dialog title="新增数据" :visible.sync="addVisible" width="30%" @close="handleCancelDialog" :close-on-click-modal="false">
<el-row type="flex" justify="center">
<el-col>
<el-form :model="addForm" :rules="rules" ref="addForm" label-width="80px" :label-position="labelPosition">
<el-form-item label="操作人" size="large" prop="name">
<el-input v-model="addForm.name" placeholder="请输入操作人"/>
</el-form-item>
<el-form-item label="分数" size="large" prop="score">
<el-input v-model="addForm.score" placeholder="请输入分数"/>
</el-form-item>
<el-form-item label="星级" size="large" prop="stars">
<el-input v-model="addForm.stars" placeholder="请输入星级"/>
</el-form-item>
<el-form-item label="所在城市" size="large" prop="city">
<el-input v-model="addForm.city" placeholder="请输入所在城市"/>
</el-form-item>
</el-form>
</el-col>
</el-row>
<span slot="footer" class="dialog-footer">
<el-button type="primary" size="medium" @click="handleConfirm">确认</el-button>
<el-button type="plain" size="medium" @click="addVisible = false">取消</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import axios from 'axios'
import { floatNumValid } from '@/assets/js/rulesValid'
export default {
data () {
return {
labelPosition: 'right',
addVisible: false,
addForm: {
name: '',
score: '',
stars: '',
city: ''
},
rules: {
name: [
{ required: true, message: '请输入操作人', trigger: 'blur' }
],
score: [
{ required: true, validator: floatNumValid, trigger: 'blur' }
],
stars: [
{ required: true, validator: floatNumValid, trigger: 'blur' }
],
city: [
{ required: true, message: '请输入所在城市', trigger: 'blur' }
]
}
}
},
mounted () {
},
methods: {
handleCancelDialog () {
this.addVisible = false
this.$refs.addForm.resetFields()
},
handleConfirm () {
this.$refs.addForm.validate(valid => {
if (valid) {
this.addForm.score = Number(this.addForm.score)
axios.post('/api/pageList/add', this.addForm)
.then(res => {
// console.log(res, '添加res')
if (res.data.code === '0') {
this.$message.success('添加成功')
this.$emit('addData')
this.addVisible = false
}
})
.catch(err => {
console.log(err)
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
/deep/ .el-form-item__label {
text-align: left;
}
/deep/ .el-dialog__header {
padding: 20px 20px 12px 20px
}
/deep/ .el-dialog__body {
padding: 32px 40px 10px 40px;
}
/deep/ .el-dialog__footer {
padding-top: 0px;
}
</style>
效果
mock模拟编辑数据
mock部分
/** post请求编辑表格数据 */
Mock.mock('/api/pageList/edit', 'post', (params) => {
// console.log(params, '编辑数据params')
let editObj = JSON.parse(params.body)
// console.log(editObj, 'newData')
tableList.forEach(item => {
if (item.id === editObj.id) {
item.name = editObj.name
item.score = editObj.score
item.stars = editObj.stars
item.city = editObj.city
}
})
return {
code: '0',
message: 'success',
data: []
}
})
vue部分
<!-- 编辑数据组件 -->
<edit-data ref="editDialog" :edit-data="rowData" @editData="afterEdit"></edit-data>
/** 编辑 */
handleEdit (row) {
this.$refs.editDialog.editVisible = true
this.rowData = row
},
/** 编辑数据后的回调 */
afterEdit () {
this.getList()
},
编辑组件
<template>
<div>
<el-dialog title="编辑数据" :visible.sync="editVisible" width="30%" @close="handleCancelDialog" :close-on-click-modal="false">
<el-row type="flex" justify="center">
<el-col>
<el-form :model="editForm" :rules="rules" ref="editForm" label-width="80px" :label-position="labelPosition">
<el-form-item label="操作人" size="large" prop="name">
<el-input v-model="editForm.name" placeholder="请输入操作人"/>
</el-form-item>
<el-form-item label="分数" size="large" prop="score">
<el-input v-model="editForm.score" placeholder="请输入分数"/>
</el-form-item>
<el-form-item label="星级" size="large" prop="stars">
<el-input v-model="editForm.stars" placeholder="请输入星级"/>
</el-form-item>
<el-form-item label="所在城市" size="large" prop="city">
<el-input v-model="editForm.city" placeholder="请输入所在城市"/>
</el-form-item>
</el-form>
</el-col>
</el-row>
<span slot="footer" class="dialog-footer">
<el-button type="primary" size="medium" @click="handleConfirm">确认</el-button>
<el-button type="plain" size="medium" @click="editVisible = false">取消</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import axios from 'axios'
import { floatNumValid } from '@/assets/js/rulesValid'
export default {
props: {
editData: {
type: ''
}
},
data () {
return {
labelPosition: 'right',
editVisible: false,
editForm: {
name: '',
score: '',
stars: '',
city: ''
},
rules: {
name: [
{ required: true, message: '请输入操作人', trigger: 'blur' }
],
score: [
{ required: true, validator: floatNumValid, trigger: 'blur' }
],
stars: [
{ required: true, validator: floatNumValid, trigger: 'blur' }
],
city: [
{ required: true, message: '请输入所在城市', trigger: 'blur' }
]
}
}
},
mounted () {
},
watch: {
editVisible: {
handler (visible) {
if (visible) {
// console.log(this.editData, 'editData')
this.editForm = this.editData
}
},
immediate: true,
deep: true
}
},
methods: {
handleCancelDialog () {
this.editVisible = false
this.$refs.editForm.resetFields()
},
handleConfirm () {
this.$refs.editForm.validate(valid => {
if (valid) {
this.editForm.score = Number(this.editForm.score)
axios.post('/api/pageList/edit', this.editForm)
.then(res => {
// console.log(res, '编辑res')
if (res.data.code === '0') {
this.$message.success('编辑成功')
this.$emit('editData')
this.editVisible = false
}
})
.catch(err => {
console.log(err)
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
/deep/ .el-form-item__label {
text-align: left;
}
/deep/ .el-dialog__header {
padding: 20px 20px 12px 20px
}
/deep/ .el-dialog__body {
padding: 32px 40px 10px 40px;
}
/deep/ .el-dialog__footer {
padding-top: 0px;
}
</style>
效果
新增和编辑都运用的组件,在成功有有个回调,注意调用分页列表接口,更新列表
mock模拟删除
mock部分
/** post请求删除表格数据 */
Mock.mock('/api/pageList/delete', 'post', (params) => {
let deleteObj = JSON.parse(params.body)
let deleteId = deleteObj.id
// console.log(deleteId, 'deleteId')
tableList = tableList.filter(val => val.id !== deleteId)
return {
code: '0',
message: 'success',
data: []
}
})
vue部分
/** 删除 */
handleDelete (row) {
console.log(row, 'row')
this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/api/pageList/delete', row)
.then(res => {
if (res.data.code === '0') {
this.$message.success('删除成功!')
this.getList()
}
})
.catch(err => {
console.log(err)
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
mock模拟批量删除
mock部分
/** post请求批量删除表格数据 */
Mock.mock('/api/pageList/batchDelete', 'post', (params) => {
console.log(params, '批量删除传参')
let deleteArr = JSON.parse(params.body)
console.log(deleteArr, 'deleteArr')
tableList = tableList.filter(val => !deleteArr.includes(val.id))
return {
code: '0',
message: 'success',
data: []
}
})
vue部分
/** 批量删除 */
handleBatchDelete () {
// console.log(this.multipleSelection, 'multipleSelection')
if (this.multipleSelection.length <= 0) {
this.$message({
type: 'warning',
message: '请至少勾选一条数据',
showClose: true
})
return
}
let ids = []
this.multipleSelection.forEach(item => {
ids.push(item.id)
})
// console.log(ids, 'ids')
this.$confirm('此操作将永久批量删除选择数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/api/pageList/batchDelete', ids)
.then(res => {
if (res.data.code === '0') {
this.$message.success('批量删除成功!')
this.getList()
}
})
.catch(err => {
console.log(err)
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
删除部分主要是拿到数据id进行数组过滤进行操作
下面附上列表页面全部代码
<template>
<div>
<el-button style="margin: 0 10px 10px 10px;float: right" @click="handleBatchDelete">批量删除</el-button>
<el-button type="primary" style="margin-bottom: 10px;float: right" @click="handleAdd">添加</el-button>
<el-table :data="listData" ref="multipleTable" border :height="tableHeightCalc" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="55"></el-table-column>
<!-- 序号 -->
<el-table-column label="序号" width="50" align="center">
<template slot-scope="scope">
<span>{{( searchForm.page -1 ) * searchForm.size + scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column prop="name" label="操作人" show-overflow-tooltip>
<template slot-scope="scope">
<span class="blue_txt" @click="handleDetail(scope.row)">{{scope.row.name}}</span>
<!-- <el-button type="text" size="mini" @click="handleDetail(scope.row)">{{scope.row.name}}</el-button> -->
</template>
</el-table-column>
<el-table-column prop="score" label="分数" show-overflow-tooltip>
<template slot-scope="scope">
<span>{{scope.row.score | scoreFilter}}</span>
</template>
</el-table-column>
<el-table-column prop="stars" label="星级" show-overflow-tooltip>
<template slot-scope="scope">
<span>{{scope.row.stars | starsFilter}}</span>
</template>
</el-table-column>
<el-table-column prop="city" label="所在城市" show-overflow-tooltip></el-table-column>
<el-table-column prop="date" label="新增时间" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" show-overflow-tooltip>
<template slot-scope="scope">
<el-button type="text" size="mini" @click="handleSend(scope.row)">发送</el-button>
<el-button type="text" size="mini" @click="handleEdit(scope.row)">编辑</el-button>
<el-button type="text" size="mini" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
<el-table-column label="下拉操作">
<template slot-scope="scope">
<el-dropdown>
<span class="el-dropdown-link">下拉菜单</span>
<el-dropdown-menu slot="dropdown">
<el-row>
<el-col :span="12">
<el-dropdown-item>
<span @click="handleCheck(scope.row)">检查</span>
</el-dropdown-item>
</el-col>
<el-col :span="12">
<el-dropdown-item>
<span @click="handleLock(scope.row)">锁定</span>
</el-dropdown-item>
</el-col>
</el-row>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<el-row style="background-color: #f8f8f9;">
<el-col :span="6">
<p>累积分数:{{totalScore}}</p>
</el-col>
<el-col :span="18">
<div class="paginationBox">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="searchForm.page"
:page-sizes="[15, 30, 50]"
:page-size="searchForm.size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
</el-col>
</el-row>
<!-- 发送人员组件 -->
<member-send ref="sendDialog" :member-list="listData" @memSend="afterSend"></member-send>
<!-- 添加数据组件 -->
<add-data ref="addDialog" @addData="afterAdd"></add-data>
<!-- 编辑数据组件 -->
<edit-data ref="editDialog" :edit-data="rowData" @editData="afterEdit"></edit-data>
</div>
</template>
<script>
import axios from 'axios'
import commonFuc from '../commonFuc'
import tableHeightMixin from '@/assets/js/tableHeightMixin'
import { tableHeightCalc } from '@/assets/js/common'
import memberSend from '../component/memberSend'
import addData from '../component/addData'
import editData from '../component/editData'
export default {
name: 'multiTable',
mixins: [commonFuc, tableHeightMixin],
components: { memberSend, addData, editData },
data () {
return {
listData: [],
rowData: '',
searchForm: {
page: 1,
size: 15
},
total: 0
}
},
mounted () {
this.getList()
},
methods: {
/** 计算表格高度 */
_tableHeightCalc () {
return tableHeightCalc()
},
/** 获取表格list */
getList () {
axios.post('/api/pageList', this.searchForm)
.then(res => {
// console.log(res, 'res')
this.listData = res.data.data.list
this.total = res.data.data.total
console.log(this.listData, 'list')
})
.catch(err => {
console.log(err)
})
},
/** 发送 */
handleSend () {
this.$refs.sendDialog.sendVisible = true
},
/** 发送成功后的回调 */
afterSend () {
// console.log('发送成功回调')
},
/** 添加数据 */
handleAdd () {
this.$refs.addDialog.addVisible = true
},
/** 添加数据后的回调 */
afterAdd () {
this.getList()
},
/** 编辑 */
handleEdit (row) {
this.$refs.editDialog.editVisible = true
this.rowData = row
},
/** 编辑数据后的回调 */
afterEdit () {
this.getList()
},
/** 删除 */
handleDelete (row) {
console.log(row, 'row')
this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/api/pageList/delete', row)
.then(res => {
if (res.data.code === '0') {
this.$message.success('删除成功!')
this.getList()
}
})
.catch(err => {
console.log(err)
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
/** 批量删除 */
handleBatchDelete () {
// console.log(this.multipleSelection, 'multipleSelection')
if (this.multipleSelection.length <= 0) {
this.$message({
type: 'warning',
message: '请至少勾选一条数据',
showClose: true
})
return
}
let ids = []
this.multipleSelection.forEach(item => {
ids.push(item.id)
})
// console.log(ids, 'ids')
this.$confirm('此操作将永久批量删除选择数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/api/pageList/batchDelete', ids)
.then(res => {
if (res.data.code === '0') {
this.$message.success('批量删除成功!')
this.getList()
}
})
.catch(err => {
console.log(err)
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
/** 检查 */
handleCheck () {
const confirmText = ['每条数据只能检测三次', '确认检查吗?']
const newDatas = []
const h = this.$createElement
for (const i in confirmText) {
newDatas.push(h('p', null, confirmText[i]))
}
this.$confirm('', '提示', {
message: h('div', null, newDatas),
confirmButtonText: '确定',
type: 'warning'
}).then(() => {
this.$message.success('检查成功!')
}).catch(() => {
this.$message({
type: 'info',
message: '已取消检查'
})
})
},
/** 锁定 */
handleLock () {
this.confirmTitle = '该条数据为默认数据'
const confirmText = '确定进行锁定吗?'
const h = this.$createElement
this.$msgbox({
title: '锁定',
message: h('p', null, [
h('p', null, this.confirmTitle),
// 对第二行单独设置样式
h('p', { style: 'background-color: #f4f9ff;width:100%;margin-top: 10px' }, confirmText)
]),
showCancelButton: true,
confirmButtonText: '确定',
cancelButtonText: '取消',
customClass: 'message_style',
// 可以选择没有tpye,则没有感叹号图标
type: 'warning'
}).then(() => {
this.$message.success('锁定成功!')
}).catch(() => {
this.$message({
type: 'info',
message: '已取消锁定'
})
})
},
/** 跳转详情 */
handleDetail (row) {
this.$router.push({name: 'memberDetail', query: {userDetail: JSON.stringify(row)}})
}
}
}
</script>
<style lang='scss' scoped>
.el-dropdown-link {
cursor: pointer;
color: #409EFF;
}
.el-dropdown-menu__item{
color: #409EFF;
font-size: 12px;
}
.el-dropdown-menu__item:focus,
.el-dropdown-menu__item:not(.is-disabled):hover {
background-color: #fff;
}
.blue_txt {
cursor: pointer;
color: #409EFF;
}
</style>
<style lang="scss">
.message_style {
width: 30%;
background-color: #EBEEF5;
}
</style>