三级联动组件的路由的跳转与传参
三级联动,用户可以点击的:一级分类、二级分类、三级分类,当你点击的时候
以商城项目为例,Home模块跳转到Search模块,以及会把用户选中的产品(产品名字、产品ID)在路由跳转的时候,进行传递
路由跳转:
声明式导航:router-link
编程式导航:push|replace
方法一:声明式导航router-link来替换a标签跳转(不推荐)
1. 点击后确实能够跳转到/search页面
![]()
![]()
2. 但是当你鼠标进入三级联动,上下滑动的时候,会出现卡顿现象!
原因是:router-link是一个组件,是需要创建的,当服务器的数据返回后,循环出很多的router-link组件[创建组件实例]1000+,创建组件实例的时候,一瞬间创建1000+很耗内存的,因此出现了卡顿现象
方法二:编程式导航(一般方法)
1.绑定点击事件
![]()
2.给点击事件一个方法

3.点击后确实能够跳转到/search页面,而且也没有了卡顿的现象
4.但是这种方法也不是最优秀的
原因是:因为每一个a标签都绑定了一个@click函数,因为这个三级联动,要循环,可能会有1000+次,所以相当于绑定了1000+个的@click回调函数,那么你觉得有1000个回调函数和有1个回调
函数,哪一个更好呢,当然是由一个更好,那么就要用到我们的老朋友,事件的委派
方法三:事件的委派+编程式导航(最佳方法)
1.利用事件的委派
在三级联动的父元素的div上绑定一个@click="goSearch"
![]()
methods中这样写:

这样也可以完成跳转到search的效果
2.但是问题又来了
利用事件委派存在一些问题:
(1)你怎么知道点击的是a标签呢?因为三级联动父div里面有a,h3,dt,dl,是把全部子节点的事件委派给父亲节点
(2)即使你能确定点击的是a标签,如何区分点击的是一级、二级、三级分类的a标签呢?
event是事件对象,可以获取到当前触发事件的节点
解决方法是:把子节点当中a标签,加上自定义属性data-categoryName,其余的子节点是没有的;一级、二级、三级分类的a标签也通过添加自定义属性来判断
<div class="all-sort-list2" @click="goSearch">
<div
class="item"
v-for="(c1, index) in categoryList"
:key="c1.categoryId"
@mouseenter="changeIndex(index)"
:class="{ cur: currentIndex === index }"
>
<h3>
<!-- 给a标签添加自定义属性 -->
<a
:data-categoryName="c1.categoryName"
:data-category1Id="c1.categoryId"
>{{ c1.categoryName }}</a>
</h3>
<!-- 二三级分类 -->
<div
class="item-list clearfix"
:style="{
display: currentIndex === index ? 'block' : 'none',
}"
>
<div
class="subitem"
v-for="c2 in c1.categoryChild"
:key="c2.categoryId"
>
<dl class="fore">
<dt>
<a
:data-categoryName="c2.categoryName"
:data-category2Id="c2.categoryId"
>{{ c2.categoryName }}</a
>
</dt>
<dd>
<em v-for="c3 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>
goSearch(event) { //event.target:获取到的是触发事件的元素(div、h3、a、em、dt、dl) let node = event.target; //给a标签添加自定义属性data-categoryName,全部的字标签当中只有a标签带有自定义属性,别的标签名字----dataset纯属扯淡 let { categoryname, category1id, category2id, category3id } = node.dataset; //第二个问题解决了:点击的到底是不是a标签(只要这个标签身上带有categoryname)一定是a标签 //当前这个if语句:一定是a标签才会进入 if (categoryname) { //准备路由跳转的参数对象 let loction = { name: "search" }; let query = { categoryName: categoryname }; //一定是a标签:一级目录 if (category1id) { query.category1Id = category1id; //一定是a标签:二级目录 } else if (category2id) { query.category2Id = category2id; //一定是a标签:三级目录 } else { query.category3Id = category3id; } //判断:如果路由跳转的时候,带有params参数,捎带脚传递过去 if (this.$route.params) { loction.params = this.$route.params; //动态给location配置对象添加query属性 loction.query = query; //路由跳转 this.$router.push(loction); } } },

浙公网安备 33010602011771号