a标签的href属性与事件修饰符阻止默认行为

讲一下遇到的问题

  1. 下面的截图,我在点击左侧导航栏的一级二级三级分类时,会跳转到Search页面,但是我在触发click事件进行跳转的时候,老是无法正常跳转,会跳转到首页,然后点击浏览器回退按钮会回退到search页面。
    在这里插入图片描述
  2. 这是我想跳转的地址在这里插入图片描述
  3. 然而却总是跳转到首页

代码

<template>
  <!-- 商品分类导航 -->
  <div class="type-nav">
    <div class="container">
      <!-- 事件委派 -->
      <div @mouseleave="leaveIndex" @click.prevent="goSearch">
        <h2 class="all">全部商品分类</h2>
        <div class="sort">
          <div class="all-sort-list2">
            <div
              class="item"
              v-for="(item, index) in categoryList"
              :key="item.categoryId"
              :class="{ bo: currentIndex == index }"
            >
              <h3 @mouseenter="changeIndex(index)">
                <a href="" :data-categoryName="item.categoryName" :data-category1Id="item.categoryId">{
    
    {
    
     item.categoryName }}</a>
              </h3>
              <!-- 二级、三级分类 -->
              <div
                class="item-list clearfix"
                :style="{ display: currentIndex == index ? 'block' : 'none' }"
              >
                <div
                  class="subitem"
                  v-for="subitem in item.categoryChild"
                  :key="subitem.categoryId"
                >
                  <dl class="fore">
                    <dt>
                      <a href="" :data-categoryName="subitem.categoryName" :data-category2Id="subitem.categoryId">{
    
    {
    
     subitem.categoryName }}</a>
                    </dt>
                    <dd>
                      <em
                        v-for="item3 in subitem.categoryChild"
                        :key="item3.categoryId"
                      >
                        <a href="" :data-categoryName="item3.categoryName" :data-category3Id="item3.categoryId">{
    
    {
    
     item3.categoryName }}</a>
                      </em>
                    </dd>
                  </dl>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <nav class="nav">
        <a href="###">服装城</a>
        <a href="###">美妆馆</a>
        <a href="###">尚品汇超市</a>
        <a href="###">全球购</a>
        <a href="###">闪购</a>
        <a href="###">团购</a>
        <a href="###">有趣</a>
        <a href="###">秒杀</a>
      </nav>
    </div>
  </div>
</template>

<script>
import {
    
     mapState } from "vuex";
// 引入第三方插件使用节流
import throttle from "lodash/throttle";
export default {
    
    
  name: "TypeNav",
  data() {
    
    
    return {
    
    
      // 鼠标滑过的一级菜单的index,切记初始值不能为0
      currentIndex: -1,
    };
  },
  mounted() {
    
    
    // 分发action,通知vuex,可以向服务器发送请求,获取数据,存取在仓库当中
    this.$store.dispatch("categoryList");
  },
  computed: {
    
    
    // 预测需要是一个函数,当这个计算属性使用时,这个函数就执行一次
    // 会注入一个state,这个state就是大仓库中的state
    ...mapState({
    
    
      categoryList: (state) => state.home.categoryList,
    }),
  },
  methods: {
    
    
    // 鼠标进入修改响应式数据currentIndex的值
    // 节流:用户操作很频繁,但是把频繁的操作变成少量的的操作,【可以给浏览器有充裕的时间解析代码】
    // 防抖:用户操作很频繁,只执行最后一次
    changeIndex: throttle(function (index) {
    
    
      this.currentIndex = index;
    }, 50),
    leaveIndex() {
    
    
      this.currentIndex = -1;
    },
    //精益求精
    //将全部的子节点的事件委派给父节点->事件回调就一个
    goSearch(event) {
    
    
      //第一个问题:div父节点子元素太多【h3、h2、em、dt、dd、dl...a】?你怎么知道你点击的一定是a
      //第二个问题:要区分一级分类、二级分类、三级分类的a标签【category1Id|category2Id|category2Id】
      let targetNode = event.target;
      //获取触发事件节点的自定义属性【a:data-categoryName】
      let {
    
     categoryname, category1id, category2id, category3id } =
        targetNode.dataset;
      //判断点击的是a【不管是1|2|3】
      if (categoryname) {
    
    
        //点击只要是a,就是往search模块跳转
        var locations = {
    
    
          name: "search",
          query: {
    
     categoryName: categoryname },
        };
        //一级分类的a
        if (category1id) {
    
    
          console.log("category1id-------", category1id);
          locations.query.category1Id = category1id;
        } else if (category2id) {
    
    
          //二级分类的a
          locations.query.category2Id = category2id;
        } else {
    
    
          //三级分类的a
          locations.query.category3Id = category3id;
        }
        //点击商品分类按钮的时候,如果路径当中携带params参数,需要合并携带给search模块
        if (this.$route.params.keyword) {
    
    
          locations.params = this.$route.params;
        }
        //目前商品分类这里携带参数只有query参数
        this.$router.push(locations);
      }
    },
  },
};
</script>

<style lang="less" scoped>
.type-nav {
    
    
  border-bottom: 2px solid #e1251b;

  .container {
    
    
    width: 1200px;
    margin: 0 auto;
    display: flex;
    position: relative;

    .all {
    
    
      width: 210px;
      height: 45px;
      background-color: #e1251b;
      line-height: 45px;
      text-align: center;
      color: #fff;
      font-size: 14px;
      font-weight: bold;
    }

    .nav {
    
    
      a {
    
    
        height: 45px;
        margin: 0 22px;
        line-height: 45px;
        font-size: 16px;
        color: #333;
      }
    }

    .sort {
    
    
      position: absolute;
      left: 0;
      top: 45px;
      width: 210px;
      height: 461px;
      position: absolute;
      background: #fafafa;
      z-index: 999;

      .all-sort-list2 {
    
    
        .item {
    
    
          h3 {
    
    
            line-height: 30px;
            font-size: 14px;
            font-weight: 400;
            overflow: hidden;
            padding: 0 20px;
            margin: 0;

            a {
    
    
              color: #333;
            }
          }

          .item-list {
    
    
            display: none;
            position: absolute;
            width: 734px;
            min-height: 460px;
            background: #f7f7f7;
            left: 210px;
            border: 1px solid #ddd;
            top: 0;
            z-index: 9999 !important;

            .subitem {
    
    
              float: left;
              width: 650px;
              padding: 0 4px 0 8px;

              dl {
    
    
                border-top: 1px solid #eee;
                padding: 6px 0;
                overflow: hidden;
                zoom: 1;

                &.fore {
    
    
                  border-top: 0;
                }

                dt {
    
    
                  float: left;
                  width: 54px;
                  line-height: 22px;
                  text-align: right;
                  padding: 3px 6px 0 0;
                  font-weight: 700;
                }

                dd {
    
    
                  float: left;
                  width: 415px;
                  padding: 3px 0 0;
                  overflow: hidden;

                  em {
    
    
                    float: left;
                    height: 14px;
                    line-height: 14px;
                    padding: 0 8px;
                    margin-top: 5px;
                    border-left: 1px solid #ccc;
                  }
                }
              }
            }
          }
        }
        .bo {
    
    
          background-color: skyblue;
        }
      }
    }
  }
}
</style>

下面是我的路由配置文件

// 配置路由, 一定要注意这里是routes,不是routers
    routes: [ 
        {
    
    
            path: '/home',
            component: Home,
            meta: {
    
    
                show: true
            }
        },
        {
    
    
            path: '/login',
            name: 'login',
            component: Login,
            meta: {
    
    
                show: false
            }
        },
        {
    
    
            // 注意占位符是:开头,占位符后面加上一个问号,可传可不传
            path: '/search/:keyword?',
            name: 'search',
            component: Search,
            meta: {
    
    
                show: true
            }
        },
        {
    
    
            path: '/register',
            component: Regsiter,
            meta: {
    
    
                show: false
            }
        },
        {
    
    
            path: '/',
            redirect: '/home'
        }
    ]

问题分析

  1. 首先讲一下,我上面的goSearch方法是使用了事件委派的方式,通过自定义属性categoryname确定了a标签,通过自定义属性categoryid确定了1|2|3级分类
  2. 因为我这个点击事件是a标签触发的,而我的a标签上有一个为空的href属性,这样的话b标签根据空链接地址会有一个默认行为,去跳转
  3. 刚好我也配置了路由重定向,他也就按照最后的重定向去跳转了,跳转至home页面,我点击浏览器回退按钮,就回到了gosearch方法跳转的地址

解决方法

  • 一是去掉a标签的href属性
  • 二是给click事件添加一个prevent事件修饰符阻止默认行为
  • 三是调用preventDefault()或者e.returnValue = false;阻止默认行为
  • 当然,不用a标签这里也可以

补充其他事件修饰符

. capture:捕获冒泡,即有冒泡发生时,有该修饰符的dom元素会先执行,如果有多个,从外到内依次执行,然后再按自然顺序执行触发的事件。

. self:将事件绑定到自身,只有自身才能触发,通常用于避免冒泡事件的影响

. once:设置事件只能触发一次,比如按钮的点击等。

. passive:该修饰符大概意思用于对DOM的默认事件进行性能优化,根据官网的例子比如超出最大范围的滚动条滚动的。

. native:在父组件中给子组件绑定一个原生的事件,就将子组件变成了普通的HTML标签,不加’. native’事件是无法触 发的。
.stop:阻止冒泡
.stop.prevent:串联修饰符

猜你喜欢

转载自blog.csdn.net/m0_56026872/article/details/127067557
今日推荐