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

Vue博客点击侧边栏最新文章链接无法切换渲染内容求助

问题:Vue3单页路由切换后文章内容不更新

在个人项目中,BlogPost.vue用于渲染从Blog.vue点击进入的单篇文章,侧边栏展示3篇最新文章。点击侧边栏链接时,浏览器地址栏的slug已变化,但页面仍显示之前的文章,刷新后才会加载正确内容。需要实现监听路由变化来重新获取文章数据。

原因分析

当前BlogPost.vue仅在组件初始化时调用getPost()获取数据,当路由参数变化时(同组件复用场景),组件不会被销毁重建,因此不会自动触发新的数据请求,导致页面内容未更新。

解决代码(修改后的BlogPost.vue)

<script setup lang="ts">
import { ref, watch, onMounted } from "vue";
import { useRoute } from "vue-router";
import axios from "axios";
import moment from "moment";

const route = useRoute();

const postsUrl = "http://localhost/wordpress/wp-json/wp/v2/posts";
const post = ref([] as any);
const isLoading = ref(false);

const latestPostsAPI = "http://localhost/wordpress/wp-json/wp/v2/posts";
const latestPosts = ref([] as any);
const errorCaughtLatest = ref(false);

const queryOptionsLatest = {
  _embed: true,
  per_page: 3,
};

const getLatest = () => {
  axios
    .get(latestPostsAPI, { params: queryOptionsLatest })
    .then((response) => {
      latestPosts.value = response.data;
    })
    .catch((error) => {
      errorCaughtLatest.value = true;
    });
};

const getPost = () => {
  isLoading.value = true;
  // 动态生成查询参数,确保每次请求用最新路由slug
  const queryOptions = {
    slug: route.params.blogSlug,
    _embed: true,
  };
  axios
    .get(postsUrl, { params: queryOptions })
    .then((response) => {
      post.value = response.data;
    })
    .catch((error) => {
      console.log(error);
    })
    .finally(() => {
      isLoading.value = false;
    });
};

// 监听路由slug变化,自动重新获取文章
watch(
  () => route.params.blogSlug,
  () => {
    getPost();
  }
);

onMounted(() => {
  getLatest();
  getPost();
});
</script>

<template>
  <div v-if="!isLoading" class="post-wrapper">
    <div class="wrapper">
      <div class="post-title">{{ post[0].title.rendered }}</div>
      <div class="post-date">
        {{ moment(post[0].date).format("MMMM Do YYYY, h:mm, dddd") }}
      </div>
      <div class="post-content" v-html="post[0].content.rendered"></div>
    </div>
  </div>
  <div class="side-container">
    <div class="side-wrapper">
      <ul v-if="!isLoading" class="blog-posts-ul" v-for="latest in latestPosts" :key="latest.id">
        <div class="posts-card">
          <router-link :to="`/blog/${latest.slug}`" class="posts-permalink"></router-link>
          <img
            v-if="latest.featured_media != 0"
            class="posts-featuredimage"
            :src="latest._embedded['wp:featuredmedia'][0].source_url"
            :alt="latest.title.rendered"
          />
          <img v-else src="@/assets/logos/favicon-big.png" />
          <div class="posts-text">
            <div class="posts-title">{{ latest.title.rendered }}</div>
            <div class="posts-date">
              <p>{{ moment(latest.date).fromNow() + " ago" }}</p>
            </div>
            <div class="posts-author">
              {{ latest._embedded.author[0].name }}
            </div>
          </div>
        </div>
      </ul>
    </div>
  </div>
</template>

关键修改点

  • 将queryOptions移到getPost()内部,确保每次请求都使用最新的路由参数
  • 添加watch监听route.params.blogSlug,参数变化时自动触发getPost()
  • 把初始化数据请求放到onMounted钩子中,符合Vue组件生命周期规范
  • 优化router-link写法,使用模板字符串更简洁
  • 给列表渲染添加:key属性,符合Vue性能优化要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 06:56:55