Vue3_15(VueRouter)

Vue Router https://router.vuejs.org/zh/guide/

vue-router是基于路由和组件的

  路由用于设定访问路径, 将路径和组件映射起来.
  在vue-router的单页面应用中, 页面的路径的改变就是组件的切换

使用vue-router

  第一步:创建路由组件的组件;
  第二步:配置路由映射: 组件和路径映射关系的routes数组;
  第三步:通过createRouter创建路由对象,并且传入routes和history模式;
  第四步:使用路由: 通过<router-link>和<router-view>;

 例子:

router.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
 
// 配置映射关系
const routes = [
  {
    path: "/",
    redirect: "/home"
  },
  // /home/shops
  {
    path: "/home",
    name: "home",
    component: () => import(/* webpackChunkName: "home-chunk" */"../pages/Home.vue"),
    meta: {
      name: "why",
      age: 18,
      height: 1.88
    },
    children: [
      {
        path: "",
        redirect: "/home/message"
      },
      {
        path: "message",
        component: () => import("../pages/HomeMessage.vue")
      },
      {
        path: "shops",
        component: () => import("../pages/HomeShops.vue")
      }
    ]
  },
  {
    path: "/about",
    name: "about",
    component: () => import("../pages/About.vue")
  },
  {
    path: "/user/:username/id/:id",
    component: () => import("../pages/User.vue")
  },
  {
    path: "/login",
    component: () => import("../pages/Login.vue")
  },
  {
    path: "/:pathMatch(.*)",
    component: () => import("../pages/NotFound.vue")
  }
];
 
// 创建一个路由对象router
const router = createRouter({
  routes,
  history: createWebHistory()
})
 
// 动态添加路由
const categoryRoute = {
  path: "/category",
  component: () => import("../pages/Category.vue")
}
 
// 添加顶级路由对象
router.addRoute(categoryRoute);
 
// 添加二级路由对象
router.addRoute("home", {
  path: "moment",
  component: () => import("../pages/HomeMoment.vue")
})
 
 
// 导航守卫beforeEach
let counter = 0;
// to: Route对象, 即将跳转到的Route对象
// from: Route对象,
/**
 * 返回值问题:
 *    1.false: 不进行导航
 *    2.undefined或者不写返回值: 进行默认导航
 *    3.字符串: 路径, 跳转到对应的路径中
 *    4.对象: 类似于 router.push({path: "/login", query: ....})
 */
router.beforeEach((to, from) => {
  console.log(`进行了${++counter}路由跳转`)
  // if (to.path.indexOf("/home") !== -1) {
  //   return "/login"
  // }
  if (to.path !== "/login") {
    const token = window.localStorage.getItem("token");
    if (!token) {
      return "/login"
    }
  }
})
 
 
export default router

App.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<template>
  <div id="app">
    <!-- props: href 跳转的链接 -->
    <!-- props: route对象 -->
    <!-- props: navigate导航函数 -->
    <!-- props: isActive 是否当前处于活跃的状态 -->
    <!-- props: isExactActive 是否当前处于精确的活跃状态 -->
    <router-link to="/home" v-slot="props" custom>
      <button @click="props.navigate">{{props.href}}</button>
      <button @click="props.navigate">哈哈哈</button>
      <span :class="{'active': props.isActive}">{{props.isActive}}</span>
      <span :class="{'active': props.isActive}">{{props.isExactActive}}</span>
      <!-- <p>{{props.route}}</p> -->
    </router-link>
    <router-link to="/about">关于</router-link>
    <router-link to="/user/kobe/id/111">用户</router-link>
    <router-link to="/category">分类</router-link>
 
    <button @click="jumpToAbout">关于</button>
    <button @click="forwardOneStep">前进一步</button>
 
    <router-view v-slot="props">
      <!-- <transition name="why"> -->
        <keep-alive>
          <component :is="props.Component"></component>
        </keep-alive>
      <!-- </transition> -->
    </router-view>
  </div>
</template>
 
<script>
 
import { useRouter } from 'vue-router'
import NavBar from './components/NavBar.vue'
 
export default {
  name: 'App',
  components: {
    NavBar
  },
  methods: {
    // jumpToAbout() {
    //   // router
    //   this.$router.push("/about")
    // }
  },
  setup() {
    const router = useRouter();
 
    const jumpToAbout = () => {
      // router.push("/about")
      // router.push({
      //   path: "/about",
      //   query: {
      //     name: "why",
      //     age: 18
      //   }
      // })
      // router.replace("/about")
    }
 
    const forwardOneStep = () => {
      router.go(1)
      // router.go(-1)
      // router.forward()
      // router.back()
    }
 
    return {
      jumpToAbout,
      forwardOneStep
    }
  }
}
</script>
 
<style>
  .why-active {
    color: red;
  }
 
  .why-enter-from,
  .why-leave-to {
    opacity: 0;
  }
 
  .why-enter-active,
  .why-leave-active {
    transition: opacity 1s ease;
  }
</style>

前端路由是如何做到URL和内容进行映射呢?监听URL的改变。

URL的hash

  URL的hash也就是锚点(#), 本质上是改变window.location的href属性;
  可以通过直接赋值location.hash来改变href, 但是页面不发生刷新;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
    <a href="#/home">home</a>
    <a href="#/about">about</a>
 
    <div class="content">Default</div>
  </div>
 
  <script>
    const contentEl = document.querySelector('.content');
    window.addEventListener("hashchange", () => {
      switch(location.hash) {
        case "#/home":
          contentEl.innerHTML = "Home";
          break;
        case "#/about":
          contentEl.innerHTML = "About";
          break;
        default:
          contentEl.innerHTML = "Default";
      }
    })
  </script>

HTML5的History  

  replaceState:替换原来的路径;
  pushState:使用新的路径;
  popState:路径的回退;
  go:向前或向后改变路径;
  forward:向前改变路径;
  back:向后改变路径;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<div id="app">
    <a href="/home">home</a>
    <a href="/about">about</a>
 
    <div class="content">Default</div>
  </div>
 
  <script>
    const contentEl = document.querySelector('.content');
 
    const changeContent = () => {
      switch(location.pathname) {
        case "/home":
          contentEl.innerHTML = "Home";
          break;
        case "/about":
          contentEl.innerHTML = "About";
          break;
        default:
          contentEl.innerHTML = "Default";
      }
    }
 
    const aEls = document.getElementsByTagName("a");
    for (let aEl of aEls) {
      aEl.addEventListener("click", e => {
        e.preventDefault();
         
        const href = aEl.getAttribute("href");
        history.pushState({}, "", href);
        //history.replaceState({}, "", href);
 
        changeContent();
      })
    }
 
    window.addEventListener("popstate", changeContent)
  </script>

 

posted @   Hexrui  阅读(62)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
返回顶部
点击右上角即可分享
微信分享提示