文章目录
一、前言
之前写了一个vue后台页面的利用mockjs完成的数据获取等操作
是好久之前写的了
趁着现在要写第二个页面
就来写一篇详细地附上步骤的文章
之后用mockjs不再迷路咯
二、项目原型和大致需求
需求其实和之前的差不多
很多地方可以用CV大法过来
主要是记录一下写页面的逻辑和步骤
让下一次更容易上手
为了让涉及到的文件稍微少一些
很多其实是可以封装出去的按钮、对话框和表格
就也先写在页面中了
三、项目目录
同样,这个页面也主要在这三个文件中进行修改
路由之类的就不再叙述了
四、详细步骤
按照步骤来写的,一开始的代码到最后会稍有更改的,也可以跳过步骤,最后附上三个文件的完整代码
1、新建一个mock文件,写接口,在页面中调用拿到mock数据
vue-admin -> mock -> departments.js
const Mock = require('mockjs')
const departments = Mock.mock({
"newsList|75": [{
id: "@increment",
content: "@csentence(50)",
publish_date: "@date(yyyy-MM-dd)",
'status|1': ['启用', '禁用'],
operator: "@cname()",
operate_time: "@date(yyyy-MM-dd hh:mm:ss)",
}, ],
})
module.exports = [
// 配置模块拿数据
{
url: '/vue-admin-template/departments/list',
type: 'post',
response: config => {
console.log(config.body)
return {
code: 20000,
data: {
content: departments.newsList
}
}
}
}
]
vue-admin -> src -> api -> departments.js
import request from '@/utils/request'
// 获取科室列表
export function getDepartmentsList(data) {
return request({
url: '/vue-admin-template/departments/list',
method: 'post',
data
});
}
vue-admin -> src -> views -> departments-> Departments.vue
<template>
<div>1111</div>
</template>
<script>
import {
getDepartmentsList
} from '@/api/departments'
export default {
data() {
return {
}
},
created() {
this.getDepartmentsList()
},
methods: {
getDepartmentsList() {
getDepartmentsList({
"dckdnc": "jdbxkvb"
}).then(response => {
console.log(response.data)
})
},
}
}
</script>
<style>
</style>
代码调试1
这句话打印了mock传过来的数据
调试的时候先看页面的终端,是否拿到数据了
代码调试2
下面这句话在终端中打印了,之前从页面拿来的数据
2、获取数据,完成分页和查询功能
vue-admin -> mock -> departments.js
const Mock = require('mockjs')
const departments = Mock.mock({
"newsList|75": [{
id: "@increment",
department: "@cword(2,15)",
department_name: "@cword(2,15)",
'status|1': ['启用', '禁用'],
operator: "@cname()",
operate_time: "@date(yyyy-MM-dd hh:mm:ss)",
}, ],
})
module.exports = [
// 配置模块拿数据
{
url: '/vue-admin-template/departments/list',
type: 'post',
response: config => {
console.log(config.body)
const body = config.body
// 启用 & 禁用 & 全部 筛选
var searchDataList = []
var searchKeyList = []
var status = ''
if (body.status === '1') {
status = '启用'
} else if (body.status === '2') {
status = '禁用'
} else {
status = '全部'
}
if (status === '全部') {
searchDataList = departments.newsList
} else {
for (let i = 0; i < departments.newsList.length; i++) {
if (departments.newsList[i].status === status) {
searchDataList.push(departments.newsList[i]);
}
}
}
// 关键词搜索
if(body.searchKey === '') {
searchKeyList = searchDataList
} else {
for (let i = 0; i < searchDataList.length; i++) {
if (searchDataList[i].department.indexOf(body.searchKey) != -1) {
searchKeyList.push(searchDataList[i]);
}
}
}
// 分页
var [index, size, total] = [body.pagenum, body.pagesize, searchKeyList.length]
var len = total / size
var totalPages = len - parseInt(len) > 0 ? parseInt(len) + 1 : len
var newDataList = searchKeyList.slice((index - 1) * size, index * size)
return {
code: 20000,
data: {
pagenum: index,
pagesize: size,
content: newDataList,
total: total,
totalPages: totalPages,
}
}
}
}
]
vue-admin -> src -> api -> departments.js
import request from '@/utils/request'
// 获取科室列表
export function getDepartmentsList(data) {
return request({
url: '/vue-admin-template/departments/list',
method: 'post',
data
});
}
vue-admin -> src -> views -> departments-> Departments.vue
<template>
<div>
<!-- 卡片视图区域 -->
<el-card>
<!-- 搜索与添加区域 -->
<el-row :gutter="20">
<el-col :span="13">
<el-button type="primary" icon="el-icon-plus">新增</el-button>
</el-col>
<el-col :span="3">
<el-select v-model="value" placeholder="是否启用远程探视" @change="statusChange()">
<el-option v-for="item in options" :key="item.value"
:label="item.label" :value="item.value">
</el-option>
</el-select>
</el-col>
<el-col :span="4">
<el-input v-model="searchinput" placeholder="科室名称"></el-input>
</el-select>
</el-col>
<el-col :span="2">
<el-button type="primary" icon="el-icon-search" @click="searchKey()">查询</el-button>
</el-col>
<el-col :span="2">
<el-button type="primary" @click="reset()">重置</el-button>
</el-col>
</el-row>
<!-- 科室列表区域 -->
<el-table :header-cell-style="{textAlign: 'center'}"
:cell-style="{textAlign: 'center'}" :data="departmentList" border
stripe>
<el-table-column type="index" label="序号" width="60"></el-table-column>
<el-table-column prop="department" label="科室" width="350"></el-table-column>
<el-table-column prop="department_name" label="科室显示名称"></el-table-column>
<el-table-column prop="status" label="是否启用远程探视" width="200"></el-table-column>
<el-table-column prop="operator" label="操作人" width="150"></el-table-column>
<el-table-column prop="operate_time" label="操作时间" width="250"></el-table-column>
<el-table-column label="操作" width="240">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="mini">编辑</el-button>
<el-button type="danger" icon="el-icon-delete" size="mini">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页区域 -->
<el-pagination class="department-pagination" :current-page="queryInfo.pagenum" :page-sizes="[10, 30, 50]"
:page-size="queryInfo.pagesize" :total="queryInfo.total" layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange" @current-change="handleCurrentChange">
</el-pagination>
</el-card>
</div>
</template>
<script>
import {
getDepartmentsList
} from '@/api/departments'
export default {
data() {
return {
// 获取科室信息列表对象
queryInfo: {
// 当前的页数
pagenum: 1,
// 当前每页显示多少条数据
pagesize: 10,
// 总页数
total: 0
},
// 查询
options: [{
value: '0',
label: '全部'
}, {
value: '1',
label: '启用'
}, {
value: '2',
label: '禁用'
}],
value: '是否启用远程探视',
searchinput: '',
// 科室列表
departmentList: []
}
},
created() {
this.getDepartmentsList()
},
methods: {
getDepartmentsList() {
getDepartmentsList({
'pagenum': this.queryInfo.pagenum,
'pagesize': this.queryInfo.pagesize,
'status': this.value,
'searchKey': this.searchinput
}).then(response => {
console.log(response.data)
this.departmentList = response.data.content
this.queryInfo.pagenum = response.data.pagenum
this.queryInfo.pagesize = response.data.pagesize
this.queryInfo.total = response.data.total
})
},
// 监听 pagesize 改变的事件
handleSizeChange(val) {
this.queryInfo.pagesize = val
this.getDepartmentsList()
console.log(`每页 ${val} 条`);
},
// 监听 页码值 改变的事件
handleCurrentChange(val) {
this.queryInfo.pagenum = val
this.getDepartmentsList()
console.log(`当前页: ${val}`);
},
// 查询数据
statusChange() {
console.log(this.value)
this.getDepartmentsList()
},
searchKey() {
console.log(this.searchinput)
this.getDepartmentsList()
},
reset() {
this.value = '0',
this.searchinput = this.getDepartmentsList()
}
},
}
</script>
<style>
.el-card {
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15) !important;
}
.el-table {
margin-top: 20px;
}
.el-pagination {
margin-top: 30px;
}
</style>
Tip1
其实写这块内容的时候,我之前是遇到过坑的,而且这个坑是小白第一次自己写的话,可以说是不能避免的
大家在写获取数据的时候,一开始肯定只会写单纯的获取数据,但其实分页和查询这两块也应该是要写在获取数据的里面的,这样写会比较好,代码不会过于冗余
Tip2
查询和筛选之后,最好要写一个重置按钮
用户交互会更好一些
页面演示
3、新增、删除、编辑按钮的实现
vue-admin -> mock -> departments.js
const Mock = require('mockjs')
const departments = Mock.mock({
"newsList|75": [{
id: "@increment",
department: "@cword(2,15)",
department_name: "@cword(2,15)",
'status|1': ['启用', '禁用'],
operator: "@cname()",
operate_time: "@date(yyyy-MM-dd hh:mm:ss)",
},],
})
module.exports = [
// 配置模块拿数据
{
url: '/vue-admin-template/departments/list',
type: 'post',
response: config => {
// console.log(config.body)
const body = config.body
// 启用 & 禁用 & 全部 筛选
var searchDataList = []
var searchKeyList = []
var status = ''
if (body.status === '1') {
status = '启用'
} else if (body.status === '2') {
status = '禁用'
} else {
status = '全部'
}
if (status === '全部') {
searchDataList = departments.newsList
} else {
for (let i = 0; i < departments.newsList.length; i++) {
if (departments.newsList[i].status === status) {
searchDataList.push(departments.newsList[i]);
}
}
}
// 关键词搜索
if(body.searchKey === '') {
searchKeyList = searchDataList
} else {
for (let i = 0; i < searchDataList.length; i++) {
if (searchDataList[i].department.indexOf(body.searchKey) != -1) {
searchKeyList.push(searchDataList[i]);
}
}
}
// 分页
var [index, size, total] = [body.pagenum, body.pagesize, searchKeyList.length]
var len = total / size
var totalPages = len - parseInt(len) > 0 ? parseInt(len) + 1 : len
var newDataList = searchKeyList.slice((index - 1) * size, index * size)
return {
code: 20000,
data: {
pagenum: index,
pagesize: size,
content: newDataList,
total: total,
totalPages: totalPages,
}
}
}
},
// 科室模块新增数据
{
url: '/vue-admin-template/departments/addlist',
type: 'post',
response: config => {
console.log(config.body)
const body = config.body
departments.newsList.push(
Mock.mock({
id: "@increment",
department: body.department,
department_name: body.department_name,
status: body.status,
operator: body.operator,
operate_time: body.operate_time,
})
)
return {
code: 20000,
message: "添加成功",
data: {
content: departments,
total: departments.newsList.length,
}
}
}
},
// 通知模块删除数据
{
url: '/vue-admin-template/departments/dellist',
type: 'post',
response: config => {
// console.log(config.body)
const body = config.body
const index = departments.newsList.findIndex((item) => {
return item.id === body.id
});
departments.newsList.splice(index, 1)
// console.log(index)
return {
code: 20000,
message: "删除成功",
data: {
content: departments,
total: departments.newsList.length,
}
}
}
},
// 通知模块编辑数据
{
url: '/vue-admin-template/departments/editlist',
type: 'post',
response: config => {
// console.log(config.body)
const body = config.body
var index = departments.newsList.findIndex((item) => {
return item.id === body.id
});
departments.newsList.splice(index, 1, Mock.mock({
id: body.id,
department: body.department,
department_name: body.department_name,
status: body.status,
operator: body.operator,
operate_time: body.operate_time,
}))
// console.log(departments.newsList)
return {
code: 20000,
message: "编辑成功",
data: {
content: departments.newsList,
total: departments.newsList.length,
}
}
}
},
]
vue-admin -> src -> api -> departments.js
import request from '@/utils/request'
// 获取科室列表
export function getDepartmentsList(data) {
return request({
url: '/vue-admin-template/departments/list',
method: 'post',
data
});
}
// 新增科室列表
export function addDepartmentsList(data) {
return request({
url: '/vue-admin-template/departments/addlist',
method: 'post',
data
});
}
// 删除通告列表
export function delDepartmentsList(data) {
return request({
url: '/vue-admin-template/departments/dellist',
method: 'post',
data
});
}
// 编辑通告列表
export function editDepartmentsList(data) {
return request({
url: '/vue-admin-template/departments/editlist',
method: 'post',
data
});
}
vue-admin -> src -> views -> departments-> Departments.vue
<template>
<div>
<!-- 卡片视图区域 -->
<el-card>
<!-- 搜索与添加区域 -->
<el-row :gutter="20">
<el-col :span="13">
<el-button type="primary" icon="el-icon-plus" @click="addDialogOpen()">新增</el-button>
</el-col>
<el-col :span="3">
<el-select v-model="value" placeholder="是否启用远程探视" @change="statusChange()">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-col>
<el-col :span="4">
<el-input v-model="searchinput" placeholder="科室名称"></el-input>
</el-select>
</el-col>
<el-col :span="2">
<el-button type="primary" icon="el-icon-search" @click="searchKey()">查询</el-button>
</el-col>
<el-col :span="2">
<el-button type="primary" @click="reset()">重置</el-button>
</el-col>
</el-row>
<!-- 科室列表区域 -->
<el-table :header-cell-style="{textAlign: 'center'}" :cell-style="{textAlign: 'center'}" :data="departmentList"
border stripe>
<el-table-column type="index" label="序号" width="60"></el-table-column>
<el-table-column prop="department" label="科室" width="350"></el-table-column>
<el-table-column prop="department_name" label="科室显示名称"></el-table-column>
<el-table-column prop="status" label="是否启用远程探视" width="200"></el-table-column>
<el-table-column prop="operator" label="操作人" width="150"></el-table-column>
<el-table-column prop="operate_time" label="操作时间" width="250"></el-table-column>
<el-table-column label="操作" width="240">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="mini" @click="editContent(scope.row.id)">编辑</el-button>
<el-button type="danger" icon="el-icon-delete" size="mini" @click="delContent(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页区域 -->
<el-pagination class="department-pagination" :current-page="queryInfo.pagenum" :page-sizes="[10, 30, 50]"
:page-size="queryInfo.pagesize" :total="queryInfo.total" layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange" @current-change="handleCurrentChange">
</el-pagination>
</el-card>
<!-- 新增的对话框 -->
<el-dialog title="新增" :visible.sync="addDialogVisible" width="35%">
<!-- 内容主体区域 -->
<el-form label-width="70px">
<el-form-item label="科室">
<el-input v-model="addList.department"></el-input>
</el-form-item>
<el-form-item label="科室显示名称">
<el-input v-model="addList.department_name"></el-input>
</el-form-item>
<el-form-item label="状态">
<el-radio v-model="addList.radioSta" label="1">启用</el-radio>
<el-radio v-model="addList.radioSta" label="2">禁用</el-radio>
</el-form-item>
<el-form-item label="操作人">
<el-input v-model="addList.operator"></el-input>
</el-form-item>
</el-form>
<!-- 底部区域 -->
<span slot="footer" class="dialog-footer">
<el-button @click="addDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="addListConfirm()">确 定</el-button>
</span>
</el-dialog>
<!-- 编辑的对话框 -->
<el-dialog title="编辑订单" :visible.sync="editVisible" width="35%">
<!-- 内容主体区域 -->
<el-form label-width="70px" :model="editForm">
<el-form-item label="科室名称" label-width="130px">
<el-input v-model="editForm.department"></el-input>
</el-form-item>
<el-form-item label="是否启用远程探视" label-width="130px">
<el-radio v-model="editForm.radioEdit" label="1">启用</el-radio>
<el-radio v-model="editForm.radioEdit" label="2">禁用</el-radio>
</el-form-item>
</el-form>
<!-- 底部区域 -->
<span slot="footer" class="dialog-footer">
<el-button @click="editVisible = false">取 消</el-button>
<el-button type="primary" @click="editListConfirm()">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import {
getDepartmentsList
} from '@/api/departments'
import {
addDepartmentsList
} from '@/api/departments'
import {
editDepartmentsList
} from '@/api/departments'
import {
delDepartmentsList
} from '@/api/departments'
// 日期格式
Date.prototype.format = function(fmt) {
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, //小时
"H+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
};
export default {
data() {
return {
// 获取科室信息列表对象
queryInfo: {
// 当前的页数
pagenum: 1,
// 当前每页显示多少条数据
pagesize: 10,
// 总页数
total: 0
},
// 查询
options: [{
value: '0',
label: '全部'
}, {
value: '1',
label: '启用'
}, {
value: '2',
label: '禁用'
}],
value: '是否启用远程探视',
searchinput: '',
// 科室列表
departmentList: [],
// 添加通知对话框
addDialogVisible: false,
// 编辑操作
editVisible: false,
// 编辑对话框
editForm: {
department: '',
department_name: '',
radioEdit: '',
id: 0,
index: 0,
operate_time: '',
operator: ''
},
// 新增对话框
addList: {
department: '',
department_name: '',
radioSta: '1',
operator: ''
},
}
},
created() {
this.getDepartmentsList()
},
methods: {
getDepartmentsList() {
getDepartmentsList({
'pagenum': this.queryInfo.pagenum,
'pagesize': this.queryInfo.pagesize,
'status': this.value,
'searchKey': this.searchinput
}).then(response => {
// console.log(response.data)
this.departmentList = response.data.content
this.queryInfo.pagenum = response.data.pagenum
this.queryInfo.pagesize = response.data.pagesize
this.queryInfo.total = response.data.total
})
},
// 监听 pagesize 改变的事件
handleSizeChange(val) {
this.queryInfo.pagesize = val
this.getDepartmentsList()
console.log(`每页 ${val} 条`);
},
// 监听 页码值 改变的事件
handleCurrentChange(val) {
this.queryInfo.pagenum = val
this.getDepartmentsList()
console.log(`当前页: ${val}`);
},
// 编辑公告内容
editContent(id) {
console.log(id)
this.getDepartmentsList()
let index = this.departmentList.findIndex(item => item.id == id);
// console.log(index)
this.editForm.id = id
this.editForm.index = index
this.editVisible = true
console.log(this.departmentList)
this.editForm.department = this.departmentList[index].department
this.editForm.department_name = this.departmentList[index].department
this.editForm.operate_time = this.departmentList[index].operate_time
this.editForm.operator = this.departmentList[index].operator
this.updateEdit(index)
// console.log(this.editForm)
},
updateEdit(index) {
if (this.departmentList[index].status === '启用') {
this.editForm.radioEdit = '1'
} else {
this.editForm.radioEdit = '2'
}
},
editListConfirm() {
var status = ''
var operate_time = new Date().format('yyyy-MM-dd HH:mm:ss')
if (this.editForm.radioEdit === '1') {
status = '启用'
} else {
status = '禁用'
}
editDepartmentsList({
'department': this.editForm.department,
'department_name': this.editForm.department_name,
'status': status,
'id': this.editForm.id,
'operate_time': operate_time,
'operator': this.editForm.operator
}).then(response => {
if (response.code != 20000) {
this.$message.error('编辑公告失败!')
} else {
this.$message.success('编辑公告成功!')
}
this.departmentList = response.data.content
this.queryInfo.total = response.data.total
})
this.editVisible = false
this.getDepartmentsList()
},
// 删除公告
delContent(id) {
// console.log(id)
this.$confirm('此操作将永久删除该公告, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delDepartmentsList({
'id': id
}).then(response => {
// console.log(response.data)
})
this.getDepartmentsList()
this.$message({
type: 'success',
message: '删除成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
// 初始化新增公告对话框
addDialogOpen() {
this.addDialogVisible = true
this.addList.department = ''
this.addList.department_name = ''
this.addList.radioSta = '1'
},
// 确认新增数据
addListConfirm() {
var status = ''
var operate_time = new Date().format('yyyy-MM-dd')
if (this.addList.radioSta === '1') {
status = '启用'
} else {
status = '禁用'
}
addDepartmentsList({
'department': this.addList.department,
'department_name': this.addList.department_name,
'status': status,
'operate_time': operate_time,
'operator': this.addList.operator
}).then(response => {
if (response.code != 20000) {
this.$message.error('添加公告失败!')
} else {
this.$message.success('添加公告成功!')
}
console.log(response.data)
this.departmentList = response.data.content.newsList
this.queryInfo.total = response.data.total
})
this.addDialogVisible = false
this.getDepartmentsList()
},
// 查询数据
statusChange() {
console.log(this.value)
this.getDepartmentsList()
},
searchKey() {
console.log(this.searchinput)
this.getDepartmentsList()
},
reset() {
this.value = '0',
this.searchinput = this.getDepartmentsList()
}
},
}
</script>
<style>
.el-card {
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15) !important;
}
.el-table {
margin-top: 20px;
}
.el-pagination {
margin-top: 30px;
}
</style>
Tip1
这里要注意
点击编辑按钮后,跳出来的编辑订单框要拿到当前行的数据并显示
Tip2
在编辑按钮这里与写上一个页面有了一个小改进
因为跳出来的编辑需要显示当前的行内容
mock制造的假数据的id用了几种方法 但还是经常不从1开始
所以这里就改成先从id拿index 就不会出现拿不到数据的情况了
页面演示
五、总结
今天写这个页面的体验还是不错的
没有遇到什么bug和坑(之前该踩的基本都踩了)
觉得写项目还真的得是有大局观
也别想着一步给它写完美
加油啦!