美文网首页
Vue Router和前端路由原理

Vue Router和前端路由原理

作者: 刷题刷到手抽筋 | 来源:发表于2022-05-28 08:50 被阅读0次

一、前端路由

什么是前端路由?简单地说,前端路由是一种根据url来渲染前端组件的技术。

前端路由应用于什么场景?多页面的场景,在多页面的场景下,相对于后端路由,前端路由由于可以实现无刷新的效果,用户体验更好。

比如,当我们的应用有两个页面,home主页,和user用户页面时候,我们希望https://my.domain.com/home访问到主页的内容,https://my.domain.com/user访问用户页面,我们就可以使用前端路由来实现。

使用前端路由,每个访问路径会对应一个组件,这个组件我们页称为页面。

二、Vue Router

注意本文中示例vue-router使用的版本是4

1. 路由配置

使用前端路由技术开发应用时候,我们希望指定url的路径与组件之间的对应关系,即当访问某个url时候,渲染哪个组件。

这是通过Vue Router提供的API:createRouter方法来实现的。具体使用为以下步骤:

  1. 提供路由配置并传入到createRouter方法中
  2. 在组件中通过<router-view>指定组件渲染的位置,当路径匹配上时候,组件会替换掉<router-view>标签。
// main.js

import { createApp } from 'vue';
import {createRouter, createWebHistory} from 'vue-router';
import routerConfig from './route.config';
import App from './App';

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

createApp(App).use(router).mount('#app')
// route.config.js
import Home from './pages/home';
import User from './pages/user';

export default [
    {
        path: '/home',
        component: Home
    },
    {
        path: '/user',
        component: User
    }
];
// App.vue
<template>
    <div>
        <router-view></router-view>
    </div>
</template>

<script>
    export default {};
</script>

上面实例代码展示了基本的路由配置,当访问localhost:8080/home时候,会渲染Home组件,当访问localhost:8080/user时候会渲染user组件。

当在全局注入了router(createApp(App).use(router))之后,在组件中可以通过this.$route来访问路由对象。

前端面试刷题网站灵题库,收集大厂面试真题,相关知识点详细解析。】

2. 动态路由匹配

有时候我们需要动态的路由,即路径中存在动态的字符,这时候可以通过Vue Router支持的动态路由语法来匹配。

路由配置:

{
    // http://localhost:8080/user/123
    path: '/user/:id',
    component: User
}

User组件:

<template>
    <div>user: {{$route.params.id}}</div>
</template>

<script>
    export default {};
</script>

当访问http://localhost:8080/user/123时候,匹配上了路由'/user/:id',其中123对应id。因此会渲染component声明的组件:User,在User里面可以通过this.route访问路由对象,route.params是动态路由匹配到的参数,所以模板中的{{$route.params.id}}值为123。

3. 导航链接和编程式导航

我们已经知道了如何通过配置路由来让访问路径和组件对应。那么在应用内如何处理路由跳转呢?即我们想实现点击某个链接跳转页面,应该怎么做呢?

有两种方式,导航链接编程式导航

导航链接即使用Vue Router提供的组件:<router-link>来实现导航:

<router-link to="/home">进入home页面</router-link>

上面的代码会在页面展示一个“进入home页面”的超链,点击之后跳转到home页面。它的行为和原生的a标签并不一样,它不会真正刷新浏览器,而只是渲染home组件。

编程式导航是通过js代码来实现路由跳转

<button @click="gotoHome">点击进入home页面</button>
{
  methods: {
    gotoHome() {
      this.$router.push('/home');
    }
  }
};

编程式导航更加灵活,比如当跳转不是点击触发的时候,就需要用编程式导航来实现。

4. 重定向和别名

重定向: 如果我们希望访问一个路径时候,自动跳转到另一个路径,那么就需要Vue Router提供的重定向的能力。

{
    path: '/',
    redirect: '/home'
}

这样配置声明了访问根路径时候重定向到'/home'。当访问http://localhost:8080时候,就会自动跳转到http://localhost:8080/home了。

别名: 设置一个路由的别名,可以让不同访问的路径指向同一个组件。

{
    path: '/home',
    component: Home,
    alias: '/main'
},

上面的配置会让我们在访问http://localhost:8080/homehttp://localhost:8080/main时候都会渲染Home组件。

5. 嵌套路由

一般一个web应用的路径可能是多级的,比如我们有一个用户列表页面,还有一个用户详情页。那么我们会希望https://my.domain.com/user/list访问用户列表页,https://my.domain.com/user/detail访问的是用户详情页。

对于多级路径,在路由配置时候是嵌套的形式,user是外层路由,而list和detail是里层路由,

对于嵌套路由的配置有2个步骤:

  1. 配置父路由和子路由,通过children字段声明
  2. 父路由声明子路由的组件渲染的位置,通过<router-view>组件来实现。

例如我们想在上面'/user/:id'动态路由后面增加一个嵌套路由'/user/:id/list'和'/user/:id/detail',那么首先配置路由

{
    path: '/user/:id',
    component: User,
    children: [
        {
            path: '/user/:id/list',
            component: UserList
        },
        {
            path: '/user/:id/detail',
            component: UserDetail
        }
    ]
}

然后在父路由User组件中增加<router-view>标签:

<template>
    <div>user: {{$route.params.id}}</div>
    <router-view></router-view>
</template>

<script>
    export default {};
</script>

然后访问/user/123/list和/user/123/detail就可以看到能够正常展示了。

这里要注意父路由的<router-view>组件是必须的,它用来在子路由匹配上之后渲染子组件。

6. 导航守卫

很多情况下我们需要在路由跳转前后做一些处理,例如在跳转到某个路由之前先判断一下用户是否有权限,如果没有权限组不跳转。

导航守卫是Vue Router提供的在路由跳转前后做处理的钩子API。

主要有3中导航守卫:全局守卫路由独享守卫组件内守卫

当我们需要在路由跳转时候做一些通用逻辑时候可以使用全局守卫。

import { createApp } from 'vue';
import {createRouter, createWebHistory} from 'vue-router';
import routerConfig from './route.config';
import App from './App';

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

// 全局守卫
router.beforeEach((to, from) => {
    console.log(`从${from.path} 跳转到  ${to.path}`);
});

createApp(App).use(router).mount('#app')

对于个别路由自己的逻辑可以使用路由独享守卫

{
    path: '/user/:id',
    component: User,
    children: [
        {
            path: 'list',
            component: UserList,
            // return false 则不跳转
            beforeEnter: () => {
                return false
            },
        },
        {
            path: 'detail',
            component: UserDetail
        },
    ]
}

在组件中也可以声明相应地钩子来处理跳转逻辑

// UserList.vue

<template>
    <div>user-list</div>
</template>

<script>
    export default {
        beforeRouteEnter() {
            return false;
        }
    };
</script>

7. 两种历史记录模式

两种历史记录模式的使用

前端路由有两种模式,HTML5和hash,默认是hash模式。这两种模式本质是不同的底层浏览器技术,但是上层Vue Router做了统一化的封装,因此在我们开发组件和配置路由时候使用这两种模式的区别并不大:

import {createRouter, createWebHistory, createWebHashHistory} from 'vue-router';
import routerConfig from './route.config';

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

可以看到在使用createRouter创建vue路由时候,可以指定使用HTML5(createWebHistory)还是hash模式(createWebHashHistory)。

比如如果访问home页,hash是这样的http://localhost:8080/#/home,HTML5模式是这样的http://localhost:8080/home

这两种模式有几个主要区别

  1. HTML5模式的路由没有"#"字符,而是在域名后直接写路径,更加优雅
  2. 由于#后面的字符不会发给服务器,因此hash路由SEO比较差
  3. HTML5需要服务器在访问不同的路径时候都能fallback到index.html,因此相对麻烦

两种历史记录模式的原理

前端路由的原理关键有2点

  1. 可以修改url,但不会引起刷新,从而在不刷新的页面的情况下跳转路由。
  2. 监听url改变,根据url渲染对应组件。

hash模式和history模式的原理都是基于这两点。hash是通过浏览器提供的locationAPI修改url,通过onhashchange方法监听hash改变;history通过浏览器提供的history.pushState或者history.replacestate修改url,通过popState事件监听url改变。

相关文章

网友评论

      本文标题:Vue Router和前端路由原理

      本文链接:https://www.haomeiwen.com/subject/gtmpurtx.html