vue项目:商品列表页的渲染,删除,搜索,面包屑导航

简介: vue项目:商品列表页的渲染,删除,搜索,面包屑导航

页面效果:

目标做一个这样子的页面如何去做

前提:导入了element ui,本文章没有体现到编辑商品和添加商品,你需要有自己的后端接口文档你可以拿我的作为一个参考

1.面包屑导航

直接引用组件ui里面的模板就好了一键搞定

1. <!-- 面包屑导航区域 -->
2. <el-breadcrumb separator="/">
3. <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
4. <el-breadcrumb-item><a>商品管理</a></el-breadcrumb-item>
5. <el-breadcrumb-item>商品列表</el-breadcrumb-item>
6. </el-breadcrumb>

路由设置根据自己的需求来

2.搜索框一栏

我们需要用到了卡片视图就是el-card,将内容放在卡片里面

1. <el-card>
2. <el-row :gutter="20">
3. <el-col :span="8">
4. <el-input placeholder="请输入内容" v-model="queryInfo.query" clearable>
5. <el-button slot="append" icon="el-icon-search" @click="getGoodsList"></el-button>
6. </el-input>
7. </el-col>
8. <el-col :span="4">
9. <el-button type="primary" @click="goAddpage">添加商品</el-button>
10. </el-col>
11. </el-row>
12. <el-card>

:gutter="20"属性设置列之间的间距为20像素。

(Element UI 中,网格系统使用了 24 列的布局,每个列的宽度相等。)

`:span="8"` 表示当前的 `el-col` 组件将占据网格系统中的 8 列。

v-model是双向绑定文本输入框输入的数据存放到data中

clearable 属性表示输入框右侧会显示一个清除按钮。

slot="append"表示搜索按钮在输入框的右边

icon="el-icon-search"是搜索按钮图标

@click="getGoodsList"搜索商品的点击事件

以下本页面中的data数据

1. data() {
2. return {
3. // 获取商品列表的参数对象
4. queryInfo: {
5. query: '',
6. // 当前的页数
7. pagenum: 1,
8. // 当前页显示多少条数据
9. pagesize: 5,
10.             },
11. // 商品列表数组
12. goodsList: [],
13. // 数据条数
14. total: 0
15.         };

搜索就是依靠绑定信息后利用信息进行发起请求进行渲染商品列表

3.商品列表区域

1. <!-- 商品列表区域 -->
2. <el-table :data="goodsList" border stripe>
3. <el-table-column type="index" label="序号"></el-table-column>
4. <el-table-column label="商品名称" prop="goods_name"></el-table-column>
5. <el-table-column label="商品价格(元)" prop="goods_price"></el-table-column>
6. <el-table-column label="商品重量" prop="goods_weight"></el-table-column>
7. <el-table-column label="创建时间" prop="add_time">
8. <template slot-scope="scope">
9.             {{ scope.row.add_time | dateFormat }}
10. </template>
11. </el-table-column>
12. <el-table-column label="操作">
13. <template slot-scope="scope">
14. <el-button type="primary" icon="el-icon-edit" size="mini"
15.                 @click="showEditDialog(scope.row.attr_id)">编辑</el-button>
16. <el-button type="danger" icon="el-icon-delete" size="mini"
17.                 @click="removeById(scope.row.goods_id)">删除</el-button>
18. </template>
19. </el-table-column>
20. </el-table>

:data="goodsList"这个是绑定数据源

border:添加表格边框。

stripe:为表格的行添加斑马纹效果,交替显示不同的背景颜色。

type="index":指定列的类型为序号列,自动生成每一行的序号。

label="序号":设置该列的标题为 "序号"。label是列的名称

prop="goods_name":指定该列从数据源中获取的属性名称为 goods_name,表示该列要显示商品的名称。prop就是从绑定的数据源里面获取数据然后渲染

<template slot-scope="scope">:使用插槽方式定义列的内容,slot-scope="scope" 表示可以访问列数据的上下文。这个就是作用域插槽

{{ scope.row.add_time | dateFormat }}:在插槽中,使用 scope.row.add_time 获取当前行的 add_time 属性,并应用 dateFormat 过滤器对时间进行格式化。

因为我这个后端获取到数据的时间是一串数字所以针对时间加一个全局的时间过滤器进行渲染

type="primary":设置按钮类型为主要类型。

icon="el-icon-edit":设置按钮的图标为编辑图标。

size="mini":设置按钮的大小为迷你型。

@click="showEditDialog(scope.row.attr_id)":绑定按钮的点击事件,当按钮被点击时,会触发 Vue 实例中的 showEditDialog 方法,并传入当前行的 attr_id 属性作为参数。

@click="removeById(scope.row.goods_id)":绑定按钮的点击事件,当按钮被点击时,会触发 Vue 实例中的 removeById 方法,并传入当前行的 goods_id 属性作为参数。

在main.js注册

1. // 全局注册时间过滤器
2. Vue.filter('dateFormat',function(originVal){
3. const dt=new Date(originVal)
4. const y=dt.getFullYear()
5. const m=(dt.getMonth()+1+'').padStart(2,'0')
6. const d=(dt.getDate()+'').padStart(2,'0')
7. const hh=(dt.getHours()+'').padStart(2,'0')
8. const mm=(dt.getMinutes()+'').padStart(2,'0')
9. const ss=(dt.getSeconds()+'').padStart(2,'0')
10. // return `yyyy-mm-dd hh:mm:ss`
11. return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
12. })

在mian.js写好了全局的时间过滤器之后再到页面写作用域插槽

商品列表是向后端发起请求获取商品数据然后渲染到表格中

我这里的后端接口文档是

响应数据是:

1. {
2. "data": {
3. "total": 50,
4. "pagenum": "1",
5. "goods": [
6.             {
7. "goods_id": 144,
8. "goods_name": "asfdsd",
9. "goods_price": 1,
10. "goods_number": 1,
11. "goods_weight": 1,
12. "goods_state": null,
13. "add_time": 1512954923,
14. "upd_time": 1512954923,
15. "hot_mumber": 0,
16. "is_promote": false
17.             }
18.         ]
19.     },
20. "meta": {
21. "msg": "获取成功",
22. "status": 200
23.     }
24. }

所以我需要写的后端发起请求是:

首先这里还需要注意因为你打开页面就是需要有数据的所以你需要在开始出现页面的时候就调用请求数据的函数

1. created() {
2. // 根据分页获取对应的商品列表
3. this.getGoodsList()
4. },

然后在methods里面写请求函数

1. // 根据分页请求数据
2. async getGoodsList() {
3. const { data: res } = await this.$http.get('goods', { params: this.queryInfo })
4. if (res.meta.status !== 200) return this.$message.error('获取商品列表失败')
5. // console.log(res.data);
6. this.goodsList = res.data.goods
7. this.total = res.data.total
8. },

async和awit是异步操作,具体可以看我前一天的文章http://t.csdn.cn/RerDO

然后结构赋值然后将获取的数组赋值到我在data中创建的goodslist渲染表格还有获取总数据条数存放到total中渲染分页区域

4.分页区域

1. <!--分页区域  -->
2. <el-pagination @size-change="handleSizeChange" 
3. @current-change="handleCurrentChange"
4. :current-page="queryInfo.pagenum"
5. :page-sizes="[5, 10, 15, 20]"
6. :page-size="queryInfo.pagesize"
7. layout="total, sizes, prev, pager, next, jumper" :total="total" background>
8. </el-pagination>

@size-change="handleSizeChange":当每页显示条数发生变化时,触发 handleSizeChange 方法。

@current-change="handleCurrentChange":当当前页码发生变化时,触发 handleCurrentChange 方法。

:current-page="queryInfo.pagenum":绑定当前页码的值为 queryInfo.pagenum,即当前页码的变量值。

:page-sizes="[5, 10, 15, 20]":设置可选择的每页显示条数选项为 5、10、15 和 20。

:page-size="queryInfo.pagesize":绑定每页显示条数的值为 queryInfo.pagesize,即每页显示条数的变量值。

layout="total, sizes, prev, pager, next, jumper":设置分页组件的布局,具体含义如下:

total:显示总条数。

sizes:显示可选择的每页显示条数选项。

prev:显示上一页按钮。

pager:显示页码按钮。

next:显示下一页按钮。

jumper:显示跳转到指定页码的输入框和确定按钮。

:total="total":绑定总条数的值为 total,即总条数的变量值。

background:设置分页组件的背景为透明背景。

1. //在分页区域中监听页面pagesize改变的事件
2. handleSizeChange(newSize) {
3. // 这里就是根据修改 几条/页 切换之后重新请求
4. this.queryInfo.pagesize = newSize
5. this.getGoodsList()
6. },
7. // 监听页码值改变的事件
8. handleCurrentChange(newPage) {
9. // console.log(newPage)
10. // 这里就是监听到了页码改变然后重新请求这个页码中的x页数据
11. this.queryInfo.pagenum = newPage
12. this.getGoodsList()
13. },

5.删除商品

在操作区域的删除按钮中加入这个点击事件@click="removeById(scope.row.goods_id)然后写删除的请求,为了防止误删给用户添加了应该消息提示框让用户确认是否删除

我这里的弹框提示做了挂载在element.js中

1. import  MessageBox from 'element-ui'
2. // 挂载一个弹框提示的组件
3. Vue.prototype.$confirm=  MessageBox.confirm

然后就是删除的页面的交互

1. // 弹出消息提示框是否删除
2. async removeById(id) {
3. // 弹框询问用户是否删除数据
4. const confirmResult = await this.$confirm('此操作将永久删除该商品, 是否继续?', '提示', {
5. confirmButtonText: '确定',
6. cancelButtonText: '取消',
7. type: 'warning'
8.     }).catch(err => err)
9. // 如果用户确认删除,则返回值为字符串confirm
10. // 如果用户取消了删除,则返回的字符串为cancel
11. if (confirmResult !== 'confirm') { return this.$message.info('已经取消删除') }
12. // const { data: res } = await this.$http.delete(`goods/${id}` )
13. const { data: res } = await this.$http.delete('goods/' + id)
14. if (res.meta.status !== 200) { return this.$message.error('删除商品失败!') }
15. this.$message.success('删除商品成功!')
16. // 刷新重新获取商品列表
17. this.getGoodsList()
18. },

6.整个页面的代码:

1. <template>
2. <div>
3. <!-- 面包屑导航区域 -->
4. <el-breadcrumb separator="/">
5. <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
6. <el-breadcrumb-item><a>商品管理</a></el-breadcrumb-item>
7. <el-breadcrumb-item>商品列表</el-breadcrumb-item>
8. </el-breadcrumb>
9. 
10. <!-- 卡片视图区域 -->
11. <el-card>
12. <el-row :gutter="20">
13. <el-col :span="8">
14. <el-input placeholder="请输入内容" v-model="queryInfo.query" clearable>
15. <el-button slot="append" icon="el-icon-search" @click="getGoodsList"></el-button>
16. </el-input>
17. </el-col>
18. <el-col :span="4">
19. <el-button type="primary" @click="goAddpage">添加商品</el-button>
20. </el-col>
21. </el-row>
22. 
23. <!-- 商品列表区域 -->
24. <el-table :data="goodsList" border stripe>
25. <el-table-column type="index" label="序号"></el-table-column>
26. <el-table-column label="商品名称" prop="goods_name"></el-table-column>
27. <el-table-column label="商品价格(元)" prop="goods_price"></el-table-column>
28. <el-table-column label="商品重量" prop="goods_weight"></el-table-column>
29. <el-table-column label="创建时间" prop="add_time">
30. <template slot-scope="scope">
31.                         {{ scope.row.add_time | dateFormat }}
32. </template>
33. </el-table-column>
34. <el-table-column label="操作">
35. <template slot-scope="scope">
36. <el-button type="primary" icon="el-icon-edit" size="mini"
37.                             @click="showEditDialog(scope.row.attr_id)">编辑</el-button>
38. <el-button type="danger" icon="el-icon-delete" size="mini"
39.                             @click="removeById(scope.row.goods_id)">删除</el-button>
40. </template>
41. </el-table-column>
42. </el-table>
43. 
44. <!--分页区域  -->
45. <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
46. :current-page="queryInfo.pagenum" :page-sizes="[5, 10, 15, 20]" :page-size="queryInfo.pagesize"
47. layout="total, sizes, prev, pager, next, jumper" :total="total" background>
48. </el-pagination>
49. </el-card>
50. 
51. 
52. 
53. 
54. </div>
55. </template>
56. 
57. <script>
58. export default {
59. name: 'VueShopListComponent',
60. 
61. data() {
62. return {
63. // 获取商品列表的参数对象
64. queryInfo: {
65. query: '',
66. // 当前的页数
67. pagenum: 1,
68. // 当前页显示多少条数据
69. pagesize: 5,
70.             },
71. // 商品列表数组
72. goodsList: [],
73. // 数据条数
74. total: 0
75.         };
76.     },
77. created() {
78. // 根据分页获取对应的商品列表
79. this.getGoodsList()
80.     },
81. mounted() {
82. 
83.     },
84. 
85. methods: {
86. // 根据分页请求数据
87. async getGoodsList() {
88. const { data: res } = await this.$http.get('goods', { params: this.queryInfo })
89. if (res.meta.status !== 200) return this.$message.error('获取商品列表失败')
90. // console.log(res.data);
91. this.goodsList = res.data.goods
92. this.total = res.data.total
93.         },
94. //在分页区域中监听页面pagesize改变的事件
95. handleSizeChange(newSize) {
96. // 这里就是根据修改 几条/页 切换之后重新请求
97. this.queryInfo.pagesize = newSize
98. this.getGoodsList()
99.         },
100. // 监听页码值改变的事件
101. handleCurrentChange(newPage) {
102. // console.log(newPage)
103. // 这里就是监听到了页码改变然后重新请求这个页码中的x页数据
104. this.queryInfo.pagenum = newPage
105. this.getGoodsList()
106.         },
107. // 弹出消息提示框是否删除
108. async removeById(id) {
109. // 弹框询问用户是否删除数据
110. const confirmResult = await this.$confirm('此操作将永久删除该商品, 是否继续?', '提示', {
111. confirmButtonText: '确定',
112. cancelButtonText: '取消',
113. type: 'warning'
114.             }).catch(err => err)
115. // 如果用户确认删除,则返回值为字符串confirm
116. // 如果用户取消了删除,则返回的字符串为cancel
117. if (confirmResult !== 'confirm') { return this.$message.info('已经取消删除') }
118. // const { data: res } = await this.$http.delete(`goods/${id}` )
119. const { data: res } = await this.$http.delete('goods/' + id)
120. if (res.meta.status !== 200) { return this.$message.error('删除商品失败!') }
121. this.$message.success('删除商品成功!')
122. // 刷新重新获取商品列表
123. this.getGoodsList()
124.         },
125. // 添加商品,路由跳转访问添加商品页面
126. goAddpage(){
127. this.$router.push('/home/goods/add')
128.         }
129.     },
130. };
131. </script>
132. 
133. <style lang="less" scoped></style>


相关文章
|
9天前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
|
1月前
|
JavaScript API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
1月前
|
JavaScript 前端开发 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
1月前
|
存储 JavaScript 前端开发
介绍一下Vue的核心功能
介绍一下Vue的核心功能
|
7月前
|
JavaScript API
【vue实战项目】通用管理系统:api封装、404页
【vue实战项目】通用管理系统:api封装、404页
81 3
|
7月前
|
人工智能 JavaScript 前端开发
毕设项目-基于Springboot和Vue实现蛋糕商城系统(三)
毕设项目-基于Springboot和Vue实现蛋糕商城系统
|
7月前
|
JavaScript Java 关系型数据库
毕设项目-基于Springboot和Vue实现蛋糕商城系统(一)
毕设项目-基于Springboot和Vue实现蛋糕商城系统
197 0
|
7月前
|
JavaScript 前端开发 API
Vue3+Vite+TypeScript常用项目模块详解
现在无论gitee还是github,越来越多的前端开源项目采用Vue3+Vite+TypeScript+Pinia+Elementplus+axios+Sass(css预编译语言等),其中还有各种项目配置比如eslint 校验代码工具配置等等,而我们想要进行前端项目的二次开发,就必须了解会使用这些东西,所以作者写了这篇文章进行简单的介绍。
154 0
Vue3+Vite+TypeScript常用项目模块详解
|
7月前
|
设计模式 JavaScript
探索 Vue Mixin 的世界:如何轻松复用代码并提高项目性能(上)
探索 Vue Mixin 的世界:如何轻松复用代码并提高项目性能(上)
探索 Vue Mixin 的世界:如何轻松复用代码并提高项目性能(上)
|
7月前
|
前端开发 JavaScript Java
毕业设计|基于SpringBoot+Vue的科研课题项目管理系统
毕业设计|基于SpringBoot+Vue的科研课题项目管理系统
203 1

热门文章

最新文章