vue路由的基本使用

vue-router简介

Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。功能包括:

  • 嵌套路由映射
  • 动态路由选择
  • 模块化、基于组件的路由配置
  • 路由参数、查询、通配符
  • 展示由 Vue.js 的过渡系统提供的过渡效果
  • 细致的导航控制
  • 自动激活 CSS 类的链接
  • HTML5 history 模式或 hash 模式
  • 可定制的滚动行为
  • URL 的正确编码

一、路由配置和使用

1、安装

打开项目终端,通过npm安装

npm install vue-router@4

2、创建路由实例

在项目中src目录想创建Router文件夹,新建index.js文件,在这个文件下配置路由:

import { createWebHashHistory, createRouter } from 'vue-router'

import Center from '../view/Center.vue' //引入组件路径(路由组件尽量放在view文件夹下)
import Home from '../view/Home.vue'

const routes = [
  { 
    path: '/Center', //跳转的路径
    name:'Center ' //命名路由,也可以不写
    component: Center //跳转到对应的组件
},

  { 
    path: '/Home', 
    component: Home
},
]

const router = createRouter({
  history: createWebHashHistory(),//hash的模式,如#/home,#/center  带#号的路径
 // history: createWebHistory(),//web的模式,如/home,/center  不带#号的路径
  routes,//`routes:routes`的缩写
})

export default router

2、在组件中引用路由 router-view ,如APP根组件中直接引用:

<template>
  app
  <!--插槽-->
  <router-view></router-view>

</template>


3、最后还需要把路由挂载到APP实例中,在main.js中注册路由:


import { createApp } from 'vue'
import App from './App.vue'
import router from './Router' //直接导入Router文件夹,会自动找到index.js这个文件


const app=createApp(App)

app.use(router) //注册路由插件
app.mount('#app')

直接输入对应的路径,显示对应的组件,到此路由的基本模型已经做好了

在这里插入图片描述

二、路由重定向与别名

  • 重定向也是通过 routes 配置redirect来完成,下面例子是从 /home 重定向到 /:
const routes = [
  { 
	path: '/home', 
	redirect: '/' 
	}
]
  • 重定向的目标也可以是一个命名的路由:(路由通过name来命名)
const routes = [{ path: '/home', redirect: { name: 'center' } }]
  • 常规参数只匹配url片段之间的字符,用 / 分割。如果我们想匹配任意路径,我们可以自定义的路径参数正则表达式,在路径参数后面的括号中加入 正则表达式:
const routes = [
    { 
        path: '/:pathMatch(.*)*', //pathMatch只是占位符,任意字母都可以
        name:'NotFound',
        component: NotFound
    },
]
  • 别名alias属性表示,当url匹配到别名/abc,也会跳转到组件center中去
const routes = [
    { 
        path: '/Center', 
        component: Center ,
        alias:'/abc'  //注意别名有个/;也可以用数组alias: ['/abc', 'aaa']
    },
]

三、声明式导航

1、传统的导航

通过a标签跳转

<div class="tabbar">
        <ul>
            <li><a href="#/home">首页</a></li>
            <li><a href="#/films">影院</a></li>
            <li><a href="#/center">我的</a></li>
        </ul>

    </div>

2、通过路由router-link

  • to跳转到对应的路由,不需要加#号
  • 不过标签会带a标签的样式,底部会有个下划线不太好看,后面我们也可以通过$route.push跳转的方法
 <ul>
      <li><router-link to="/home">首页</router-link> </li>
      <li><router-link to="/films">影院</router-link> </li>
      <li><router-link to="/center">我的</router-link></li>
</ul>
  • 通过active-class="kerwin"来命名,使选中的显示高亮
<template>
    <div class="tabbar">
        <ul>
            <li>
                <router-link to="/home" active-class="kerwin">首页</router-link>
            </li>

            <li>
                <router-link to="/films"  active-class="kerwin">影院</router-link> 
            </li>

            <li>
                <router-link to="/center"  active-class="kerwin">我的</router-link>
            </li>
        </ul>

    </div>

</template>
<script setup>


</script>
<style scoped>
.kerwin{
    color: red;
}
.tabbar{
    position: fixed;
    width: 100%;
    height: 50px;
    line-height: 50px;
    text-align: center;
    bottom: 10px;
}
.tabbar ul{
    display: flex;

}

.tabbar ul li{
    flex:1;
}


</style>

如图所示:
在这里插入图片描述

四、嵌套路由

一个路由组件下面,再嵌套路由,要将组件渲染到这个嵌套的 router-view 中,我们需要在路由中配置 children:

const routes = [
  {
    path: '/user',
    component: User,
    children: [
      {
        // 当 /user/profile 匹配成功
        // UserProfile 将被渲染到 User 的 <router-view> 内部
        path: 'profile',
        // path: '/user/profile'的简写,通过http://localhost:5173/#/user/profile访问
        component: UserProfile,
      },
      {
        // 当 /posts 匹配成功
        // UserPosts 将被渲染到 User 的 <router-view> 内部
        path: '/posts', //注:可以通过http://localhost:5173/#/posts访问
        component: UserPosts,
      },
    ],
  },
]
注意,以 / 开头的嵌套路径将被视为根路径。这允许你利用组件嵌套,而不必使用嵌套的 URL。

五、编程式导航

  • router 指代路由器实例。在组件内部,你可以使用 $router 属性访问路由,例如
    this.$router.push(...)。如果使用组合式 API,你可以通过调用 useRouter() 来访问路由器。
声明式编程式
< router-link :to=“…” >router.push(…)

该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:

import { useRouter, useRoute } from 'vue-router'

const router = useRouter()
const route = useRoute()

const username = 'eduardo'
// 我们可以手动建立 url,但我们必须自己处理编码
router.push(`/user/${username}`) // -> /user/eduardo
// 同样
router.push({ path: `/user/${username}` }) // -> /user/eduardo
// 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益
router.push({ name: 'user', params: { username } }) // -> /user/eduardo
// `params` 不能与 `path` 一起使用
router.push({ path: '/user', params: { username } }) // -> /user
  • 替换当前位置
    直接在传递给 router.push 的 to 参数中增加一个属性 replace: true :
router.push({ path: '/home', replace: true })
// 相当于
router.replace({ path: '/home' })
  • 横跨历史
    该方法采用一个整数作为参数,表示在历史堆栈中前进或后退多少步,类似于 window.history.go(n)。
// 向前移动一条记录,与 router.forward() 相同
router.go(1)

// 返回一条记录,与 router.back() 相同
router.go(-1)

// 前进 3 条记录
router.go(3)

// 如果没有那么多记录,静默失败
router.go(-100)
router.go(100)

六、动态路由匹配

很多时候,我们需要将给定匹配模式的路由映射到同一个组件。例如,我们可能有一个 User 组件,它应该对所有用户进行渲染,但用户 ID 不同。在 Vue Router 中,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数 :

import User from './User.vue'

// 这些都会传递给 `createRouter`
const routes = [
  // 动态字段以冒号开始
  { path: '/users/:id', component: User }, //id属于占位符
]

路径参数 用冒号 : 表示。当一个路由被匹配时,它的 params 的值将在每个组件中以 route.params 的形式暴露出来。因此,我们可以通过更新 User 的模板来呈现当前的用户 ID:

<template>
  <div>
    <!-- 当前路由可以通过 $route 在模板中访问 -->
    User {{ $route.params.id }}
  </div>
</template>

要对同一个组件中参数的变化做出响应的话,你可以简单地 watch $route 对象上的任意属性,在这个场景中,就是$route.params

<script setup>
import { watch } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()

watch(() => route.params.id, (newId, oldId) => {
  // 对路由变化做出响应...
})
</script>

或者,使用 beforeRouteUpdate 导航守卫,它还允许你取消导航:

<script setup>
import { onBeforeRouteUpdate } from 'vue-router'
// ...

onBeforeRouteUpdate(async (to, from) => {
  // 对路由变化做出响应...
  userData.value = await fetchUser(to.params.id)
})
</script>

七、路由拦截

正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。

1、全局前置守卫

你可以使用 router.beforeEach 注册一个全局前置守卫:

const router = createRouter({ ... })

router.beforeEach((to, from) => {
  // ...
  // 返回 false 以取消导航
  return false
})

每个守卫方法接收两个参数:

  • to: 即将要进入的目标 用一种标准化的方式
  • from: 当前导航正要离开的路由 用一种标准化的方式

可以返回的值如下:

  • false: 取消当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
  • 一个路由地址: 通过一个路由地址重定向到一个不同的地址,如同调用 router.push(),且可以传入诸如 replace: true 或 name: ‘home’ 之类的选项。它会中断当前的导航,同时用相同的 from 创建一个新导航。
// GOOD
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  else next()
})

2、全局后置钩子

你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

router.afterEach((to, from) => {
  sendToAnalytics(to.fullPath)
})
  • 它们对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。

3、组件内的守卫(路由生命周期)

你可以为路由组件添加以下配置:

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave
<script>
export default {
  beforeRouteEnter(to, from) {
    // 在渲染该组件的对应路由被验证前调用
    // 不能获取组件实例 `this` !
    // 因为当守卫执行时,组件实例还没被创建!
  },
  beforeRouteUpdate(to, from) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
    // 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
  },
  beforeRouteLeave(to, from) {
    // 在导航离开渲染该组件的对应路由时调用
    // 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
  },
}
</script>
  • 这个 离开守卫 通常用来预防用户在还未保存修改前突然离开。该导航可以通过返回 false 来取消。
beforeRouteLeave (to, from) {
  const answer = window.confirm('数据未保存,你确定要离开吗!')
  if (!answer) return false
}

八、路由懒加载

Vue Router 支持开箱即用的动态导入,这意味着你可以用动态导入代替静态导入:
改成箭头函数的写法就可以了

// 将
// import UserDetails from './views/UserDetails.vue'
// 替换成
const UserDetails = () => import('./views/UserDetails.vue')

const router = createRouter({
  // ...
  routes: [
    { path: '/users/:id', component: UserDetails }
    // 或在路由定义里直接使用它
    { path: '/users/:id', component: () => import('./views/UserDetails.vue') },
  ],
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值