vue3 之 商城项目—一级分类

整体认识和路由配置

在这里插入图片描述
场景:点击哪个分类跳转到对应的路由页面,路由传对应的参数

router/index.js

import { createRouter, createWebHashHistory } from 'vue-router'
import Layout from '@/views/Layout/index.vue'
import Home from '@/views/Home/index.vue'
import Category from '@/views/Category/index.vue'
const router = createRouter({history: createWebHashHistory(import.meta.env.BASE_URL),routes: [{path: '/',name: 'layout',component: Layout,children: [{path: '',name: 'home',component: Home},{path: 'category/:id',name: 'category',component: Category}]},{path: '/login',name: 'login',component: Login},]
})export default router

layoutHeader.vue

<li v-for="item in categoryStore.categoryList" :key="item.id"><RouterLink active-class="active" :to="`/category/${item.id}`">{{ item.name }}</RouterLink>
</li>

面包屑导航渲染

在这里插入图片描述
在这里插入图片描述
封装接口

import request from '@/utils/request'/*** @description: 获取分类数据* @param {*} id 分类id * @return {*}*/
export const getTopCategoryAPI = (id) => {return request({url:'/category',params:{id}})
}

渲染面包屑导航

<script setup>import { findTopCategoryAPI } from '@/apis/category'const categoryData = ref({})const route = useRoute()const getCategory = async (id) => {// 如何在setup中获取路由参数 useRoute() -> route 等价于this.$routeconst res = await findTopCategoryAPI(id)categoryData.value = res.result}getCategory(route.params.id)
</script><template><div class="bread-container"><el-breadcrumb separator=">"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item><el-breadcrumb-item>{{ categoryData.name }}</el-breadcrumb-item></el-breadcrumb></div>
</template>

banner轮播图实现

在这里插入图片描述
在这里插入图片描述
适配接口

export function getBannerAPI (params = {}) {// 默认为1 商品为2const { distributionSite = '1' } = paramsreturn httpInstance({url: '/home/banner',params: {distributionSite}})
}

迁移首页Banner逻辑

<script setup>
// 部分代码省略
import { getBannerAPI } from '@/apis/home'// 获取banner
const bannerList = ref([])const getBanner = async () => {const res = await getBannerAPI({distributionSite: '2'})console.log(res)bannerList.value = res.result
}onMounted(() => getBanner())</script><template><div class="top-category"><div class="container m-top-20"><!-- 面包屑 --><div class="bread-container"><el-breadcrumb separator=">"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item><el-breadcrumb-item>{{ categoryData.name }}</el-breadcrumb-item></el-breadcrumb></div><!-- 轮播图 --><div class="home-banner"><el-carousel height="500px"><el-carousel-item v-for="item in bannerList" :key="item.id"><img :src="item.imgUrl" alt=""></el-carousel-item></el-carousel></div></div></div>
</template><style scoped lang="scss">
// 部分代码省略
.home-banner {width: 1240px;height: 500px;margin: 0 auto;img {width: 100%;height: 500px;}
}
</style>

激活状态显示和分类列表渲染

在这里插入图片描述
** 导航激活状态设置**

<RouterLink active-class="active" :to="`/category/${item.id}`">{{ item.name }}</RouterLink>

分类数据模版

在这里插入图片描述

<script setup>import GoodsItem from '../Home/components/GoodsItem.vue'
import { useBanner } from './composables/useBanner'
import { useCategory } from './composables/useCategory'
const { bannerList } = useBanner()
const { categoryData } = useCategory()</script><template><div class="top-category"><div class="container m-top-20"><!-- 面包屑 --><div class="bread-container"><el-breadcrumb separator=">"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item><el-breadcrumb-item>{{ categoryData.name }}</el-breadcrumb-item></el-breadcrumb></div><!-- 轮播图 --><div class="home-banner"><el-carousel height="500px"><el-carousel-item v-for="item in bannerList" :key="item.id"><img :src="item.imgUrl" alt=""></el-carousel-item></el-carousel></div><div class="sub-list"><h3>全部分类</h3><ul><li v-for="i in categoryData.children" :key="i.id"><RouterLink :to="`/category/sub/${i.id}`"><img :src="i.picture" /><p>{{ i.name }}</p></RouterLink></li></ul></div><div class="ref-goods" v-for="item in categoryData.children" :key="item.id"><div class="head"><h3>- {{ item.name }}-</h3></div><div class="body"><GoodsItem v-for="good in item.goods" :goods="good" :key="good.id" /></div></div></div></div>
</template><style scoped lang="scss">
.top-category {h3 {font-size: 28px;color: #666;font-weight: normal;text-align: center;line-height: 100px;}.sub-list {margin-top: 20px;background-color: #fff;ul {display: flex;padding: 0 32px;flex-wrap: wrap;li {width: 168px;height: 160px;a {text-align: center;display: block;font-size: 16px;img {width: 100px;height: 100px;}p {line-height: 40px;}&:hover {color: $xtxColor;}}}}}.ref-goods {background-color: #fff;margin-top: 20px;position: relative;.head {.xtx-more {position: absolute;top: 20px;right: 20px;}.tag {text-align: center;color: #999;font-size: 20px;position: relative;top: -20px;}}.body {display: flex;justify-content: space-around;padding: 0 40px 30px;}}.bread-container {padding: 25px 0;}
}.home-banner {width: 1240px;height: 500px;margin: 0 auto;img {width: 100%;height: 500px;}
}
</style>

解决路由缓存问题

什么是路由缓存问题
缓存问题:当路由path一样,参数不同的时候会选择直接复用路由对应的组件,相同的组件实例会被重复使用,两个路由渲染同一个组件,意味着组件的生命周期钩子不会被调用

问题:一级分类的切换正好满足上面条件,组件实例复用,导致分类数据无法更新

解决思路
1️⃣组件实例不复用,强制销毁重建
2️⃣监听路由变化,变化之后执行数据更新操作

解决方案

  1. 给 routerv-view 添加key属性,破坏缓存
<RouterView :key="$route.fullPath" />

在这里插入图片描述

  1. 使用 onBeforeRouteUpdate钩子函数,做精确更新
    在这里插入图片描述
// 封装分类数据业务相关代码
import { onMounted, ref } from 'vue'
import { getCategoryAPI } from '@/apis/category'
import { useRoute } from 'vue-router'
import { onBeforeRouteUpdate } from 'vue-router'export function useCategory () {// 获取分类数据const categoryData = ref({})const route = useRoute()const getCategory = async (id = route.params.id) => {const res = await getCategoryAPI(id)categoryData.value = res.result}onMounted(() => getCategory())// 目标:路由参数变化的时候 可以把分类数据接口重新发送onBeforeRouteUpdate((to) => {// 存在问题:使用最新的路由参数请求最新的分类数据getCategory(to.params.id)})return {categoryData}
}

总结
1️⃣路由参数问题产生的原因是什么?
路由只有参数变化时,会复用组件实例

2️⃣两种方案都可以解决路由缓存问题,如何选择
在意性能问题,选择onBeforeRouteUpdate,精细化控制
不在意性能问题,选择key,简单粗暴

使用逻辑函数拆分业务

概念理解
基于逻辑函数拆分业务是指把同一个组件中独立的业务代码通过函数做封装处理,提升代码的可维护性
在这里插入图片描述
实现步骤
1️⃣按照业务生命以 use 打头的逻辑函数
2️⃣把独立的业务逻辑封装到各个函数内部
3️⃣函数内部把组件中需要用到的数据或者方法return出去
4️⃣在组件中调用函数把数据或者方法组合回来使用

封装banner轮播图相关的业务代码

import { ref, onMounted } from 'vue'
import { getBannerAPI } from '@/apis/home'export function useBanner () {const bannerList = ref([])const getBanner = async () => {const res = await getBannerAPI({distributionSite: '2'})console.log(res)bannerList.value = res.result}onMounted(() => getBanner())return {bannerList}
}

组件内使用

import { useBanner } from './composables/useBanner'
const { bannerList } = useBanner()

核心总结
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/254086.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智慧自助餐饮系统(SpringBoot+MP+Vue+微信小程序+JNI+ncnn+YOLOX-Nano)

一、项目简介 本项目是配合智慧自助餐厅下的一套综合系统&#xff0c;该系统分为安卓端、微信小程序用户端以及后台管理系统。安卓端利用图像识别技术进行识别多种不同菜品&#xff0c;识别成功后安卓端显示该订单菜品以及价格并且生成进入小程序的二维码&#xff0c;用户扫描…

transformer剪枝论文汇总

文章目录 NN Pruning摘要实验 大模型剪枝LLM-PrunerSparseGPT LTPVTPWidth & Depth PruningPatch SlimmingDynamicViTSPViTDynamicBERTViT SlimmingFastFormersNViTUVCPost-training pruning NN Pruning 《Block Pruning For Faster Transformers》 《为更快的transformer…

Django学习记录02

1.请求与响应 1.1get与post的区别 get 一般是从url输入地址&#xff0c;会调用get请求 post 一般是内部数据传输# get请求 def something(request):# req是一个对象&#xff0c;封装了用户发送过来的所有请求相关数据# 1.获取请求方式 http://localhost:8000/something# pri…

Go 语言 for 的用法

For statements 本文简单翻译了 Go 语言中 for 的三种用法&#xff0c;可快速学习 Go 语言 for 的使用方法&#xff0c;希望本文能为你解开一些关于 for 的疑惑。详细内容可见文档 For statements。 For statements with single condition 在最简单的形式中&#xff0c;只要…

centos7编译安装redis

一、环境 系统&#xff1a;CentOS Linux release 7.9.2009 (Core) redis版本&#xff1a;redis 6.0.6 二、安装及部署 当前最新稳定版本是redis 6.0.6 国内网址&#xff1a;http://www.redis.cn redis下载列表&#xff1a;http://download.redis.io/releases/ 下载 wge…

机器学习--K-近邻算法常见的几种距离算法详解

文章目录 距离度量1 欧式距离(Euclidean Distance)2 曼哈顿距离(Manhattan Distance)3 切比雪夫距离 (Chebyshev Distance)4 闵可夫斯基距离(Minkowski Distance)5 标准化欧氏距离 (Standardized EuclideanDistance)6 余弦距离(Cosine Distance)7 汉明距离(Hamming Distance)【…

14.scala隐式转换

目录 概述实践代码执行结果 结束 概述 隐式转换&#xff1a;偷偷的(隐式)对现有功能进行增强(转换) 实践 代码 package com.fun.scalaimport java.io.File import scala.io.Sourceobject ImplicitApp {def main(args: Array[String]): Unit {// implicit 2 to 等价 &…

K8S之Pod常见的状态和重启策略

Pod常见的状态和重启策略 常见的Pod状态PendingPodScheduledUnschedulablePodInitializingImagePullBackOffInitializedRunningErrorCrashLoopBackOffTerminatingSucceededFailedEvictedUnknown Pod的重启策略使用Always重启策略使用Never重启策略使用OnFailure重启策略(常用) …

go消息队列RabbitMQ - 订阅模式-direct

1.发布订阅 在Fanout模式中&#xff0c;一条消息&#xff0c;会被所有订阅的队列都消费。但是&#xff0c;在某些场景下&#xff0c;我们希望不同的消息被不同的队列消费。这时就要用到Direct类型的Exchange。 在Direct模型下&#xff1a; 队列与交换机的绑定&#xff0c;不能…

NuxtJs安装Sass后出现ERROR:Cannot find module ‘webpack/lib/RuleSet‘

最近了解NuxtJs时&#xff0c;发现问题比较多&#xff0c;对于初学者来说是件比较头痛的事。这次是安装sass预处理器&#xff0c;通过命令安装后&#xff0c;出现了ERROR&#xff1a;Cannot find module webpack/lib/RuleSet 错误&#xff0c;于是根据之前经验&#xff0c;对版…

解析spritf和sscanf与模拟常用字符串函数strchr,strtok(二)

今天又来继续我们的字符串函数的文章&#xff0c;这也是最后一篇了。希望这两篇文章能让各位理解透字符串函数。 目录 strchr strtok sprintf和sscanf strchr strchr 是一个用于在字符串中查找特定字符首次出现位置的函数。以下是解析和模拟实现 strchr 函数的示例&…

在Visual Studio中引用和链接OpenSceneGraph (OSG) 库

在Visual Studio中引用和链接OpenSceneGraph (OSG) 库&#xff0c;按照以下步骤操作&#xff1a; 构建或安装OSG库 下载OpenSceneGraph源代码&#xff08;如3.0版本&#xff09;并解压。使用CMake配置项目&#xff0c;为Visual Studio生成解决方案文件。通常您需要设置CMake中的…

Bee+SpringBoot稳定的Sharding、Mongodb ORM功能(同步 Maven)

Hibernate/MyBatis plus Sharding JDBC Jpa Spring data GraphQL App ORM (Android, 鸿蒙) Bee 小巧玲珑&#xff01;仅 860K, 还不到 1M, 但却是功能强大&#xff01; V2.2 (2024春节・LTS 版) 1.Javabean 实体支持继承 (配置 bee.osql.openEntityCanExtendtrue) 2. 增强批…

Spring Boot + 七牛OSS: 简化云存储集成

引言 Spring Boot 是一个非常流行的、快速搭建应用的框架&#xff0c;它无需大量的配置即可运行起来&#xff0c;而七牛云OSS提供了稳定高效的云端对象存储服务。利用两者的优势&#xff0c;可以为应用提供强大的文件存储功能。 为什么选择七牛云OSS? 七牛云OSS提供了高速的…

PCIE Order Set

1 Training Sequence Training Sequence是由Order Set(OS) 组成&#xff0c;它们主要是用于bit aligment&#xff0c;symbol aligment&#xff0c;交换物理层的参数。当data_rate 2.5GT or 5GT 它们不会被扰码(scramble)&#xff0c;当date_rate 8GT or higher 根据特殊的规则…

第59讲订单数据下拉实现

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;/*** 订单查询 type值 0 全部订单 1待付款 2 待收货 3 退款/退货* param type* return*/RequestMapping("/list")public R list(Integer type,Integer page,Integer pageSize){System.out.pri…

Golang数据库编程详解 | 深入浅出Go语言原生数据库编程

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站https://www.captainbed.cn/kitie。 Golang学习专栏&#xff1a;https://blog.csdn.net/qq_35716689/category_12575301.html 前言 对数据库…

Vue3编写简单的App组件(二)

一、Vue3页面渲染基本流程 1、入口文件 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><link rel"icon" href"/favicon.ico"><meta name"viewport" content"widthde…

es6中标签模板

之所以写这篇文章&#xff0c;是因为标签模板是一个很容易让人忽略的知识点 首先我们已经非常熟悉模板字符串的使用方法 const name "诸葛亮" const templateString hello, My name is ${name}标签模板介绍 这里的标签模板其实不是模板&#xff0c;而是函数调用…

【CV论文精读】【MVDet】Multiview Detection with Feature Perspective Transformation

0.论文摘要 合并多个摄像机视图进行检测减轻了拥挤场景中遮挡的影响。在多视图检测系统中&#xff0c;我们需要回答两个重要问题。首先&#xff0c;我们应该如何从多个视图中聚合线索&#xff1f;第二&#xff0c;我们应该如何从空间上相邻的位置聚集信息&#xff1f;为了解决…