5 Vue Router 4.x路由管理 (FH)

目录

前置知识 

pushState() 方法

1 为什么需要 Vue Router?

2  一个不用 Vue Router 的例子

3 Vue Router 安装和入门

通过  标签中的to传参

4 嵌套路由:实现页面子组件切换

 5 动态路由匹配和参数获取

6 一个问题:路由组件不刷新

7  高级路由匹配语法和优先级

8 获取 query 查询参数

9 使用命名路由精确控制跳转

10  路由别名:不同路径渲染同一组件  Router-  alias

11 重定向:把当前 URL 跳转到其它 URL

12 编程式的控制导航

13 命名视图:同一路由渲染多个组件

14  在嵌套路由中使用命名视图

15 给当前活跃导航设置高亮样式

16 导航守卫   

1 全局导航守卫 

2  路由导航守卫

3 组件导航守卫

17 路由 meta 元数据

18 页面滚动行为控制

19 代码分割 : 路由组件的懒加载进行 代码分割

20 给组件传递 Props

21 封装 router-link 组件

22 处理导航错误

23 动态的添加路由

24 路由过渡动画

25  Vue router    Composition API


前置知识 

1.后退:

window.history.back() -- 相当于用户在浏览器的工具栏上点击返回按钮;

2.前进:

window.history.forward() -- 相当于用户在浏览器的工具栏上点击前进按钮;

3.移动到指定历史记录点:

通过go()方法,指定一个相对于当前页面位置的数值,从当前会话的历史记录中加载页面(当前位置页面索引:0,上一页:-1,下一页:1);

window.history.go(-2)--后退2页,相当于调用两次back();

window.history.go(1)--前进1页,相当于调用forward();

可以通过window.history.length,得到历史记录栈中一共有多少页。

window.onpopstate、

window.history.pushState、

window.history.replaceState      API的区分

HTML5引入了 history.pushState() 和 history.replaceState() 方法,它们分别可以添加和修改历史记录条目。这些方法通常与window.onpopstate 配合使用

pushState() 方法

pushState() 需要三个参数: 一个状态对象, 一个标题 (目前被忽略), 和 (可选的) 一个URL. 让我们来解释下这三个参数详细内容:

1     状态对象可以是能被序列化的任何东西。原因在于Firefox将状态对象保存在用户的磁盘上,以便在用户重启浏览器时使用,我们规定了状态对象在序列化表示后有640k的大小限制。如果你给 pushState() 方法传了一个序列化后大于640k的状态对象,该方法会抛出异常。如果你需要更大的空间,建议使用 sessionStorage 以及 localStorage.

2 标题 — Firefox 目前忽略这个参数,但未来可能会用到。在此处传一个空字符串应该可以安全的防范未来这个方法的更改。或者,你可以为跳转的state传递一个短标题。

3 URL — 该参数定义了新的历史URL记录。注意,调用 pushState() 后浏览器并不会立即加载这个URL,但可能会在稍后某些情况下加载这个URL,比如在用户重新打开浏览器时。新URL不必须为绝对路径。如果新URL是相对路径,那么它将被作为相对于当前URL处理。新URL必须与当前URL同源,否则 pushState() 会抛出一个异常。该参数是可选的,缺省为当前URL。
 

replaceState() 方法
history.replaceState() 的使用与 history.pushState() 非常相似,区别在于 replaceState() 是修改了当前的历史记录项而不是新建一个。 注意这并不会阻止其在全局浏览器历史记录中创建一个新的历史记录项。

replaceState() 的使用场景在于为了响应用户操作,你想要更新状态对象state或者当前历史记录的URL。

popstate 事件

   每当活动的历史记录项发生变化时, popstate 事件都会被传递给window对象。如果当前活动的历史记录项是被 pushState 创建的,或者是由 replaceState 改变的,那么 popstate 事件的状态属性 state 会包含一个当前历史记录状态对象的拷贝。

    页面加载时,或许会有个非null的状态对象。这是有可能发生的,举个例子,假如页面(通过pushState() 或 replaceState() 方法)设置了状态对象而后用户重启了浏览器。那么当页面重新加载时,页面会接收一个onload事件,但没有 popstate 事件。然而,假如你读取了history.state属性,你将会得到如同popstate 被触发时能得到的状态对象。

 

1 为什么需要 Vue Router?

SPA(single page application):单一页面应用程序,只有一个完整的页面;它在加载页面时,不会加载整个页面,而是只更新某个指定的容器中内容。单页面应用(SPA)的核心之一是: 更新视图而不重新请求页面;vue-router在实现单页面前端路由时,提供了两种方式:Hash模式和History模式;根据mode参数来决定采用哪一种方式。
这里的路由就是SPA(单页应用)的路径管理器

2  一个不用 Vue Router 的例子

<template>
  <nav>
    <a
      v-for="(route, path) in routes"
      :href="path"
      @click.prevent="changeRoute(path)"
      >{
  { route.label }}</a
    >
  </nav>
  <component :is="currentPage" />
</template>

<script setup>
import PageOne from "./components/PageOne.vue";
import PageTwo from "./components/PageTwo.vue";
import PageThree from "./components/PageThree.vue";

import { ref, computed } from "vue";

const routes = {
  "/": {
    component: PageOne,
    label: "页面1",
  },
  "/2": {
    component: PageTwo,
    label: "页面2",
  },
  "/3": {
    component: PageThree,
    label: "页面3",
  },
};

const currentPath = ref(location.pathname);

const currentPage = computed(
  () => routes[currentPath.value].component || PageOne
);

function changeRoute(path) {
  history.pushState(null, null, path);
  currentPath.value = location.pathname;
}
</script>

3 Vue Router 安装和入门

1 yarn add vue-router@4 

2 新建配置文件 router.js

router.js

import PageOne from "./components/PageOne.vue";
import PageTwo from "./components/PageTwo.vue";
import PageThree from "./components/PageThree.vue";

import { createRouter, createWebHistory } from "vue-router";

const routes = [
  {
    path: "/",
    component: PageOne,
  },
  {
    path: "/2",
    component: PageTwo,
  },
  {
    path: "/3",
    component: PageThree,
  },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;

main.js 

import { createApp } from "vue";
import App from "./App.vue";
import router from "./routes"; //引入vue router

const app = createApp(App);

app.use(router); //使用router

app.mount("#app");

App.vue

 <router-link to="/">页面1</router-link>

 <router-view></router-view>

<template>
  <nav>
    <router-link to="/">页面1</router-link>
    <router-link to="/2">页面2</router-link>
    <router-link to="/3">页面3</router-link>
  </nav>
  <router-view></router-view>
</template>

<script>
export default {};

</script>

通过 <router-link> 标签中的to传参

<router-link :to="{name:xxx,params:{key:value}}">valueString</router-link>

4 嵌套路由:实现页面子组件切换

 文件目录:

更新配置:  嵌套路由

const routes = [
  {
    path: "/",
    component: HomePage,
  },
  {
    path: "/about",
    component: AboutMe,
    children: [
      { path: "work", component: WorkExperience },
      { path: "education", component: EducationExperience },
    ],
  },
];

页面:

App.vue
<template>
  <nav>
    <router-link to="/">首页</router-link>
    <router-link to="/about">关于</router-link>
  </nav>
  <router-view></router-view>
</template>


AboutMe.vue
<template>
  <div class="container">
    <p>Hi 你好!这是关于我的页面</p>
    <p>更多详情查看:</p>
    <nav>
      <router-link to="/about/work">工作经历</router-link>
      <router-link to="/about/education">教育经历</router-link>
    </nav>
    <router-view></router-view>
  </div>
</template>

 5 动态路由匹配和参数获取

配置:


const routes = [
  {
    path: "/",
    component: BlogListPage,
  },
  {
    path: "/:postId",
    component: BlogPostPage,
  },
];

BlogListPage.vue

<template>
  <main>
    <div className="blogPosts">
      <article v-for="blogPost in blogPosts" :key="blogPost.id">
        <h2>
          <router-link :to="`/${blogPost.id}`">{
  {
            blogPost.title
          }}</router-link>
        </h2>
        <p>{
  { blogPost.body.substring(0, 100) + "..." }}</p>
      </article>
    </div>
  </main>
</template>
<script>
import { getAllPosts } from "../data/blogPosts";


 blogPosts.vue 


blogPosts.vue 

<template>
  <article>
    <h2>
      {
  { blogPost.title }}
    </h2>
    <p>{
  { blogPost.body }}</p>
    <footer>
      <router-link to="/">回到主页</router-link>
    </footer>
  </article>
</template>
<script>


export default {
  data() {
    return { blogPost: {} };
  },
  created() {
    this.blogPost = getBlogPostById(this.$route.params.postId);
  },
};

export function getBlogPostById(id) {
  return blogPosts.find((post) => post.id === Number(id));
}

</script>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值