效果
功能项
1. 使用Vue脚手架创建项目
2. 利用ElementUI组件库在PC端渲染列表,实现页面组件的拆分
3. 使用Mock数据来渲染表格页面
4. 数据量过大时,采用分页方式展示数据
5. 实现菜品的新增、编辑和删除功能
6. 实现菜品搜索功能,并处理搜索结果异常的情况
7. 使用插槽来渲染编号
8. 在删除操作时,需考虑关联的业务逻辑
9. 通过自定义指令来控制按钮的权限
10. 当用户多次访问导致服务器过载并限制用户登录时,如何处理?
环境配置
依赖模块
- axios
npm install axios
- mockjs
npm install mockjs
- elementUI
npm i element-ui -S
引入组件库、依赖模块
- 在main.js 中引入 elementUI 组件库
- 定义全局
axios
,挂载到Vue
实例原型上
本地服务,定义接口
在 vue.config.js 中配置
- 定义接口
- mock 模拟数据
核心功能讲解
mock 数据+前端分页
在vue.config.js
配置 devserve 服务中间件,定义表格接口,使用mock
模拟表格的数据。
vue.config.js 代码
const { defineConfig } = require('@vue/cli-service') let Mock = require('mockjs') module.exports = defineConfig({ transpileDependencies: true, devServer: { setupMiddlewares: (middlewares, devServer) => { if (!devServer) { throw new Error('webpack-dev-server is not defined'); } middlewares.unshift({ name: 'first-in-array', // `path` 是可选的 path: '/getTable', middleware: (req, res) => { // mock 模拟数据 let tableData = Mock.mock({ 'array|100':[{ "id":"@id", // 随机id "name":"@cname",//随机中文名称 "date":"@datetime",//@datetime 来生成当前日期和时间 "type|1":['show','delete','edit'], // 定义用户权限,随机抽一个 "address":"@county(true)" // 生产带有省市区的地址 }] }) res.send(tableData); }, }); return middlewares; }, }, })
页面实现
element 组件库
- Table 表格 https://element.eleme.cn/#/zh-CN/component/table
- Pagination 分页 https://element.eleme.cn/#/zh-CN/component/pagination
需要考虑特殊情况,后端返量100条数据,前端如何分页 ?
业务逻辑
- 在
data
中定义两个数组,分别存放总数据和当前页数据 - 点击分页时,从总数据中取出当前页数据
核心代码
页面模板内容
<el-table :data="currentData" style="width: 100%"> <el-table-column prop="date" label="日期" width="180"> </el-table-column> <el-table-column prop="name" label="姓名" width="180"> </el-table-column> <el-table-column prop="address" label="地址"> </el-table-column> <el-table-column label="操作"> <template slot-scope="scope"> <button type="primary">删除</button><el-button type="success">修改</el-button> </template> </el-table-column> </el-table> <el-pagination layout="prev, pager, next" :page-size="pageSize" @current-change="currentChange" :total="tableData.length"> </el-pagination>
data
数据
data(){ return { serachVal:"",// 搜索变量 pageSize:10,// 每页数量 pageNumber:1,// 当前页码 // 总数据 tableData: [], // 当前页数据 根据点击的页码,覆盖当前列表数据 currentData:[] } },
获取 table 表格数据
async mounted(){ // 访问本地服务接口 let tableData = await this.$axios("/getTable") // 后台返回的总数据 this.tableData = tableData.data.array // slice 从数组中取出数据,不改变原数据 // 参数1:起始位置(索引值) // 参数2:结束位置(索引值) // 初始化当前页数据 this.currentData = this.tableData.slice(0,10) console.log('tableData',this.tableData) },
点击分页,触发页面切换
methods:{ currentChange(data){ console.log(data) let startIndex = (data -1) * this.pageSize; // 页码数 * 每页数量获取起始值 // 起始值+10,为结束的位置 this.currentData = this.tableData.slice(startIndex,startIndex+10) } }
搜索功能
业务逻辑
前端搜索-实现逻辑
搜索框的内容 与tableData
对比,筛选出符合条件的数据,最终渲染页面
核心代码
computed 巧用计算属性
表格中数据写在计算属性中,当搜索值改变后,会重新计算获取最新的数据
computed: { gtableData() { // 获取符合搜索条件的数据 let serachArry = this.tableData.filter((item) => { // indexof 查找元素在字符串、数组中的下标位置,如果没找到返回“-1” // 通过 indexOf特性实现模糊搜索,查找的元素会返回正确下下标,否则 -1 // serachVal :前端搜索值 return item.name.indexOf(this.serachVal) !== -1 }) // 分页总长度 this.totalLength = serachArry.length; // 【获取当前页数据】 // slice 从数组中取出数据,不改变原数据 // 参数1:起始位置(索引值) // 参数2:结束位置(索引值) // 页码数 * 每页数量,获取起始值 let startIndex = (this.pageNumber - 1) * this.pageSize; return serachArry.slice(startIndex, startIndex + 10) } },
页面模板内容
<!-- 表格data属性 绑定计算属性 gtableData --> <el-table :data="gtableData" style="width: 100%"> <el-table-column prop="date" label="日期" width="180"> </el-table-column> <el-table-column prop="name" label="姓名" width="180"> </el-table-column> <el-table-column prop="address" label="地址"> </el-table-column> <el-table-column label="操作"> <template slot-scope="scope"> <button type="primary" v-btnauth="scope.row.type" @click="remove(scope.row)">删除</button> <el-button type="success" v-btnauth="scope.row.type" @click="edit(scope.row)">修改</el-button> </template> </el-table-column> </el-table>