首次加载组件时,VueJS导航栏活动卡指示器未指向

htrmnn0y  于 2022-12-23  发布在  Vue.js
关注(0)|答案(1)|浏览(132)

我的导航栏指示器有问题(下面屏幕截图中的蓝色下划线)

指示器工作正常,但当您打开页面第一次(或重新加载)指示器不出现,并在控制台中有一个错误:Active link not found.。我认为,这种行为的原因是当mounted事件被调用时,路由器没有完全加载。
我的Navbar组件的代码:

<template>
  <nav>
    <RouterLink to="/"><img :src="logo" alt="Logo" /></RouterLink>
    <div class="navigationwrapper">
      <ul class="links" @mouseleave="fixIndicator">
        <li v-for="({ route, name, routeName }, index) in navLinks" @mouseenter="moveIndicator" :route-name="routeName" ref="navigationLinks">
          <RouterLink :to="route">{{ name }}</RouterLink>
        </li>
      </ul>
      <span id="indicator"></span>
    </div>
  </nav>
</template>
<script>
import { animate } from "motion";
import { RouterLink } from "vue-router";
import logo from "../assets/img/logo.png";

export default {
  name: "Navbar",
  data() {
    return {
      logo: logo,
      navLinks: [
        {
          route: "/",
          routeName: "home",
          name: "Home",
        },
        {
          route: "/about",
          routeName: "about",
          name: "About",
        },
        {
          route: "/team",
          routeName: "team",
          name: "Team",
        },
        {
          route: "/demo",
          routeName: "demo",
          name: "Demo",
        },
      ],
    };
  },
  methods: {
    moveIndicator(e) {
      console.log(this.activeLink());
      const node = e.target;
      const nodeLeft = node.offsetLeft;
      const nodeWidth = node.offsetWidth;
      animate("#indicator", { width: `${nodeWidth}px`, left: `${nodeLeft}px` }, { duration: 0.2, easing: "ease-in-out" });
    },
    fixIndicator() {
      const node = this.activeLink();
      if (node == null) {
        console.error("Active link not found.");
        return;
      }
      const nodeLeft = node.offsetLeft;
      const nodeWidth = node.offsetWidth;
      animate("#indicator", { width: `${nodeWidth}px`, left: `${nodeLeft}px` }, { duration: 0.2, easing: "ease-in-out" });
    },
    activeLink() {
      return this.$refs.navigationLinks.find((link) => {
        return link.getAttribute("route-name") == this.$route.name;
      });
    },
  },
  mounted() {
    this.fixIndicator();
  },
};
</script>

我认为在路由器满负荷后的某种事件可以解决这个问题,但我不知道一个,也没有找到。
我用于动画的库:https://motion.dev

ryevplcw

ryevplcw1#

这个问题的一个解决方案是将调用这个.fixIndicator从挂载的钩子转移到正在呈现的路径组件中的beforeRouteEnter钩子。beforeRouteEnter钩子在路径组件解析之后,在输入路径之前被调用,因此它是更新活动链接指示符的好地方。
我做过类似这样的事情,但它不起作用,调用该事件的方法正确吗?没有console.log,因此函数甚至不执行。

export default {
  name: "Navbar",
  beforeRouteEnter(to, from, next) {
    console.log("test");
    this.fixIndicator();
  },
  data() {
    return {
      logo: logo,
      navLinks: [
        {
          route: "/",
          routeName: "home",
          name: "Home",
        },
        {
          route: "/about",
          routeName: "about",
          name: "About",
        },
        {
          route: "/team",
          routeName: "team",
          name: "Team",
        },
        {
          route: "/demo",
          routeName: "demo",
          name: "Demo",
        },
      ],
    };
  },
  methods: {
    moveIndicator(e) {
      const node = e.target;
      const nodeLeft = node.offsetLeft;
      const nodeWidth = node.offsetWidth;
      animate("#indicator", { width: `${nodeWidth}px`, left: `${nodeLeft}px` }, { duration: 0.2, easing: "ease-in-out" });
    },
    fixIndicator() {
      const node = this.activeLink();
      if (node == null) {
        console.error("Active link not found.");
        return;
      }
      const nodeLeft = node.offsetLeft;
      const nodeWidth = node.offsetWidth;
      animate("#indicator", { width: `${nodeWidth}px`, left: `${nodeLeft}px` }, { duration: 0.2, easing: "ease-in-out" });
    },
    activeLink() {
      return this.$refs.navigationLinks.find((link) => {
        return link.getAttribute("route-name") == this.$route.name;
      });
    },
  },
};

相关问题