编程式导航 + 事件委派,实现路由跳转

一、问题说明

 如图所示,在项目中三级联动,要实现路由跳转跳转,有两种方法:

  • 编程式导航: this.$router.push( ) 、this.$router.replace( ),通过触发点击事件实现路由跳转,有多少个 a 标签,就会有多少个触发函数。不会造成卡顿,但是也对性能有一定的影响。
  • 声明式导航:router-link 标签实现,可以实现路由的跳转以及参数的传递,但是由于 router-link 是一个组件,相当于 VueComponent类的实例对象,当服务器的数据返回之后,一瞬间出现了很多个 router-link 组件,很消耗内存,会出现卡顿的现象。

只使用编程式导航或者声明式导航,都会对性能产生影响。

二、解决方法

1.可以使用编程式导航配合事件委派,实现三级路由跳转的效果。

事件委派把子节点的事件都委托给父节点,只需要调用一次回调函数,即可实现效果。

2.使用事件委派(三级联动)遇到的问题:

(1)把事件委派给父节点之后,父节点下的全部子节点都可以触发事件,怎么判断触发事件的节点是否为 a 标签呢?

(2)如果确定了是 a 标签触发事件,如何确定是一级、二级、三级中的哪一级触发了事件呢?同时,要如何在路由跳转的同时传递参数呢?

3.解决方法

对于第一个问题:给每一级的 a 标签都添加自定义属性 data-categoryName 绑定该商品的名称(其余标签无该属性)

对于第二个问题:给一、二、三级的 a标签分别添加data-category1Id 、data-category2Id 、data-category3Id 自定义属性,绑定该商品的ID,以此区分。同时,在函数中传入参数event  ,获取当前的点击事件,通过event.target属性获取当前点击节点。节点有一个dataset 属性,可以获取节点的自定义属性 (event.target.dataset)  。给标签添加自定义属性的时候,把路由跳转时需要传递的参数categoryName和categoryId分别绑定给自定义属性,触发点击事件时,通过event.target.dataset配合解构直接获取,并使用 this.$router.push( )直接传递即可。

注意:event是系统属性,所以我们只需要在函数定义的时候作为参数传入,在函数使用的时候不需要传入该参数。

4.完整代码

<!-- 三级联动 -->
<div class="sort">
  <!-- 利用事件委派结合编程式导航实现路由的跳转与传递参数 -->
  <div class="all-sort-list2" @click="goSearch">
    <!-- 一级分类 -->
    <div class="item" v-for="(c1, index) in categoryList.slice(0, 16)" :key="c1.categoryId"
      :class="{cur: currentIndex===index}">
      <h3 @mouseenter="changeIndex(index)">
        <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, index) 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, 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 函数:

// 进行路由跳转的方法
goSearch(event) {
  // 最好的解决方案就是利用 编程式导航 + 事件委派
  // 存在一些问题:事件委派,是把全部的子节点【h3 dt dl em】的事件委派给父节点
  // 点击a标签才会进行路由的跳转【1:判断点击的是否是a标签 2:如何获取参数【1、2、3级分类的产品的名字、ID】(如何确定点击的是 1级、2级还是3级分类的a标签)
  // 第一个问题:把子节点当中a标签,加上自定义属性 data-categoryName,其余子节点没有
  let element = event.target;
  // 获取到当前触发事件的节点,有可能是各种元素,需要带有 data-categoryname 属性的节点【一定是a标签】
  // 节点有一个属性,dataset 属性,可以获取节点的自定义属性 event.target.dataset , event.target.dataset.categoryName
  let { categoryname, category1id, category2id, category3id } = element.dataset;
  // 如果标签身上有 categoryname 属性,一定是 a 标签
  if (categoryname) {
    // 当点击标签,参数包括 name id,整理路由跳转的参数
    let location = { name: 'search' };
    let query = { categoryName: categoryname };
    // 一级分类、二级分类、三级分类的 a 标签,再分别添加属性 data-category1Id data-category2Id data-category3Id 以此区分一、二、三级分类
    if (category1id) {
      query.category1Id = category1id;
    } else if (category2id) {
      query.category2Id = category2id;
    } else {
      query.category3Id = category3id;
    }
    // 整理完参数
    location.query = query;
    // 路由跳转
    this.$router.push(location);
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值