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

Vue模板渲染前data值设置异常,router-link参数缺失求助

解决Vue中RouterLink因用户数据加载时机导致的缺失参数问题

问题核心

  1. App.vue异步逻辑错误:beforeCreate是同步钩子,调用getUser(异步函数)时未加await,导致用户数据还没获取完成就提交到store,此时store中的user_1/user_2是未resolved的Promise或空值。
  2. StartPage模板渲染时机问题:模板渲染时,组件本地的user_1/user_2还是初始空对象,访问username会返回undefined,触发RouterLink必填参数缺失的错误。

解决方案

1. 修复App.vue的异步数据加载逻辑

将beforeCreate改为异步钩子,确保用户数据获取完成后再提交到store:

async beforeCreate() {
    await this.$store.dispatch("initializeUser");
    try {
      // 等待getUser返回实际用户数据
      this.user_1 = await getUser("lukasz");
      this.user_2 = await getUser("karolina");
      this.$store.commit("setUser_1", this.user_1);
      this.$store.commit("setUser_2", this.user_2);
    } catch (error) {
      console.error("Error fetching users:", error);
    }
  },

2. 修改StartPage组件,优化数据响应与模板渲染

  • 用计算属性直接从store获取用户数据,确保数据更新时自动响应
  • 添加v-if判断,仅当用户数据存在时渲染RouterLink,避免空值报错
<template>
  <div>
    <!-- 确保user_2存在且有username才渲染 -->
    <router-link 
      v-if="user_2 && user_2.username"
      class="user2" 
      :to="{name: 'User View', params: {user: user_2.username}}"
    >
      <div class="split left" @mouseover="setHearts" @click="setSelectedUser(user_2)">
        <div class="centered">
          <button>{{ user_2.username }}</button>
        </div>
        <HeartIcon v-for="index in hearts" :key="index" class="heart"></HeartIcon>
      </div>
    </router-link>

    <!-- 确保user_1存在且有username才渲染 -->
    <router-link 
      v-if="user_1 && user_1.username"
      class="user1" 
      :to="{name: 'User View', params: {user: user_1.username}}"
    >
      <div class="split right" @mouseover="setFootballs" @click="setSelectedUser(user_1)">
        <div class="centered">
          <button class="button-text">{{ user_1.username }}</button>
        </div>
        <FootballIcon v-for="index in footballs" :key="index" class="football"></FootballIcon>
      </div>
    </router-link>

    <!-- 可选:添加加载状态提示 -->
    <div v-if="!user_1?.username || !user_2?.username">加载中...</div>
  </div>
</template>

<script>
import HeartIcon from "@/components/Heart.vue";
import FootballIcon from "@/components/Football.vue";

export default {
  name: 'StartPage',
  computed: {
    // 直接从store获取用户数据,实时响应更新
    user_1() {
      return this.$store.state.user_1 || {};
    },
    user_2() {
      return this.$store.state.user_2 || {};
    }
  },
  data() {
    return {
      hearts: 10,
      footballs: 10
    }
  },
  components: {
    HeartIcon,
    FootballIcon
  },
  methods: {
    setHearts() {
      const hearts = document.querySelectorAll('.left .heart');
      hearts.forEach(heart => {
        const maxTop = window.innerHeight - heart.clientHeight;
        const maxLeft = window.innerWidth - heart.clientWidth;
        const randomTop = Math.random() * maxTop;
        const randomLeft = Math.random() * maxLeft;
        heart.style.top = `${randomTop}px`;
        heart.style.left = `${randomLeft}px`;
        heart.style.transform = `rotate(${Math.random() * 90 - 45}deg)`;
      });
    },
    setFootballs() {
      const footballs = document.querySelectorAll('.right .football');
      footballs.forEach(football => {
        const maxTop = window.innerHeight - football.clientHeight;
        const maxLeft = window.innerWidth - football.clientWidth;
        const randomTop = Math.random() * maxTop;
        const randomLeft = Math.random() * maxLeft;
        football.style.top = `${randomTop}px`;
        football.style.left = `${randomLeft}px`;
        football.style.transform = `rotate(${Math.random() * 90 - 45}deg)`;
      });
    },
    async setSelectedUser(user) {
      try {
        await this.$store.dispatch("setSelectedUser", user);
      } catch (error) {
        console.error("Error setting selected user:", error);
      }
    }
  }
}
</script>

3. 优化App.vue的hasUser判断逻辑

确保只有两个用户数据都就绪时,才切换到主页面:

<template>
  <div id="wrapper">
    <StartPage v-if="!hasUser" />
    <div v-else>
      <Navbar />
      <section class="section">
        <router-view />
      </section>
    </div>
  </div>
</template>

<script>
// ...其他代码
computed: {
  hasUser() {
    // 检查两个用户的username是否存在
    return this.$store.state.user_1?.username && this.$store.state.user_2?.username;
  }
}
// ...其他代码
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:54:54