Vue路由

118 阅读6分钟

Vue路由

1-vue路由的基本使用

在npm中安装

npm install vue-router@4

定义好路由文件

  • 导入组件
  • 配置路由路径和组件
  • 创建路由(配置history模式和添加路由)
  • 导出路由
//router.js
import { createRouter, createWebHashHistory } from 'vue-router'

import Film from '../views/Film.vue'
import Cinema from '../views/Cinema.vue'
import Center from '../views/Center.vue'
const routes = [
    { path: '/film', component: Film },
    { path: '/cinema', component: Cinema },
    { path: '/center', component: Center },
]


const router = createRouter({
    // 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
    history: createWebHashHistory(),
    routes, // `routes: routes` 的缩写
})

export default router

在main.js中导入并且使用

// main.js

var app = createApp(App)
app.use(router)  //使用路由
app.mount('#app')

2-路由的重定向

1-重定向-更改路径

  • 通过修改routes配置,将/home重定向到/
const routes = [
    {
    path:"/home",
    redirect:"/"
    }
]

2-重定向-更改路由名字

  • 使用带名字的路由替换/home
const routes = [
    {
    path:"/home",
    redirect:{name:"homePage"}
    }
]

3-重定向-使用方法动态返回重定向目标

  • 通过方法,动态返回重定向目标
const routes = [
  {
    // /search/screens -> /search?q=screens
    path: '/search/:searchText',
    redirect: to => {
      // 方法接收目标路由作为参数
      // return 重定向的字符串路径/路径对象
      return { path: '/search', query: { q: to.params.searchText } }
    },
  },
  {
    path: '/search',
    // ...
  },
]

:

  • 通过/search?id=xxx方式去请求,使用path:"/search"
  • 通过/search/xxx方式去请求,使用path:"/search/:xxx"

4-404-NotFound

  • 处理错误地址
{
        path:"/:pathMatch(.*)*",
        component:Notfound //路径错误
    },

3-路由的别名

1-取一个别名

  • 使用alias:"/新路径"
const routes = [
    { 
    path: '/', 
    component: Homepage, 
    alias: '/home' 
    }
]

2-取多个别名

  • 使用alias:["/新路径1","/新路径2"]
const routes = [
    { 
    path: '/', 
    component: Homepage, 
    alias: ['/home' ,'/homepage' ]
    }
]

4-声明式导航和自定义导航

1-声明式导航

  1. vue-router提供了一个全局组件 router-link
  2. router-link实质上最终会渲染成a链接 to属性等价于提供 href属性(to无需#)
  3. router-link提供了声明式导航高亮的功能(自带类名)
<template>
    <div>
        <!--声明式导航 -->
        <ul>
            <li>
                <router-link to="/film" activeClass="tabbar-active">电影</router-link>
            </li>
            <li>
                <router-link to="/cinema" activeClass="tabbar-active">影院</router-link>
            </li>
            <li>
                <router-link to="/center" activeClass="tabbar-active">我的</router-link>
            </li>
        </ul>
    </div>
</template>

<style lang="scss" scoped>
.tabbar-active{
    color:red;
}
</style>

2-自定义导航

<template>
    <!-- 自定义导航 -->
    <ul>
        <router-link to="/film" custom v-slot="{navigate,isActive}">
            <li @click="navigate" :class="isActive?'tabbar-active':''">电影</li>
        </router-link>
        <router-link to="/cinema" custom v-slot="{navigate,isActive}">
            <li @click="navigate" :class="isActive?'tabbar-active':''">影院</li>
        </router-link>
        <router-link to="/center" custom v-slot="{navigate,isActive}">
            <li @click="navigate" :class="isActive?'tabbar-active':''">我的</li>
        </router-link>
    </ul>
</template>

<style lang="scss" scoped>
.active{
    color:red;
}
</style>

3-路由出口RouterView

<!-- 路由出口 --> <!-- 路由匹配到的组件将渲染在这里 --> 
<router-view></router-view>

5-编程式导航

1-实例中使用

  • vue实例中使用this.$router.push(),根据()中的参数不同,使用方法不同
// 字符串路径
router.push('/users/eduardo')

// 带有路径的对象
router.push({ path: '/users/eduardo' })

// 命名的路由,并加上参数,让路由建立 url
router.push({ name: 'user', params: { username: 'eduardo' } })

// 带查询参数,结果是 /register?plan=private
router.push({ path: '/register', query: { plan: 'private' } })

// 带 hash,结果是 /about#team
router.push({ path: '/about', hash: '#team' })

2-替换位置

  • 它的作用类似于 router.push,唯一不同的是,它在导航时不会向 history 添加新记录,正如它的名字所暗示的那样——它取代了当前的条目。

image.png

router.push({ path: '/home', replace: true })
// 相当于
router.replace({ path: '/home' })

3-声明式导航和函数式导航的比较

  1. 声明式 会渲染成a标签使用
  2. 函数式 通过传参导航

6-嵌套路由

  • 使用children:[]嵌套下一级路由
{
        path: '/film', component: Film, name: "film",
        children: [
            {
                path: "nowplaying",
                component: Nowplaying
            },
            {
                path: "comingsoon",
                component: Comingsoon
            },
            {
                path: "/film",
                redirect:"/film/nowplaying"
            }
        ]
}

7-路由模式

1. 哈希模式(Hash Mode)

在哈希模式下,URL 中的路径会包含一个 # 符号,例如:http://example.com/#/path/to/route。这个 # 符号被用来表示页面内的锚点,而不会触发浏览器向服务器请求新页面。Vue 路由通过监听 URL 中 # 后面的部分来进行路由的切换。

配置哈希模式的 Vue 路由:

javascriptCopy code
import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

const router = new VueRouter({
  mode: 'hash', // 默认就是 'hash' 模式
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About },
    // 其他路由配置
  ]
});

2. 历史模式(History Mode)

历史模式使用浏览器提供的 history.pushState API 来完成 URL 的切换,使得 URL 看起来更像传统的 URL,没有 # 符号。例如:http://example.com/path/to/route

配置历史模式的 Vue 路由:

javascriptCopy code
import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

const router = new VueRouter({
  mode: 'history',
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About },
    // 其他路由配置
  ]
});

需要注意的是,在使用历史模式时,服务器需要正确配置,以便在直接访问路由时返回主页,以防止404错误。

选择使用哈希模式还是历史模式取决于你的项目需求和服务器配置的情况。哈希模式通常更容易配置,但带有 # 符号,而历史模式更符合传统 URL 的形式,但需要服务器支持。

8-路由守卫

路由守卫是 Vue Router 提供的一种机制,用于在导航过程中对路由进行监控和控制。守卫主要通过一些钩子函数来实现,在不同的阶段触发,允许你执行一些自定义逻辑。

以下是 Vue Router 中常用的路由守卫钩子函数:

1. 全局前置守卫 (beforeEach):

  • 在路由切换开始时调用。
  • 用于进行全局的导航守卫逻辑,例如身份验证。
  router.beforeEach((to, from, next) => {
    // 在路由切换前执行一些逻辑
    if (to.meta.requiresAuth && !userAuthenticated) {
      // 如果路由需要身份验证且用户未认证,则重定向到登录页
      next('/login');
    } else {
      // 继续导航
      next();
    }
  });

2. 全局解析守卫 (beforeResolve):

  • 在导航被确认之前调用,也就是导航即将被 resolved。
  • beforeEach 之后调用。
    router.beforeResolve((to, from, next) => {
      // 在导航被确认之前执行一些逻辑
      // ...

      // 继续导航
      next();
    });

3. 全局后置守卫 (afterEach):

  • 在导航成功完成后调用,即页面已经渲染。
  • 可用于执行一些全局的后置逻辑,例如日志记录。

    router.afterEach((to, from) => {
      // 导航完成后执行一些逻辑
      // ...
    });

4. 路由独享的守卫:

  • 可以在路由配置中单独定义 beforeEnter 守卫,仅对某个路由生效。

   const route = {
     path: '/example',
     component: Example,
     beforeEnter: (to, from, next) => {
       // 在进入路由前执行一些逻辑
       // ...
       next();
     }
   };

5. 组件内的守卫:

  • 在组件内部定义 beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave 钩子函数。
  • beforeRouteEnter 在路由进入组件前调用,beforeRouteUpdate 在组件复用时调用,而 beforeRouteLeave 在离开组件时调用。
 
   const MyComponent = {
     beforeRouteEnter(to, from, next) {
       // 在路由进入组件前执行一些逻辑
       // ...
       next();
     },
     beforeRouteUpdate(to, from, next) {
       // 在组件复用时执行一些逻辑
       // ...
       next();
     },
     beforeRouteLeave(to, from, next) {
       // 在离开组件时执行一些逻辑
       // ...
       next();
     }
   };

9-路由懒加载

路由懒加载是一种优化技术,它允许将你的 Vue.js 应用程序的路由组件按需加载,而不是一次性加载所有路由的组件。这可以减小初始加载时的文件体积,提高应用的性能。

以下是使用路由懒加载的基本步骤:

  1. 使用动态 import 语法:

    在定义路由的时候,将组件的 import 语句写成一个函数,这个函数返回一个 import 语句。这样,Webpack 将会在需要的时候异步加载这个组件。

    
    const Home = () => import('./views/Home.vue');
    const About = () => import('./views/About.vue');
    const Contact = () => import('./views/Contact.vue');
    

    上述代码中,import() 返回一个 Promise,在路由导航到对应的路由时,Webpack 将会异步加载相应的组件。

  2. 配置路由:

    在路由的配置中,使用上述定义的组件。

    
    const router = new VueRouter({
      routes: [
        { path: '/', component: Home },
        { path: '/about', component: About },
        { path: '/contact', component: Contact }
      ]
    });
    

    此时,这些组件将会在首次访问对应的路由时才会被加载。

这样做的好处是,只有在需要的时候才加载组件,而不是一开始就加载所有组件,从而减小了初始加载时的文件大小,提高了应用的性能。