十七、网上商城项目(3)
迪丽瓦拉
2025-06-01 09:32:11
0

本章概要

  • 商品列表
    • 商品列表项组件
    • 商品列表组件
  • 分类商品和搜索结果页面
    • Loading 组件
    • Books 组件

17.4 商品列表

商品列表页面以列表形式显示所有商品,将商品列表和商品列表项分别定义为单独的组件,商品列表组件作为父组件在其内部循环渲染商品列表项子组件。

17.4.1 商品列表项组件

在 components 目录下新建 BookLisItem.vue。如下:

BookLisItem.vue




说明:
在这里插入图片描述

to 属性使用了表达式,因此要用 v-bind 指令(这里使用的是简写语法)进行绑定。params 和 path 字段不能同时存在,如果使用了 path 字段,那么 params 将被忽略,所以这里使用命名路由。当然,也可以采用前面例子中拼接路径字符串的方式。
在这里插入图片描述

router-link 默认渲染为 a 标签,所有路由的跳转都是在当前浏览器窗口中完成的,但有时希望在新的浏览器窗口中打开目标页面,那么可以使用 target=“_blank”。但要注意,如果使用 v-slot API 定制 router-link ,将其渲染为其它标签,那么就不能使用 a 标签的target 属性,只能编写单击事件响应代码,然后通过 window.open() 方法打开一个新的浏览器窗口。
在这里插入图片描述

BookListItem 组件需要的商品数据是由父组件通过 prop 传进来的,所以这里定义了一个 item prop。
在这里插入图片描述

单击“加入购物车”按钮时,会调用 addCartItem() 方法将该商品加入购物车中,由于购物车中的商品不需要商品的定价,所以这里先计算出商品的实际价格。
在这里插入图片描述

购物车中保存的每种商品都有一个数量,通过 quantity 字段表示,在商品列表项页面中的“加入购物车”功能是一种便捷方式,商品的数量默认为 1,后面会看到商品详情页面中加入任意数量商品功能的实现。
在这里插入图片描述

在添加商品到购物车中后,路由跳转到购物车页面,这也是电商网站通常采用的方式,可以刺激用户的冲动消费。

17.4.2 商品列表组件

商品列表组件作为商品列表项组件的父组件,负责为商品列表项组件提供商品数据,并通过 v-for 指令循环渲染商品列表项组件。
在 components 目录下新建 BookList.vue 。如下:

BookList.vue


BookList 组件的代码比较简单,主要就是通过 v-for 命令循环渲染 BookListItem 子组件。某些项目的实现是在列表组件中向服务端请求数据渲染列表项,但在本项目中,BookList 组件会被多个页面复用,并且请求的数据接口是不同的,因此 BookList 组件仅仅是定义了一个 list prop 用来接收父组件传递进来的商品列表数据。

17.5 分类商品和搜索结果页面

单击某个分类链接,将跳转到分类商品页面,在该页面下,将以列表形式列出该分类下的所有商品信息;当搜索框中输入某个关键字,单击“搜索”按钮后,将跳转到搜索结果页面,在该页面下,也是以列表形式列出匹配关键字的所有商品信息。
既然这两个页面都是以列表形式显示商品信息,那么可以将他们合并为一个页面组件来实现,在该页面中无非就是根据路由的路径来动态切换页面标题,以及向服务端请求不同的数据接口。
先给出这两个页面的路由配置,编辑 router 目录下的 index.js 文件。如下:

router/index.js

...
const routes = [{path: '/',redirect: {name: 'home'}},{path: '/home',name: 'home',meta: {title: '首页'},component: Home},{path: '/category/:id',name: 'category',meta: {title: '图书分类'},component: () => import('../views/Books.vue')},{path: '/search',name: 'search',meta: {title: '搜索结果'},component: () => import('../views/Books.vue')}
]routes.afterEach((to) => {document.title = to.meta.title;
})
...

在路由配置中,采用的是延迟加载路由的方式,只有在路由到该组件时才加载。关于延时加载路由,可以参看 14.14 节。
将分类图书(/category/:id)和搜索结果(/search)的导航链接对应到同一个目标路由组件 Books 上,同时根据 14.10.1 小节介绍的知识,利用全局后置钩子来为路由跳转后的页面设置标题。

17.5.1 Loading 组件

考虑到图书列表的数据是从服务端去请求数据及网络状况的原因,图书列表的显示可能会有延迟,为此,决定编写一个 Loading 组件,在图书列表数据还没有渲染时,给用户一个提示,让用户稍安勿躁。
在 10.9 节中,已经给出了一个使用 loading 图片实现加载提示的示例,也可以沿用该示例实现加载提示。在这里换一种实现方式,考虑到图片本身加载也需要时间(虽然 loading 图片一般都很小),采用 CSS 实现 loading 加载的动画效果,这种实现在网上有很多,本项目从中找了一个实现,并将其封装为组件。
在 components 目录下新建 Loading.vue 。如下:

Loading.vue



主要代码就是 CSS 的样式规则,没必要去深究具体的实现细节,当然想研究 CSS 如何实现该种动画效果另当别论。

17.5.2 Books 组件

有了 Loading 组件,接下来就可以开始编写 Books 组件了。在 views 目录下新建 Books.vue 。如下:

views/Books.vue


说明:
在这里插入图片描述

为了控制 Loading 组件的显示与删除,定义一个数据属性 loading ,其默认值为 true,然后使用 v-if 指令进行条件判断。当成功接收到服务端发回的数据时,将数据属性 loading 设置为 false,这样 v-if 指令就会删除 Loading 组件。
在这里插入图片描述

因为分类商品和搜索结果使用的是同一个组件,但是向服务端请求的数据接口是不同的,分类商品请求的接口是 /book/category/6,而搜索请求的接口是 /search?wd=keyword,为此定义了 setRequestUrl 方法动态设置请求的接口 URL。
在这里插入图片描述

判断目标路由有多种方式,可以在导航守卫中通过 to.path 或 to.fullPath 判断,也可以使用 this.route.path 和 this.$route.fullPath 判断,如果在路由配置中使用了命名路由,还可以使用 this.route.name 判断,如本例所示。
在这里插入图片描述

在组件内导航守卫 beforeRouteEnter() 中请求初次渲染的数据,当然也可以利用 created 生命周期钩子完成相同的功能。
在这里插入图片描述

由于搜索框是独立的,用户可能会多次进行搜索行为,所以使用组件内守卫 beforeRouteUpdate() ,在组件被复用的时候再次请求数据。
在这里插入图片描述

BookList 组件所需要的数据是通过 list prop 传进去的,由于父子组件生命周期的调用时机问题,可能会出现子组件已经 mounted ,而父组件的数据才传过去,导致子组件不能正常渲染,为此可以添加一个 v-if 指令,使用列表数据的长度作为条件判断,确保子组件能正常接收到数据并渲染。在本项目使用的 Vue.js 版本和采用的实现方式下,不添加 v-if 指令也能正常工作,如果以后遇到子组件的列表数据不能正常渲染,可以试试这种解决方案。

Books 组件的渲染效果与 BookList 组件渲染的效果是类似的,只是多了一个标题,以及在没有请求到数据时给出的一个提示信息。

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
A.机器学习入门算法(三):基... 机器学习算法(三):K近邻(k-nearest neigh...
数字温湿度传感器DHT11模块... 模块实例https://blog.csdn.net/qq_38393591/article/deta...
有限元三角形单元的等效节点力 文章目录前言一、重新复习一下有限元三角形单元的理论1、三角形单元的形函数(Nÿ...
Redis 所有支持的数据结构... Redis 是一种开源的基于键值对存储的 NoSQL 数据库,支持多种数据结构。以下是...
win下pytorch安装—c... 安装目录一、cuda安装1.1、cuda版本选择1.2、下载安装二、cudnn安装三、pytorch...
MySQL基础-多表查询 文章目录MySQL基础-多表查询一、案例及引入1、基础概念2、笛卡尔积的理解二、多表查询的分类1、等...
keil调试专题篇 调试的前提是需要连接调试器比如STLINK。 然后点击菜单或者快捷图标均可进入调试模式。 如果前面...
MATLAB | 全网最详细网... 一篇超超超长,超超超全面网络图绘制教程,本篇基本能讲清楚所有绘制要点&#...
IHome主页 - 让你的浏览... 随着互联网的发展,人们越来越离不开浏览器了。每天上班、学习、娱乐,浏览器...
TCP 协议 一、TCP 协议概念 TCP即传输控制协议(Transmission Control ...
营业执照的经营范围有哪些 营业执照的经营范围有哪些 经营范围是指企业可以从事的生产经营与服务项目,是进行公司注册...
C++ 可变体(variant... 一、可变体(variant) 基础用法 Union的问题: 无法知道当前使用的类型是什...
血压计语音芯片,电子医疗设备声... 语音电子血压计是带有语音提示功能的电子血压计,测量前至测量结果全程语音播报࿰...
MySQL OCP888题解0... 文章目录1、原题1.1、英文原题1.2、答案2、题目解析2.1、题干解析2.2、选项解析3、知识点3...
【2023-Pytorch-检... (肆十二想说的一些话)Yolo这个系列我们已经更新了大概一年的时间,现在基本的流程也走走通了,包含数...
实战项目:保险行业用户分类 这里写目录标题1、项目介绍1.1 行业背景1.2 数据介绍2、代码实现导入数据探索数据处理列标签名异...
记录--我在前端干工地(thr... 这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前段时间接触了Th...
43 openEuler搭建A... 文章目录43 openEuler搭建Apache服务器-配置文件说明和管理模块43.1 配置文件说明...