16.开发Search组件模块中的TypeNav商品分类菜单(过渡动画效果)
重难点说明
-
组件与vuex交互
-
事件控制二三级分类列表的显示与隐藏
-
优化高频事件触发处理: 利用lodash进行函数节流处理
-
优化减小打包文件: 对lodash库实现按需引入
-
解决快速移出后可能显示第一个分类的子分类列表的bug
-
优化减少组件对象数量: 使用编程式导航代替声明式导航
-
优化事件处理效率: 利用事件委托
-
利用标签自定义属性携带动态数据
-
控制一级列表的显示与隐藏
- 一级列表显示隐藏的过渡效果
- 优化请求执行的位置, 减少请求次数
- 合并分类query参数与搜索的关键字params参数
要求:Home组件中三级菜单一直显示,而Search组件中初始进来隐藏,当鼠标划入则显示,鼠标移出则隐藏,另外三级菜单要有过渡动画效果。
过渡动画:前提组件|元素务必要有v-if|v-show指令才能进行过渡动画控制。
新增代码如下:Search组件中使用/
<template>
<div>我是搜索页
<TypeNav></TypeNav>
</div>
</template>
TypeNav组件中使用@mouseleave和 @mouseenter对show属性显隐进行控制
<div @mouseleave="leaveIndex" @mouseenter="enterShow">
<transition name="sort">
<div class="sort" v-show="show">
</div>
</transition>
</div>
---------------------------------------------------------------------------
data() {
return {
show:true
}
},
---------------------------------------------------------------------------
//组件挂载完毕
mounted() {
//当组件挂载完毕,让show属性变为false
//如果不是Home路由组件,将typeNav进行隐藏
if (this.$route.path != "/home") {
this.show = false;
}
},
---------------------------------------------------------------------------
methods: {
//当鼠标离开的时候,让商品分类列表进行隐藏
leaveIndex() {
this.currentIndex = -1;
//判断如果是Search路由组件的时候才会执行
if (this.$route.path != '/home') {
this.show = false;
}
},
//当鼠标移入的时候,让商品分类列表进行展示
enterShow() {
if (this.$route.path != '/home') {
this.show = true;
}
}
},
---------------------------------------------------------------------------
//过渡动画的样式
//过渡动画开始状态(进入)
.sort-enter {
height: 0px;
}
// 过渡动画结束状态(进入)
.sort-enter-to {
height: 461px;
}
// 定义动画时间、速率
.sort-enter-active {
transition: all 0.5s linear;
}
注意點1
:
问题:Search組件中使用三級联动菜单TypeNav需要引入吗?
答案:不需要,因为三級联动菜单TypeNav是注册的全局组件,可以直接使用。
注意點2
:通过show属性控制三级菜单的显隐,设计思路是:初始化show:true -> 通过mounted()钩子函数判断当路由为非home组件时设置show = false,这样当进入Search组件时菜单会默认自动隐藏 -> 定义鼠标划入、离开的函数,进行显隐控制
注意點3
:
问题:控制划入+划出的@mouseenter和@mouseleave应该放在哪一层上?
答案:也应该放在父层上,还是父类委派操作,同时添加路由路径逻辑判断控制show的属性。
注意點4
:
问题:v-show属性应该放在哪一层上?
答案:应该放在“全部商品分类”标签的里面元素,而不是放在父类元素。因为如果放在父类元素错误效果是当进入Search组件时整个菜单就完全隐藏后续无法进行显示了。
正确代码请看,请注意v-show所在元素的位置
<div @mouseleave="leaveIndex" @mouseenter="enterShow">
<h2 class="all">全部商品分类</h2>
<!-- 过渡动画 -->
<transition name="sort">
<!--1级联动菜单-->
<div class="sort" v-show="show">
正确效果如图
错误代码请看,请注意v-show所在元素的位置
<div @mouseleave="leaveIndex" @mouseenter="enterShow" v-show="show">
<h2 class="all">全部商品分类</h2>
<!-- 过渡动画 -->
<transition name="sort">
<!--1级联动菜单-->
<div class="sort" >
错误效果如图
注意點5
:使用动画效果,要使用标签/进行包裹,另外配合样式搭配使用
<transition name="sort">
...
</transition>
//过渡动画的样式
//过渡动画开始状态(进入)
.sort-enter {
height: 0px;
}
// 过渡动画结束状态(进入)
.sort-enter-to {
height: 461px;
}
// 定义动画时间、速率
.sort-enter-active {
transition: all 0.5s linear;
}
17.(优化)针对三级菜单联动进行优化,优化方向为减少查询
消耗资源场景:正常情况下查询list的接口放在TypeNav组件中,这样坏处是进入Home组件会请求一次,当点击跳转Search组件时Home组件销毁然而查询list的接口还会再次执行一次,也就是存在多次查询相同接口的场景。
优化方案:想办法减少或者只执行一次查询到处使用。优化方案把查询list的接口放在App.vue的mounted()方法中,因为App.vue只会执行一次,代码如下
把TypeNav的mounted()中的查询移到App.vue的mounted()中
mounted() {
//派发一个action||获取商品分类的三级列表的数据
this.$store.dispatch("getCategoryList")
}
问题1:能否把查询list接口方法这行放在main.js中,因为main.js也只执行一次。
答案:不能,因为main.js是个js文件,哪怕打印里面的this,控制台会输出underfine,而App.vue中的this指代的是组件实例,而只有组件实例才有$store的属性,所以只能放在App.vue中。
本人其他相关文章链接
1.vue尚品汇商城项目-day03【16.开发Search组件模块中的TypeNav商品分类菜单(过渡动画效果)+17.(优化)针对三级菜单联动进行优化,优化方向为减少查询】
2.vue尚品汇商城项目-day03【18.合并params和query参数(Header组件+TypeNav组件)】
3.vue尚品汇商城项目-day03【vue插件-19.mockjs模拟数据(开发Home首页当中的ListContainer组件与Floor组件)】
4.vue尚品汇商城项目-day03【20.获取Banner轮播图的数据+21.使用swiper轮播图插件】
5.vue尚品汇商城项目-day03【22.开发Floor组件】