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://xiahunao.cn/news/2775486.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【网工】华为设备命令学习(Telnet)

本次实验AR3为我们实际中远程的路由&#xff0c;AR4模拟我们的设备&#xff0c;最终实现Telnet的远程控制路由&#xff01; 本次笔记主要记录Telnet技术实现原理&#xff0c;后续再补充具体配置代码。 Telnet协议是TCP/IP协议族中的一员&#xff0c;是Internet远程登录服务的…

哈希表—闭散列

目录 背景 实现 设置状态 存储 获取key函数 构造函数 插入 查找 删除 打印 完整代码 背景 常用哈希函数 除留取余法 设散列表中允许的地址数为m&#xff0c;取一个不大于m&#xff0c;但最接近或者等于m的质数p作为除数&#xff0c;按照哈希 函数&#xff1a;H a…

ubuntu22.04安装部署03: 设置root密码

一、前言 ubuntu22.04 安装完成以后&#xff0c;默认root用户是没有设置密码的&#xff0c;需要手动设置。具体的设置过程如下文内容所示&#xff1a; 相关文件&#xff1a; 《ubuntu22.04装部署01&#xff1a;禁用内核更新》 《ubuntu22.04装部署02&#xff1a;禁用显卡更…

山西电力市场日前价格预测【2024-02-08】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2024-02-08&#xff09;山西电力市场全天平均日前电价为200.58元/MWh。其中&#xff0c;最高日前电价为347.58元/MWh&#xff0c;预计出现在07:00。最低日前电价为0.00元/MWh&#xff0c;预计出…

数据结构 - 线索树

一、 为什么要用到线索二叉树&#xff1f; 我们先来看看普通的二叉树有什么缺点。下面是一个普通二叉树&#xff08;链式存储方式&#xff09;&#xff1a; 乍一看&#xff0c;会不会有一种违和感&#xff1f;整个结构一共有 7 个结点&#xff0c;总共 14 个指针域&#xff0c…

【多模态】27、Vary | 通过扩充图像词汇来提升多模态模型在细粒度感知任务(OCR等)上的效果

文章目录 一、背景二、方法2.1 生成 new vision vocabulary2.1.1 new vocabulary network2.1.2 Data engine in the generating phrase2.1.3 输入的格式 2.2 扩大 vision vocabulary2.2.1 Vary-base 的结构2.2.2 Data engine2.2.3 对话格式 三、效果3.1 数据集3.2 图像细粒度感…

云安全的基本概念(基本目标与指导方针)

目录 一、云安全概念概述 1.1 概述 二、云安全的基本目标 2.1 安全策略开发模型 2.1.1 信息安全三元组 2.1.1.1 保密性(Confidentiality) 2.1.1.2 完整性(Integrity) 2.1.1.3 可用性(Availability) 2.1.2 信息安全三元组的局限性 2.2 其他信息安全属性 2.2.1 真实性 …

双指针和单调栈

双指针 用于解决一类基于子段的统计问题 子段就是&#xff1a;数组中连续的一段 可以用一个闭区间来表示数组中的连续一段 这个方法核心就是优化&#xff1a;两种循环的枚举 也就是枚举左端点l和右端点r的所有可能优化关键就是&#xff1a;去除枚举中的冗余部分 具体优化策略…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Span组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Span组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Span组件 鸿蒙&#xff08;HarmonyOS&#xff09;作为Text组件的子组件&#xff0…

C# 委托(delegate)本质理解

目录 代码如下&#xff0c;很简单 运行的结果 反编译程序查看 关注两点&#xff1a; 什么是委托 委托的三个步骤 委托的意义 代码如下&#xff0c;很简单 namespace Delegate { class Program { delegate void SayHi(); void SayHi_1() …

[Java][算法 双指针]Day 02---LeetCode 热题 100---04~07

LeetCode 热题 100---04~07 第一题&#xff1a;移动零 思路 找到每一个为0的元素 然后移到数组的最后 但是需要注意的是 要在给定的数组原地进行修改 并且其他非零元素的相对顺序不能改变 我们采用双指针法 定义两个指针i和j i和j一开始分别都在0索引位置 然后判断j所…

爪哇部落算法组2024新生赛热身赛题解

第一题&#xff08;签到&#xff09;&#xff1a; 1、题意&#xff1a; 2、题解: 我们观察到happynewyear的长度是12个字符&#xff0c;我们直接从前往后遍历0到n - 12的位置&#xff08;这里索引从0开始&#xff09;&#xff0c;使用C的substr()函数找到以i开头的长度为12的字…

【Linux】进程学习(二):进程状态

目录 1.进程状态1.1 阻塞1.2 挂起 2. 进程状态2.1 运行状态-R进一步理解运行状态 2.2 睡眠状态-S2.3 休眠状态-D2.4 暂停状态-T2.5 僵尸状态-Z僵尸进程的危害 2.6 死亡状态-X2.7 孤儿进程 1.进程状态 1.1 阻塞 阻塞&#xff1a;进程因为等待某种条件就绪&#xff0c;而导致的…

leetcode(哈希表)49.字母异位词分组(C++详细解释)DAY5

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 示例 1: 输入: strs [“eat”, “tea”…

【JavaWeb】头条新闻项目实现 基本增删改查 分页查询 登录注册校验 业务功能实现 第二期

文章目录 一、为什么使用token口令二、登录注册功能2.1 登录表单提交后端代码&#xff1a; 2.2 根据token获取完整用户信息代码实现&#xff1a; 2.3 注册时用户名占用校验代码实现&#xff1a; 2.4 注册表单提交代码实现&#xff1a; 三、头条首页功能3.1 查询所有头条分类3.2…

第三讲 多重背包问题①——转化

【题目来源】AcWing 4. 多重背包问题 I 【题意分析】和完全背包问题类似&#xff0c;但是区别在于每一种物品的数量是有限的。 【解决方法】 1.转化为 0 / 1 0/1 0/1 背包问题 因为每一种物品数量有限&#xff0c;所以将每个物品看作单独的种类&#xff0c;可转化为 0 / 1 0/…

掌握Vue,开启你的前端开发之路!

介绍&#xff1a;Vue.js是一个构建数据驱动的Web应用的渐进式框架&#xff0c;它以简洁和轻量级著称。 首先&#xff0c;Vue.js的核心在于其视图层&#xff0c;它允许开发者通过简单的模板语法将数据渲染进DOM&#xff08;文档对象模型&#xff09;。以下是Vue.js的几个重要特点…

Git中为常用指令配置别名

目录 1 前言 2 具体操作 2.1 创建.bashrc文件 2.2 添加指令 2.3 使其生效 2.4 测试 1 前言 在Git中有一些常用指令比较长&#xff0c;当我们直接输入&#xff0c;不仅费时费力&#xff0c;还容易出错。这时候&#xff0c;如果能给其取个简短的别名&#xff0c;那么事情就…

力扣102. 二叉树的层序遍历 (复习vector和queue的常见用法

目录 题目描述 题目解析 题目答案 题目所用知识点 最后 题目描述 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术…

K8S之运用节点选择器指定Pod运行的节点

node节点选择器的使用 使用场景实践使用nodeName使用nodeSelectornodeName和nodeSelector混合使用1、设置了nodeName 和 设置 Node上都不存在的标签。看调度情况2、设置nodeName 为node1 和 设置 node2上才有的标签。看调度情况 实践总结 使用场景 默认情况&#xff0c;在创建…