Vue3基础(5)——前端路由、vue-router

黑马程序员Vue全套视频教程,从vue2.0到vue3.0一套全覆盖,前端必会的框架教程_哔哩哔哩_bilibili喜欢的小伙伴们别忘了投币,点赞,收藏呦,历经 5 年的反复打磨与锤炼,黑马程序员重磅推出全套最新的 Vue2 + Vue3 基础课程。共计 500 多集的免费视频,助您轻松掌握前端圈最火的 Vue 框架!https://www.bilibili.com/video/BV1zq4y1p7ga?p=399&spm_id_from=333.1007.top_right_bar_window_history.content.click

1. 前端路由

路由(router)就是对应关系

路由分为两大类:

(1)前端路由:Hash地址与组件之间的对应关系。

  • SPA与前端路由之间的关系:SPA指的是一个web网站只有唯一的一个HTML页面,所有组件的展示与切换都在这唯一一个页面内完成。此时不同组件之间的切换,要依赖于前端路由来完成。

(2)后端路由:请求方式、请求地址与function处理函数之间的对应关系。

前端路由的工作方式:

  1. 用户点击了页面上的路由链接
  2. 导致了URL地址栏中的Hash值发生了变化
  3. 前端路由监听到了Hash地址的变化
  4. 前端路由把当前Hash地址对应的组件渲染到浏览器中。


 2. vue-router 的基本使用

vue-route是vue.js官方给出路由解决方案,只能结合vue项目使用,能够轻松管理SPA项目中的组件切换。

注意版本:vue-router 3.x只能结合vue2使用,vue-router 4.x只能结合vue3使用!

(1)安装 vue-router 

npm i vue-router@next -S

(2)定义路由组件:在项目中定义所需的组件,将来要用vue-router控制它们的展示与切换。

(3)声明路由链接和占位符:使用标签声明路由链接,使用标签声明路由占位符。




(4)创建路由模块:在项目中创建router.js路由模块,在其中按如下步骤创建并得到路由对象:

  1. 从vue-router中按需导入两个方法
  2. 导入需要使用路由控制的组件
  3. 创建路由实例对象
  4. 向外共享路由实例对象
  5. 在main.js中导入并挂载路由模块
// router.js
// 1、从vue-router按需导入两个方法
// createRouter方法用于创建路由实例对象
// createWebHashHistory方法用于指定路由的工作模式(hash模式)
import { createRouter, createWebHashHistory } from 'vue-router'
// 2、导入需要使用路由控制的组件
import Home from './MyHome.vue'
import Movie from './MyMovie.vue'
import About from './MyAbout.vue'

// 3、创建路由对象
const router = createRouter({
  // 通过history属性,指定路由的工作模式
  history: createWebHashHistory(),
  // 自定义路由高亮的 class 类名,会覆盖掉默认的router-link-active类名
  linkActiveClass: 'active-router',
  // 通过routes数组,声明路由的匹配规则。
  // path是hash地址,component是要展示的组件,redirct是要重定向到的新地址
  routes: [
    { path: '/', redirect: '/home' },
    { path: '/home', component: Home },
    { path: '/movie', component: Movie },
    { path: '/about', component: About },
  ],
})

// 4、导出路由对象
export default router
// main.js
import { createApp } from 'vue'
import App from './components/start/App.vue'
// 5、在main.js中导入并挂载路由模块
import router from './components/start/router'
import './assets/css/bootstrap.css'
import './index.css'

const app = createApp(App)
// 挂载路由模块
app.use(router)
app.mount('#app')

 (5)路由重定向

路由重定向:用户在访问地址A的时候,强制用户跳转到地址C,从而展示特定的组件页面。

  • 通过路由规则的redirect属性,指定一个新的路由地址。

(6)路由高亮

将激活的路由链接进行高亮显示:

  • ① 使用默认的高亮class类:被激活的路由链接,默认会应用一个叫做router-link-active的类名,开发者可以使用此类名选择器,在index.css文件中为激活的路由链接设置高亮样式。
  • ② 自定义路由高亮的class类:在创建路由的实例对象时,开发者可以基于linkActiveClass属性,自定义路由链接被激活时所应用的类名。
/* index.css */
.router-link-active {
  background-color: red;
  color: white;
  font-weight: bold;
}

.active-router {
  background-color: blue;
  color: white;
  font-weight: bold;
}

3. vue-router 的高级用法

1. 嵌套路由

嵌套路由:通过路由实现组件的嵌套展示。

  1. 声明子路由链接和子路由占位符
  2. 在父路由规则中,通过children属性嵌套声明子路由规则



// router.js
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from './MyHome.vue'
import Movie from './MyMovie.vue'
import About from './MyAbout.vue'
import Tab1 from './tabs/MyTab1.vue'
import Tab2 from './tabs/MyTab2.vue'

const router = createRouter({
  history: createWebHashHistory(),
  linkActiveClass: 'active-router',
  routes: [
    { path: '/', redirect: '/home' },
    { path: '/home', component: Home },
    { path: '/movie', component: Movie },
    {
      path: '/about',
      component: About,
      // 嵌套路由的重定向
      redirect: '/about/tab1',
      // 通过 children 属性嵌套声明子级路由规则
      // 注意:子路由的path不要以/开头
      children: [
        { path: 'tab1', component: Tab1 },
        { path: 'tab2', component: Tab2 },
      ],
    },
  ],
})

export default router

2. 动态路由匹配

动态路由:把Hash地址中可变的部分定义为参数项,从而提高路由规则的复用性。

  • 在vue-router中使用英文的冒号(:)来定义路由的参数项。
  • ① 通过动态路由匹配的方式渲染出来的组件中,可以使用 $route.params 对象访问到动态匹配的参数值。【记住路由规则里的参数名称,因为必须用 $route.params.参数名称 来获取参数值】
  • ② 为了简化路由参数的获取方式,vue-rouetr允许在路由规则中开启props传参。
// router.js 关键部分代码
    // 动态路由匹配
    // 声明props:true选项,即可在MyMovie组件中,以props形式接收到路由规则匹配到的参数项
    { path: '/movie/:mid', component: Movie, props: true },
    
    电影1 
    电影2 
    电影3 



3. 编程式导航

(1)编程式导航 vs 声明式导航

  • 编程式导航:通过调用API实现导航的方式。
    • 在普通网页中调用location.href跳转到新页面的方式属于编程式导航。
  • 声明式导航:通过点击链接实现导航的方式。

(2)vue-router中的编程式导航API

  • 跳转到指定Hash地址,从而展示对应组件:this.$router.push('hash地址')
  • 实现导航历史的前进后退:this.$router.go(整数值)



4. 命名路由

命名路由:通过name属性为路由规则定义名称。

  • 注意:命名路由的name值不能重复,必须保证唯一性!
  • 使用命名路由实现声明式导航:为标签动态绑定to属性的值,并通过name属性指定要跳转到的路由规则。期间还可以使用params属性指定跳转期间要携带的路由参数。
  • 使用命名路由实现编程式导航:调用push函数期间制定一个配置对象,name是要跳转到的路由规则,params是携带的路由参数。
// router.js 关键部分代码
// 命名路由
    { name: 'mov', path: '/movie/:mid', component: Movie, props: true },



5. 导航守卫

导航守卫可以控制路由的访问权限。

(1)声明全局导航守卫:全局导航守卫会拦截每个路由规则,从而对每个路由进行访问权限的控制。

  • 在守卫方法中如果不声明next形参,则默认允许用户访问每一个路由!
  • 在守卫方法中如果声明了next形参,则必须调用next()函数,否则不允许用户访问任何一个路由!

(2)next函数的三种调用方式:

  • 直接放行:next() 
  • 强制其停留在当前页面:next(false) 
  • 强制其跳转到登录页面:next('/login') 
// router.js 部分关键代码

// 声明全局的导航守卫
// 三个可选参数:to目标路由对象; from当前导航正要离开的路由对象; next是一个函数,表示放行
router.beforeEach((to, from, next) => {
  const tokenStr = localStorage.getItem('token') // 1、读取token

  if (to.path === '/main' && !tokenStr) {  // 2、想访问“后台主页”,且token值不存在
    // next(false) // 3.1 不允许跳转
    next('/login') // 3.2 强制跳转到“登录页面”
  } else {
    next()  // 3.3 直接放行,允许访问后台主页
  }
})

4. 后台管理案例

知识点:命名路由、路由重定向、导航守卫、嵌套路由、动态路由匹配、编程式导航

main.js:

import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
import './assets/css/bootstrap.css'
// 1、导入路由模块
import router from './router'

const app=createApp(App)

//2、挂载路由对象
app.use(router)

app.mount('#app')

router.js:

//1、按需导入对应的函数
import { createRouter, createWebHashHistory } from "vue-router";

import Login from './components/MyLogin.vue'
import Home from './components/MyHome.vue'

import Users from './components/menus/MyUsers.vue'
import Rights from './components/menus/MyRights.vue'
import Goods from './components/menus/MyGoods.vue'
import Orders from './components/menus/MyOrders.vue'
import Settings from './components/menus/MySettings.vue'
import UserDetail from './components/user/MyUserDetail.vue'

//2、创建路由对象
const router=createRouter({
    history:createWebHashHistory(),
    routes:[
        // 路由重定向
        {path:'/',redirect:'/login'},
        {path:'/login',component:Login},
        {
            path:'/home',
            component:Home,
            // 用户访问/home时,重定向到/home/users
            redirect:'/home/users',
            // 子路由规则
            children:[
                {path:'users',component:Users},
                {path:'rights',component:Rights},
                {path:'goods',component:Goods},
                {path:'orders',component:Orders},
                {path:'settings',component:Settings},
                // 用户详情页的动态路由规则
                {path:'users/:id',component:UserDetail,props:true},
            ]
        },
    ],
})

// 全局路由导航守卫
router.beforeEach((to,from,next)=>{
    // 若用户访问的是登录页面,直接放行
    if(to.path==='/login') return next()
    // 获取Token值
    const token=localStorage.getItem('token')
    if(!token){  // 若Token值不存在,强致跳转登录页面
        return next('/login')
    }
    next()  // 存在token值,直接放行
})

//3、向外共享路由实例对象
export default router

index.css:

:root {
  font-size: 13px;
}

html,
body,
#app {
  height: 100%;
}

App.vue:



/components/MyLogin.vue:





/components/MyHome.vue:





/components/subcomponents/MyHeader.vue:





/components/subcomponents/MyAside.vue:略,只有样式,没有路由相关操作。

/components/menus/MyUsers.vue:






/components/menus/MyGoods.vue:略,只有样式,没有路由相关操作。

/components/menus/MyOrders.vue:略,只有样式,没有路由相关操作。

/components/menus/MyRights.vue:略,只有样式,没有路由相关操作。

/components/menus/MySettings.vue:略,只有样式,没有路由相关操作。

/components/user/MyUserDetail.vue:





你可能感兴趣的:(Vue,vue.js,javascript)