You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue router-link仅首次点击生效问题排查求助

问题根源及解决方案

你遇到的问题是Vue组件复用导致的生命周期钩子不触发——当你在News.vue里点击不同的路由链接时,Topnews.vue组件并没有被销毁重建,而是被复用了,所以created钩子只会在第一次加载时执行一次,后续路由参数变化时不会重新获取数据。

下面是两种最常用的解决方法:

方法1:监听路由变化(watch $route)

修改Topnews.vue的script部分,添加watch监听$route的变化,每当路由参数更新时重新请求数据:

<template id="topnews1">
  <div class="col-sm-7">
    <div class="cars">
      <img :src="topnews.thumb" class="img-responsive" width=100%/>
      <div class="name" ><h3>{{ topnews.title }}</h3>
        <p>
          <br>{{ topnews.info }}<br/>
        </p>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data:function(){
    return {topnews: {title: '', thumb: '', info: ''}}
  },
  created:function() {
    this.fetchData(); // 把请求逻辑抽成方法,方便复用
  },
  watch: {
    '$route': function(to) {
      this.fetchData(to.params.id);
    }
  },
  methods: {
    fetchData(id = this.$route.params.id) {
      let uri = '/news/' + id;
      Axios.get(uri).then((response) => {
        this.topnews = response.data;
      });
    }
  }
}
</script>

这里把数据请求逻辑抽成了fetchData方法,既可以在created里初始化调用,也可以在路由变化时调用,保持代码复用性。

方法2:使用路由守卫beforeRouteUpdate

Vue提供了专门的路由守卫beforeRouteUpdate,用于在当前路由改变但组件被复用时触发,你可以用它来更新数据:

<template id="topnews1">
  <!-- 模板部分不变 -->
</template>
<script>
export default {
  data:function(){
    return {topnews: {title: '', thumb: '', info: ''}}
  },
  created:function() {
    this.fetchData();
  },
  beforeRouteUpdate(to, from, next) {
    // 获取新的路由参数id,重新请求数据
    this.fetchData(to.params.id);
    next(); // 必须调用next()才能完成导航
  },
  methods: {
    fetchData(id = this.$route.params.id) {
      let uri = '/news/' + id;
      Axios.get(uri).then((response) => {
        this.topnews = response.data;
      });
    }
  }
}
</script>

这种方法更贴近路由相关的逻辑处理,适合需要在路由切换前做一些操作的场景。

额外方法:强制组件销毁重建(不推荐,除非必要)

如果你不想修改Topnews.vue的代码,也可以在父组件的<router-view>上绑定:key="$route.fullPath",这样每次路由变化时都会销毁重建组件,从而触发created钩子:

<router-view :key="$route.fullPath"></router-view>

不过这种方法会带来组件销毁重建的性能开销,所以优先推荐前两种方法。

为什么原来的代码会出现这种情况?

当Vue-router发现当前组件可以复用时(比如从/news/1到/news/2,都是同一个Topnews组件),它会复用现有组件实例,而不是创建新的。这是Vue的性能优化策略,但也导致created、mounted这类只会执行一次的钩子不会再次触发,所以我们需要手动监听路由变化来更新数据。

内容的提问来源于stack exchange,提问作者mr Enthusiast

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:53:11