三级联动组件的路由的跳转与传参

三级联动,用户可以点击的:一级分类、二级分类、三级分类,当你点击的时候

以商城项目为例,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);
        }
      }
    },
posted @ 2022-05-21 22:36  yeqi7  阅读(266)  评论(0)    收藏  举报