vue尚品汇商城项目-day02【15.动态展示三级菜单联动】

news/2025/1/16 21:17:44/

在这里插入图片描述

文章目录

    • 15.动态展示三级菜单联动
      • 15.1动态调用展示三级菜单步骤
      • 15.2完成一级菜单鼠标划入显示背景色
      • 15.3控制二三级商品分类的显示与隐藏
      • 15.4演示卡顿现象引入防抖与节流
      • 15.5三级联动组件的路透跳转与传递参数
  • 本人其他相关文章链接

15.动态展示三级菜单联动

问题1:

在这里插入图片描述

代码:

<script>
export default {name: "TypeNav",computed:{...mapState({categoryList:state=>state.home.categoryList})}
}
</script>

原因分析:因为缺少mapState引入,所以报错mapState不认识,添加引入即可

import { mapState } from "vuex";

15.1动态调用展示三级菜单步骤

简单总结使用步骤:

  1. 在字模块actions、mutations中定义函数
  2. 在App.vue中触发调用
  3. 编写计算属性,这样state中就已经保存最新的数据了
  4. 在模板代码处遍历动态拼接最新的数据,进行展示

详细使用步骤:

  • 第1步:/store/home/index.js引入方法定义actions、mutations中的函数。
import {getCategoryList} from '@/api'
//Home模块的小仓库
//actions代表一系列动作,可以书写自己的业务逻辑,也可以处理异步
const actions = {//getCategoryList返回的是一个Promise对象//需要用await接受成功返回的结果,await必须要结合async一起使用(CP)async getCategoryList(context) {let response = await getCategoryList();if (response.code == 200) {context.commit("GETCATEGORYLIST", response.data)}}
}
//mutations代表维护,操作维护的是state中的数据,且state中数据只能在mutations中处理
const mutations = {GETCATEGORYLIST(state, categoryList) {state.categoryList = categoryList}
}
//state代表仓库中的数据
const state = {//home仓库中存储三级菜单的数据categoryList:[]
}
//getters理解为计算属性,用于简化仓库数据,让组件获取仓库的数据更加方便
const getters = {}//创建并暴露store
export default {actions,mutations,state,getters
}
  • 第2步:在App.vue中定义mounted钩子函数,派发一个action,获取商品分类的三级列表的数据。
mounted() {//派发一个action||获取商品分类的三级列表的数据this.$store.dispatch("getCategoryList")}
  • 第3步:/components/TypeNav/index.vue,在要使用state数据的地方使用mapState生成计算函数,然后模板中循环遍历使用数据。
<div class="item bo" v-for="(c1,index) in categoryList" :key="c1.categoryId"><h3><a href="">{{c1.categoryName}}</a></h3>
</div>computed:{...mapState({categoryList:state=>state.home.categoryList})}

问题2:为啥actions定义的getCategoryList函数要使用async+await?

答案:因为getCategoryList函数函数最后返回的是一个promise的对象,如图,而我们直接想要的是成功的回调函数,所以用async+await可直接获取到。

在这里插入图片描述

15.2完成一级菜单鼠标划入显示背景色

效果如下:

在这里插入图片描述

共有2种方式:

  • 方式1:css直接使用:hover添加背景色,知识点:hover在鼠标移到链接上时添加的特殊样式
//方式1::hover
.item:hover {background: skyblue;
}
  • 方式2:通过定义鼠标划入事件添加背景色,思路说明,每一项都有自己的index,我们初始化currentIndex为-1,当鼠标划入时修改currentIndex的值,当判断currentIndex == index时动态绑定样式,同时搭配@mouseenter和@mouseleave即可实现划入划出的背景效果。
<div @mouseleave="leaveIndex" >
<h3 @mouseenter="changeIndex(index)" :class="{cur: currentIndex == index }">methods: {//用于修改组件实例身上的currentIndex的属性值//当用户鼠标移入到h3身上的时候就会立即出发一次changeIndex(index) {this.currentIndex = index;},//当鼠标离开的时候,让商品分类列表进行隐藏leaveIndex() {this.currentIndex = -1;}
}.cur {background: skyblue;
}

注意点1:mouseenter:当鼠标移入元素本身(不包含元素的子元素)会触发事件,事件不会叠加。对应的移除事件是 mouseleave。

注意点2:现在想实现个新效果,鼠标从第一项划入“全部商品分类”也不会去除背景色,具体效果如图,具体方案可采用“事件委派”指的是把事件委派给父亲元素去控制,逻辑就是把“全部商品分类”和一级菜单用一个div单独包起来,在外侧进行划出控制。

15.3控制二三级商品分类的显示与隐藏

共有2种方式:

  • 方式1:通过css的:hover控制display的block|none显示与隐藏
.item-list {display: none;...
}
&:hover {.item-list {display: block;}
}
  • 方式2:通过js的方式控制display的显示与隐藏
 <div class="item-list clearfix" :style="{display: currentIndex == index ? 'block' : 'none'}">

问题:css中的&:hover,中的&啥意思?

答案:

贴个CSS代码进行讲解

.box{&:before{border-color: red;}&:after{border-color: green;}}

& 表示在嵌套层次中回溯一层,即&:before相当于.box:before

15.4演示卡顿现象引入防抖与节流

正常:事件触发非常频繁,而且每一次的触发,回调函数都要去执行(如果时间很短,而回调函数内部有计算,那么很可能出现浏览器卡顿现象),正常效果如图1,错误效果如,2。

在这里插入图片描述

如图1

在这里插入图片描述

如图2

节流:在规定的间隔时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发【给浏览器有充裕的时间解析代码】。

防抖:前面的所有的触发都被取消,最后一次执行在规定的时间之后才会触发,也就是说如果连续快速的触发只会执行一次。

注意点0:

安装命令:cnpm install --save lodash

使用方式:

//引入lodash:是把lodash全部封装好的函数全都引入进来了
//按需引入:只是引入节流函数,其他的函数没有引入(模块),这样做的好处是,当你打包项目的时候体积会小一些
import throttle from "lodash/throttle";changeIndex: throttle(function(index) {//修改当前currentIndex索引值//函数节流:在20MS时间之内只能执行一次this.currentIndex = index;}, 20),

注意点1:可使用lodash插件:里面封装函数的防抖与节流的业务方法【闭包+延迟器】

注意点2:防抖与节流区别是啥?

答案:“节流”是规定时间内只执行一次,而“防抖”是无论多长时间我都是最后执行一次。

注意点3:lodash官网:https://www.lodashjs.com/

防抖:debounce(func, [wait=0], [options=])

节流:throttle(func, [wait=0], [options=])

15.5三级联动组件的路透跳转与传递参数

三级联动用户可以点击的:一级分类、二级分类、三级分类,当你点击的时候Home模块跳转到Search模块,一级会把用户选中的产品(产品名字,产品ID)在路由跳转的时候,进行传递。

路由跳转:

  • 声明式导航:router-link

  • 编程式导航:push|replace

问题1:选用“声明式导航”还是“编程式导航“?

答案:应该选用编程式导航。如果使用声明式导航router-link,可以实现路由的跳转与传递参数,但是需要注意,会出现卡顿现象,因为三级联动菜单是循环遍历产生的,如果循环遍历1000次那得新生成/标签,很占用内存,肯定会卡顿。

问题2:既然选择”编程式导航“,那么是/标签绑定点击事件?还是采用其他方式?

答案:不能采用a标签绑定事件方式,应该采用“父元素委托事件”方式。因为这样只需定义一次函数即可,而采用a标签我还得循环遍历定义1000次函数。

问题3:我们想要效果是点击a标签才跳转路由,如何确认a标签?

答案:给a标签绑定自定义属性,使用event.target.dataset可以获取自定义属性名称,能获取自定义属性名称的一定是我们要的a标签。

问题4:采用“父元素委托事件”方式后,会出现如图错误效果:当点击1级菜单时 -> 先跳转到搜索页 -> 又自动跳转到首页

答案:把/标签的href属性必须删掉

问题5:自定义属性名为啥叫 data-xxx,输出打印的dataset名称全是小写,但是为啥前面的data-没了?举例说明自定义属性名称叫:data-categoryName,为啥最后dataset获取的名称却是categoryname,明显前缀data-没了,而且莫名变成小写了?

在这里插入图片描述

答案:JS中要想使用dataset获取自定义属性,那么在HTML模板中自定义属性名必须叫“data-xxx”。

下方为别人博客摘抄:

HTML5 中添加了 data-* 的方式来自定义属性,实际上就是在自定义属性名前加上前缀data- 即可,使用这样的结构可以进行数据存放。使用data-* 可以解决自定义属性混乱无管理的现状。

一个自定义一旦加上了前缀 data- ,那么在 JS 中就可以通过 elementNodeObject.dataset拿到这个属性,显然 dataset 是 attribute 集合的一个子集。
dataset 属性的值是 DOMStringMap的一个实例,也就是一个名值对儿的映射。在这个映射中,每个 data-name 形式的属性都会有一个对应的属性,只不过没有 data- 前缀。

完整代码 src/commponents/TypeNav/index.vue

<!--1级联动菜单--><div class="sort"><div class="all-sort-list2" @click="goSearch"><div class="item bo" v-for="(c1,index) in categoryList" :key="c1.categoryId"><h3 @mouseenter="changeIndex(index)" :class="{cur: currentIndex == index }"><a :data-categoryName="c1.categoryName" :data-category1Id="c1.categoryId">{{c1.categoryName}}</a></h3><!--方式2:通过js的方式控制display的显示与隐藏--><div class="item-list clearfix" :style="{display: currentIndex == index ? 'block' : 'none'}"><div class="subitem"><!--2级联动菜单--><dl class="fore" v-for="(c2,index) in c1.categoryChild" :key="c2.categoryId"><dt><a :data-categoryName="c2.categoryName" :data-category2Id="c2.categoryId">{{c2.categoryName}}</a></dt><dd><!--3级联动菜单--><em v-for="(c3,index) in c2.categoryChild" :key="c3.categoryId"><a :data-categoryName="c3.categoryName" :data-category3Id="c3.categoryId">{{c3.categoryName}}</a></em></dd></dl></div></div></div></div></div>
------------------------------------------------------------------------------------------------------
//进行路由跳转的回调函数goSearch(event) {//最好的解决方案:编程式导航+事件委派//存在一些问题:事件委派,是把全部的子节点【h3、dt、dl、em】的事件委派给父亲节点//问题1:点击a标签的时候,才会进行路由跳转【怎么能确认点击的一定是a标签?】//答案:给a标签绑定自定义data-categoryName属性,只要能获取到自定义属性就代表是a标签//event.target:获取到的是触发事件的元素(div、h3、a、em、dt、dl)let element = event.target;//节点有一个属性dataset,可以过去节点的自定义属性与属性值let {categoryname, category1id, category2id, category3id} = element.dataset;//如果标签身上带有categoryname一定是a标签,且当前这个if语句:一定是a标签才会进入if (categoryname) {//准备路由跳转的参数对象let location = {name: 'search'}let query = {categoryName: categoryname}//一级目录if(category1id) {query.category1Id = category1id//二级目录} else if (category2id) {query.category2Id = category2id//三级目录} else {query.category3Id = category3id}//动态给location配置对象添加query属性location.query = query;//路由跳转this.$router.push(location);}}

问题6:Vue项目启动默认打开http://0.0.0.0:8080,浏览器显示无法访问,而输入http://localhost:8080就能展示页面

在这里插入图片描述

解决方案:在vue.config.js文件中新增一行:host: 'localhost’即可。

module.exports = {productionSourceMap:false,// 关闭ESLINT校验工具lintOnSave: false,devServer: {//代理服务器解决跨域proxy: {"/api": {target: "http://39.98.123.211:8510"},},//解决默认打开浏览器,会出现0.0.0.0:8080,浏览器显示无法访问host: 'localhost'}
};

本人其他相关文章链接

1.vue尚品汇商城项目-day02【9.Home组件拆分+10.postman测试接口】
2.vue尚品汇商城项目-day02【vue插件-13.nprogress进度条的使用】
3.vue尚品汇商城项目-day02【11.对axios二次封装+12.接口统一管理】
4.vue尚品汇商城项目-day02【14.vuex状态管理库】
5.vue尚品汇商城项目-day02【15.动态展示三级菜单联动】


http://www.ppmy.cn/news/37837.html

相关文章

Java设计模式(六)桥接模式

结构型模式&#xff0c;共七种&#xff1a;适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 这种模式涉及到一个作为桥接的接口&#xff0c;使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。 它的主要特点是把抽象…

如何使用ChatGPT写论文?

使用ChatGPT写论文详细操作步骤 说明ChatGPT是一款ai产品&#xff0c;尽管它非常强大&#xff0c;对我们来说本质上也仅仅是一个辅助工具&#xff0c;切勿让AI完全取代我们的思考能力。目前的ChatGPT写论文还不能一步到位&#xff0c;只能通过一些技巧来完成整篇论文。使用Cha…

centos7在docker上安装es(elasticsearch)

因为需要部署kibana容器&#xff0c;因此需要让es和kibana容器互联 1.创建网络 docker network create es-net 2.将es的tar文件拉取到虚拟机中&#xff08;因为es文件较大&#xff0c;不建议直接使用docker进行拉取&#xff09; 没有es.tar文件的可以下载&#xff1a; 链接…

C++环境设置

本地环境设置 如果您想要设置 C 语言环境&#xff0c;您需要确保电脑上有以下两款可用的软件&#xff0c;文本编辑器和 C 编译器。 文本编辑器 这将用于输入您的程序。文本编辑器包括 Windows Notepad、OS Edit command、Brief、Epsilon、EMACS 和 vim/vi。 文本编辑器的名…

信息学奥赛一本通 1384:珍珠(bead)

【题目链接】 ybt 1384&#xff1a;珍珠(bead) 【题目考点】 1. 图论&#xff1a;floyd 求传递闭包 传递闭包&#xff1a;二维数组e&#xff0c;e[i][j]表示顶点i到顶点j是否有路径。 【解题思路】 这是个有向图。每颗珍珠是一个顶点&#xff0c;初始情况下&#xff0c;如…

为社会开发,无障碍开发,开发人员的公益时间

无障碍开发让每一个人受益无障碍开发让每一个人受益无障碍开发的重要性无障碍开发案例无障碍小助手百度无障碍开放平台Apple Watch 的无障碍功能Google 的无障碍开发指南微软的无障碍开发工具结论无障碍开发让每一个人受益 无障碍开发是指开发人员在设计和开发软件时&#xff…

C++实现vector

#include <iostream> // using namespace std; template <typename T> class Myvector { private:T * first;//指向头T * last;//指向最后一个元素T * end;//指向容器末尾 public:Myvector():first(nullptr),last(nullptr),end(nullptr){ cout << "Myve…

Nautilus Chain 首个生态基础设施 Poseiswap,公布空投规则

以Optimism、Arbitrum One等为代表的Layer2生态&#xff0c;率先对交互测试用户发放了空投后&#xff0c;越来越多的用户也开始向新的未发币的Layer2生态比如zkSync Era、StarkNet等看齐&#xff0c;以期待从中获得潜在的空投机会。而除了Layer2概念板块外&#xff0c;以Nautil…