自学内容网 自学内容网

Vue3嵌套导航相对路径问题

有如下的页面设计,页面上方第一次导航,两个菜单,首页和新闻
点击新闻,内容里面嵌套一个左侧和右侧,左侧有4条新闻,点击某一条新闻,右侧显示详情

代码如下:

​
File Path: d:\hello\src\App.vue
<template>
  <div id="app">
    <nav>
      <router-link to="/">Home</router-link>
      <router-link to="/news">News</router-link>
    </nav>
    <router-view></router-view> <!-- 用于渲染当前路由匹配的组件 -->
  </div>
</template>

<script lang="ts">
export default {
  name: 'App'
};
</script>

<style>
nav {
  display: flex;
  justify-content: center;
  margin-bottom: 20px;
}

nav a {
  margin: 0 15px;
  text-decoration: none;
  color: #42b983;
}
</style>

File Path: d:\hello\src\views\NewsDetail.vue
<template>
  <div>
    <h2>News Detail {{ id }}</h2>
    <p>This is the detail of the news with ID: {{ id }}</p>
  </div>
</template>

<script lang="ts">
import { defineComponent, computed, onMounted } from 'vue'; // 确保只导入一次
import { useRoute } from 'vue-router';

export default defineComponent({
  name: 'NewsDetail',
  setup() {
    const route = useRoute();
    const id = computed(() => route.params.id);

    // 在组件挂载时打印 ID
    onMounted(() => {
      console.log('Entered NewsDetail with ID:', route.params.id);
    });

    return { id };
  }
});
</script>

File Path: d:\hello\src\router\index.ts
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/HomeView.vue'; // 确保路径正确
import News from '../views/News.vue'; // 确保路径正确
import NewsDetail from '../views/NewsDetail.vue'; // 确保路径正确

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/news',
    name: 'News',
    component: News,
    children: [
      {
        path: 'detail/:id', // 使用动态参数
        name: 'NewsDetail',
        component: NewsDetail
      }
    ]
  }
];

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes
});

export default router;

File Path: d:\hello\src\views\News.vue
<template>
  <div>
    <h1>News</h1>
    <ul>
      <li>
        <router-link to="detail/1">News Detail 1</router-link>
      </li>
      <li>
        <router-link to="news/detail/2">News Detail 2</router-link>
      </li>
      <a href="detail/1">a标签 news 3</a>
    </ul>
    <router-view></router-view> <!-- 用于渲染子路由的内容 -->
  </div>
</template>

<script lang="ts">
export default {
  name: 'News',
  mounted() {
       console.log(this.$route.path); // 这里可以访问当前路径
     }
};
</script>

File Path: d:\hello\src\main.ts
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

const app = createApp(App);

app.use(router);

app.mount('#app');

File Path: d:\hello\src\views\HomeView.vue
<template>
  <div>
    <h1>Welcome to the Home Page</h1>
    <p>This is the home page content.</p>
  </div>
</template>

<script lang="ts">
export default {
  name: 'HomeView'
};
</script>

File Path: d:\hello\src\views\AboutView.vue
<template>
  <div class="about">
    <h1>This is an about page</h1>
  </div>
</template>

<style>
@media (min-width: 1024px) {
  .about {
    min-height: 100vh;
    display: flex;
    align-items: center;
  }
}
</style>


​

首先点击 首页,然后点击新闻,当前的网址是:
http://localhost:5173/news
然后点击News detail 1,发现网址变成了:
http://localhost:5173/detail/1

 并且页面空白了,因为没有找到路由/detail
为什么会跳转到 http://localhost:5173/detail/1 而不是 http://localhost:5173/news/detail/1,这里不是写的相对路径吗?
可以参考下面的a标签,也是这样跳转的,个人觉得在当前路径是http://localhost:5173/news的时候,访问相对路径detail,就相当于一个文件夹是http://localhost:5173/,news相当于news.html,而detail和他是同级的,所以相对路径会解析为http://localhost:5173/detail
而路由中,detail和news不是同级关系
如果要写相对路径,也只能写成

to="news/detail/1"

即使写成./detail/1也不行 
这里是讨论相对路径的问题,当然,写成下面也是可以的

:to="{ name: 'NewsDetail', params: { id: 1 } }"






----------
 

Vue3 嵌套导航相对路径问题

在现代前端开发中,使用 Vue.js 进行单页面应用(SPA)的构建已成为一种趋势。Vue3 引入了许多新特性,使得开发变得更加灵活和高效。然而,在处理嵌套路由时,相对路径的问题往往会让开发者感到困惑。

页面设计

设想一个简单的页面设计:在页面的顶部有一个导航栏,用户可以选择 “首页” 和 “新闻”。当用户点击 “新闻” 时,页面中会显示一个包含左侧和右侧的布局。在左侧,用户可以看到四条新闻,点击其中一条后,右侧会显示该新闻的详细信息。

路由配置

在 Vue3 中,路由的配置是通过 vue-router 来实现的。以下是路由的基本配置:

javascript

Copy

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/news',
    name: 'News',
    component: News,
    children: [
      {
        path: 'detail/:id',
        name: 'NewsDetail',
        component: NewsDetail
      }
    ]
  }
];

在这个配置中,/news 路由下嵌套了一个 detail/:id 路由,用于显示新闻的详细信息。

相对路径的问题

当用户在 /news 路由下点击某个新闻链接时,理应跳转到 /news/detail/1。然而,开发者可能会发现,点击链接后,浏览器跳转到了 /detail/1,导致页面空白。这是因为 Vue Router 在解析相对路径时,默认是从根路径 / 开始的。

这种情况下,用户需要明确指定完整的相对路径,例如:

html

Copy

<router-link to="detail/1">News Detail 1</router-link>

或者使用命名路由:

html

Copy

<router-link :to="{ name: 'NewsDetail', params: { id: 1 } }">News Detail 1</router-link>

深入理解 Vue Router

在 Vue Router 中,路由的解析是基于路径的层级结构。当你在 /news 路由下执行相对路径跳转时,Vue Router 会根据当前路由的层级关系来解析路径。因此,理解路由的层级结构对于正确使用相对路径至关重要。

例如,若当前路径为 /news,想要访问 /news/detail/1,则需要使用相对路径 detail/1,而不是直接使用 detail/1。这就像在文件系统中,想要从一个文件夹访问另一个文件夹下的文件,必须明确指定路径。

结论

在 Vue3 中处理嵌套路由时,理解相对路径的解析机制是非常重要的。通过合理配置路由和使用合适的路径表示法,开发者可以避免常见的路径解析错误,从而提升用户体验。希望本文能帮助你更好地理解 Vue3 中嵌套导航的相对路径问题,提升你的开发效率。


 

进一步探索 Vue3 嵌套导航的最佳实践

在深入理解 Vue3 中嵌套导航的相对路径问题后,我们可以探讨一些最佳实践,以确保在项目中高效且无误地使用这些特性。

1. 使用命名路由

命名路由不仅能提高代码的可读性,还能减少路径错误的可能性。使用命名路由时,开发者可以避免手动拼接路径,从而提高代码的可维护性。例如:

html

Copy

<router-link :to="{ name: 'NewsDetail', params: { id: news.id } }">
  {{ news.title }}
</router-link>

这种方式使得代码更具可读性,并且在路由变化时,开发者不需要担心路径的调整。

2. 路由守卫

在复杂的应用程序中,可能需要在路由切换时执行一些逻辑,比如权限验证或数据预加载。使用 Vue Router 的路由守卫,可以在进入某个路由之前进行检查:

javascript

Copy

router.beforeEach((to, from, next) => {
  if (to.name === 'NewsDetail' && !userIsLoggedIn()) {
    next({ name: 'Login' });
  } else {
    next();
  }
});

这种方式能够确保用户在访问特定页面前满足某些条件,从而提升应用的安全性。

3. 动态路由匹配

在处理新闻详情时,通常会有多个新闻项。利用动态路由匹配,可以轻松实现这一功能。通过在路由中定义动态参数,Vue Router 会自动解析并传递参数:

javascript

Copy

{
  path: '/news/detail/:id',
  name: 'NewsDetail',
  component: NewsDetail
}

在 NewsDetail 组件中,可以通过 this.$route.params.id 获取当前新闻的 ID,从而加载相应的数据。

4. 组件懒加载

为了提升应用的性能,尤其是在大型应用中,使用组件懒加载是一个不错的选择。通过 import() 函数,可以实现路由的按需加载:

javascript

Copy

const NewsDetail = () => import('./components/NewsDetail.vue');

const routes = [
  {
    path: '/news/detail/:id',
    name: 'NewsDetail',
    component: NewsDetail
  }
];

这种方式不仅可以减少初始加载时间,还能提升用户体验。

5. 设计良好的用户体验

在嵌套导航中,良好的用户体验至关重要。可以考虑以下几点:

  • 面包屑导航:帮助用户了解当前页面的位置,并方便地返回上级页面。
  • 加载指示器:在数据加载时提供视觉反馈,提升用户的等待体验。
  • 错误处理:处理路由错误时,提供友好的错误页面,避免用户感到困惑。

6. 维护良好的代码结构

在大型项目中,代码的结构和组织显得尤为重要。建议将路由配置、组件和视图分开管理,保持代码的清晰和可维护性。例如,可以在 router 目录中集中管理所有路由配置,在 views 目录中集中管理所有视图组件。

总结

在 Vue3 中,嵌套导航和相对路径的管理虽然可能会带来一些挑战,但通过合理的设计和最佳实践,可以有效地解决这些问题。无论是使用命名路由、动态路由匹配,还是组件懒加载,都是提升开发效率和用户体验的有效手段。

希望通过本篇文章的深入探讨,能够帮助开发者在实际项目中更好地应用 Vue3 的嵌套导航特性,构建出更高效、用户友好的应用。随着前端技术的不断发展,掌握这些技巧将为你的开发之路铺平道路。


 

深入理解 Vue3 的嵌套导航与状态管理

在构建复杂的 Vue3 应用时,除了嵌套导航和路由管理,状态管理同样是一个不可忽视的方面。Vuex 是 Vue.js 官方的状态管理库,能够帮助我们在多个组件间共享状态。结合 Vue Router 使用时,可以使得应用的结构更加清晰和高效。

1. Vuex 与嵌套导航的结合

在处理嵌套导航时,可能需要在不同的页面之间共享数据。例如,在新闻列表页面和新闻详情页面之间,用户可能需要看到相同的新闻数据。通过 Vuex,我们可以将这些数据存储在全局状态中,方便各个组件访问。

Vuex Store 示例

javascript

Copy

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    newsList: [],
    currentNews: null
  },
  mutations: {
    setNewsList(state, news) {
      state.newsList = news;
    },
    setCurrentNews(state, news) {
      state.currentNews = news;
    }
  },
  actions: {
    fetchNews({ commit }) {
      // 假设有一个 API 获取新闻数据
      fetch('/api/news')
        .then(response => response.json())
        .then(data => {
          commit('setNewsList', data);
        });
    },
    fetchNewsDetail({ commit }, id) {
      fetch(`/api/news/${id}`)
        .then(response => response.json())
        .then(data => {
          commit('setCurrentNews', data);
        });
    }
  }
});

在这个例子中,我们定义了一个 Vuex store,包含新闻列表和当前新闻的状态,以及相应的 mutations 和 actions。

2. 在组件中使用 Vuex

在新闻列表组件中,我们可以通过 Vuex 获取新闻数据:

javascript

Copy

<template>
  <div>
    <h1>新闻列表</h1>
    <ul>
      <li v-for="news in newsList" :key="news.id">
        <router-link :to="{ name: 'NewsDetail', params: { id: news.id } }">
          {{ news.title }}
        </router-link>
      </li>
    </ul>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState(['newsList'])
  },
  created() {
    this.$store.dispatch('fetchNews');
  }
};
</script>

在新闻详情组件中,我们可以根据路由参数获取当前新闻的数据:

javascript

Copy

<template>
  <div>
    <h1>{{ currentNews.title }}</h1>
    <p>{{ currentNews.content }}</p>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState(['currentNews'])
  },
  created() {
    const newsId = this.$route.params.id;
    this.$store.dispatch('fetchNewsDetail', newsId);
  }
};
</script>

3. 处理异步数据与加载状态

在处理数据时,尤其是从 API 获取数据时,可能会遇到加载状态和错误处理的问题。可以在 Vuex 中添加状态管理,以便在组件中进行相应的处理。

Vuex Store 示例(添加加载状态)

javascript

Copy

export default new Vuex.Store({
  state: {
    newsList: [],
    currentNews: null,
    isLoading: false,
    error: null
  },
  mutations: {
    setLoading(state, isLoading) {
      state.isLoading = isLoading;
    },
    setError(state, error) {
      state.error = error;
    }
  },
  actions: {
    async fetchNews({ commit }) {
      commit('setLoading', true);
      try {
        const response = await fetch('/api/news');
        const data = await response.json();
        commit('setNewsList', data);
      } catch (error) {
        commit('setError', error.message);
      } finally {
        commit('setLoading', false);
      }
    }
  }
});

在组件中,我们可以根据 isLoading 和 error 状态来显示相应的加载指示器或错误信息:

javascript

Copy

<template>
  <div>
    <h1>新闻列表</h1>
    <div v-if="isLoading">加载中...</div>
    <div v-if="error">错误: {{ error }}</div>
    <ul>
      <li v-for="news in newsList" :key="news.id">
        <router-link :to="{ name: 'NewsDetail', params: { id: news.id } }">
          {{ news.title }}
        </router-link>
      </li>
    </ul>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState(['newsList', 'isLoading', 'error'])
  },
  created() {
    this.$store.dispatch('fetchNews');
  }
};
</script>

结论

通过结合 Vue Router 和 Vuex,我们可以构建出更加高效和灵活的 Vue3 应用。嵌套导航和状态管理的合理使用,不仅提升了应用的性能和用户体验,也使得代码的可维护性大大增强。在实际开发中,掌握这些技巧将帮助你更好地应对复杂的应用需求,提升开发效率。希望这篇文章能够为你的 Vue3 学习之旅提供帮助和启发。

 

进阶:优化 Vue3 应用的性能

在构建复杂的 Vue3 应用时,性能优化是一个不可忽视的方面。随着应用规模的扩大,用户的体验可能会受到影响。因此,了解并应用一些性能优化的策略是非常重要的。以下是一些有效的优化方法:

1. 组件懒加载

如前所述,使用组件懒加载可以显著减少初始加载时间。结合 Vue Router 的动态导入,可以在用户访问特定路由时才加载相应的组件。

javascript

Copy

const NewsDetail = () => import('./components/NewsDetail.vue');

这种方法不仅能减少初始包的大小,还能提高应用的响应速度。

2. 使用计算属性和侦听器

在 Vue 中,计算属性是基于其依赖进行缓存的,只有在依赖发生变化时才会重新计算。这意味着,如果你有一些复杂的逻辑,可以将其放入计算属性中,从而避免不必要的重复计算。

javascript

Copy

computed: {
  filteredNews() {
    return this.newsList.filter(news => news.isVisible);
  }
}

同样,侦听器可以帮助你监控数据变化,并在数据变化时执行某些操作。例如,在用户输入搜索条件时,你可以使用侦听器来更新显示的新闻列表。

3. 使用虚拟滚动

当展示大量数据时,直接渲染所有数据会导致性能下降。使用虚拟滚动技术可以只渲染可见区域的组件,从而提升性能。可以借助第三方库如 vue-virtual-scroller 来实现这一功能。

html

Copy

<virtual-scroller :items="newsList">
  <template v-slot="{ item }">
    <div>{{ item.title }}</div>
  </template>
</virtual-scroller>

4. 事件节流和防抖

在处理频繁触发的事件(如滚动、输入等)时,使用节流和防抖技术可以有效减少事件处理的次数,从而提高性能。

  • 防抖:在事件触发后,延迟执行函数,只有在特定时间内没有再次触发时才会执行。

javascript

Copy

methods: {
  debounce(func, delay) {
    let timer;
    return function(...args) {
      clearTimeout(timer);
      timer = setTimeout(() => func.apply(this, args), delay);
    };
  }
}

  • 节流:限制函数在一定时间内只能执行一次。

javascript

Copy

methods: {
  throttle(func, limit) {
    let lastFunc;
    let lastRan;
    return function(...args) {
      if (!lastRan) {
        func.apply(this, args);
        lastRan = Date.now();
      } else {
        clearTimeout(lastFunc);
        lastFunc = setTimeout(() => {
          if (Date.now() - lastRan >= limit) {
            func.apply(this, args);
            lastRan = Date.now();
          }
        }, limit - (Date.now() - lastRan));
      }
    };
  }
}

5. 适时使用 v-if 和 v-show

在 Vue 中,v-if 和 v-show 用于条件渲染组件。v-if 会在条件为假时完全销毁组件,而 v-show 仅仅是切换组件的显示状态。对于频繁切换的组件,使用 v-show 更加高效;而对于不常显示的组件,使用 v-if 则更节省资源。

html

Copy

<div v-if="isVisible">这个组件会被销毁</div>
<div v-show="isVisible">这个组件不会被销毁</div>

6. 使用 Web Workers

对于计算密集型的任务,可以考虑使用 Web Workers。在主线程中执行繁重的计算会导致 UI 卡顿,而 Web Workers 可以在后台线程中处理这些任务,从而保持界面的流畅性。

javascript

Copy

const worker = new Worker('path/to/worker.js');
worker.postMessage(data);
worker.onmessage = function(event) {
  console.log('Result from worker:', event.data);
};

结论

优化 Vue3 应用的性能是一个持续的过程。通过合理使用组件懒加载、计算属性、虚拟滚动、事件节流和防抖等技术,可以显著提升应用的响应速度和用户体验。此外,结合 Vuex 进行状态管理,可以有效地减少不必要的渲染和数据请求,进一步提高性能。

希望这篇文章为你的 Vue3 开发提供了有价值的见解和实用的建议。随着技术的不断进步,保持学习和实践的态度,将帮助你在前端开发的道路上走得更远。


原文地址:https://blog.csdn.net/2401_86733530/article/details/142943532

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!