【Vue2】Router 路由
1.什么是单页面应用程序
单页面应用程序(英文名: Single Page Application)简称SPA,
顾名思义,指的是一个Web网站中只有唯一-的一-个HTML页面,
所有的功能与交互都在这唯--的一个页面内完成。
结论:在SPA项目中,不同功能之间的切换,要依赖于前端路由来完成!
4.什么是前端路由
通俗易懂的概念: Hash地址与组件之间的对应关系。
5.前端路由的工作方式
① 用户点击了页面.上的路由链接
② 导致了URL地址栏中的Hash值发生了变化
③ 前端路由监听了到Hash地址的变化
④ 前端路由把当前Hash地址对应的组件渲染都浏览器中
6、手写路由案例:
<template> <div id="app"> <a href="#/index">首页</a> | <a href="#/movie">电影</a> | <a href="#/about">关于</a> <component :is="routerName"></component> </div> </template> <script> import Home from '@/components/Home.vue' import Movie from '@/components/Movie.vue' import About from '@/components/About.vue' export default { name: 'App', components: { Home, Movie, About }, data() { return { routerName: '' } }, created() { window.onhashchange = () => { const hash = location.hash switch (hash) { case '#/home': this.routerName = 'Home' break case '#/Movie': this.routerName = 'Movie' break case '#/About': this.routerName = 'About' break } } }, } </script> <style lang="less"> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
1.什么是vue-router
vue-router是vue.js官方给出的路由解决方案。
它只能结合vue项目进行使用,能够轻松的管理SPA项目中组件的切换。
vue-router的官方文档地址: https://router.vuejs.org/zh/
2.使用Vue-Router步骤
① 安装vue-router包
npm i vue-router@3.5.2 -S
② 创建路由模块
router/index.js
// 导入资源配置
import Vue from 'vue' import Router from 'vue-router' // 安装Router插件 Vue.use(Router)
// 创建路由实例 const router = new Router() // 导出Router实例 export default router
③ 导入并挂载路由模块
main.js文件中,Vue实例,入参路由实例
import Vue from 'vue' import App from './App.vue' Vue.config.productionTip = false // ES6 模块导入 如果提供的是一个目录地址,默认导入里面index名称文件 // import router from '@/router/index.js' import router from '@/router/index.js' new Vue({ render: h => h(App), router }).$mount('#app')
④ 声明路由链接和占位符
配置路由和地址的对应关系:
import Vue from 'vue' import Router from 'vue-router' // 把路由对应的组件和Hash映射起来 import Home from '@/components/Index.vue' import Movie from '@/components/Movie.vue' import About from '@/components/About.vue' Vue.use(Router)
// 配置路由列表 path不需要写#号 const routes = [ { path: '/home', component: Home }, { path: '/movie', component: Movie }, { path: '/about', component: About } ]
// 注册到路由实例中 const router = new Router({ routes }) export default router
更改原来的手写路由分配,App.vue:
改用 router-view占位符标签实现路由分配
<template> <div id="app"> <a href="#/index">首页</a> | <a href="#/movie">电影</a> | <a href="#/about">关于</a> <router-view></router-view> </div> </template>
<script> export default { name: 'App' } </script> <style lang="less"> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
可以使用router-link代替a标签,router-link本身还是使用a标签做的
使用Router-link替换a标签 <router-link to="/index">首页</router-link> | <router-link to="/movie">电影</router-link> | <router-link to="/about">关于</router-link>
2.1、懒加载路由
https://www.cnblogs.com/mindzone/p/13909668.html
3、路由重定向问题
新的问题是,进入页面后没有默认页,需要用户自己手动点击,才会跳转
所以需要把首页在进入页面时就路由进来,这个功能可以使用路由重定向来解决:
// 配置路由列表 path不需要写#号 const routes = [ { path: '/', redirect: '/home' }, { path: '/home', component: Home }, { path: '/movie', component: Movie }, { path: '/about', component: About } ]
4、子路由和子路由占位符
路由配置:
import Vue from 'vue' import Router from 'vue-router' // 把路由对应的组件和Hash映射起来 import Home from '@/components/Index.vue' import Movie from '@/components/Movie.vue' import About from '@/components/About.vue' // 引入子组件 import SubPage1 from '@/components/about/SubPage1.vue' import SubPage2 from '@/components/about/SubPage2.vue' // 安装Router插件 Vue.use(Router) // 设定路由的配置项 const routes = [ { path: '/', redirect: '/index'}, { path: '/index', component: Home }, { path: '/about', component: About, children: [ // 子组件不能写斜杠开头, router会默认视为第一层级的规则来分配 { path: 'tab1', component: SubPage1 }, { path: 'tab2', component: SubPage2 } ] } ] const router = new Router({ routes }) export default router
在About组件中编写对应的占位符:
<template> <div> <h3>关于 组件</h3> <p> <router-link to="/about/tab1" >子页面1</router-link> <router-link to="/about/tab2" >子页面2</router-link> </p> <router-view></router-view> </div> </template> <script> export default { name: 'About' } </script>
5、默认子路由或者重定向
import Vue from 'vue' import Router from 'vue-router' // 把路由对应的组件和Hash映射起来 import Home from '@/components/Index.vue' import Movie from '@/components/Movie.vue' import About from '@/components/About.vue' // 引入子组件 import SubPage1 from '@/components/about/SubPage1.vue' import SubPage2 from '@/components/about/SubPage2.vue' // 安装Router插件 Vue.use(Router) // 设定路由的配置项 const routes = [ { path: '/', redirect: '/index'}, { path: '/index', component: Home }, { path: '/about', component: About, // 方式一:使用重定向配置 redirect: '/about/tab1', children: [ // 方式二:使用默认子路由,省略路径实现 // { path: '', component: SubPage1 }, { path: 'tab1', component: SubPage1 }, { path: 'tab2', component: SubPage2 } ] } ] const router = new Router({ routes }) export default router
6、动态路由实现
类似Rest风格,根据参数动态渲染页面的内容,提高页面的复用性
<template> <div id="app"> <router-link to="/movie/1">电影1</router-link> | <router-link to="/movie/2">电影2</router-link> | <router-link to="/movie/3>电影3</router-link> <hr> <router-view></router-view> </div> </template> <script> export default { name: 'App', } </script> <style lang="less"> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
路由配置时,声明一个动态路径参数标记:
在vue-router中使用英文的冒号(:) 来定义路由的参数项。
import Vue from 'vue' import Router from 'vue-router' // 把路由对应的组件和Hash映射起来 import Movie from '@/components/Movie.vue' // 安装Router插件 Vue.use(Router) // 设定路由的配置项 const routes = [ /** * 动态参数配置 * * props: true 开启props属性传参 */ { path: '/movie/:id', component: Movie }, ] const router = new Router({ routes }) export default router
组件会把路由的路径参数封装成对象获取,通过下面这段代码获取
this.$route.params.id
可以开启Props属性来接收参数
<template> <div> <!-- this.$route.params 可以获取路由的参数 --> <h3>电影 组件 </h3> <p> 路由Rest参数 {{ $route.params.id }} -> {{ id }}</p> </div> </template> <script> export default { name: 'Movie', props: { id: { type: String, default: '' } } } </script>
7、路径参数和查询参数
<template> <div> <h3>电影 组件 </h3> <p> 路由Rest参数 {{ $route.params.id }} -> {{ id }}</p> <p> 路由Query查询参数 {{ $route.query }}</p> </div> </template> <script> export default { name: 'Movie', props: { id: { type: String, default: '' } } } </script>
在使用路由时,附加查询参数:
<template> <div id="app"> <router-link to="/movie/1">电影1</router-link> | <router-link to="/movie/2">电影2</router-link> | <router-link to="/movie/3?aaa=100&bbb=true">电影3</router-link> <hr> <router-view></router-view> </div> </template> <script> export default { name: 'App' } </script> <style lang="less"> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
8、编码式路由的跳转
<template> <div> <!-- this.$route.params 可以获取路由的参数 --> <h3>电影 组件 </h3> <p> 路由Rest参数 {{ $route.params.id }} -> {{ id }}</p> <p> 路由Query查询参数 {{ $route.query }}</p> <!-- 声明式导航,向上面这种直接写标签和路径的实现组件跳转被称为声明式导航 普通网页中点击<a>链接、vue项目中点击<router-link>都属于声明式导航 编程式导航, 利用浏览器API实现导航的方式 普通网页中调用location.href跳转到新页面的方式,属于编程式导航 5.1 vue-router中的编程式导航API vue-router提供了许多编程式导航的API,其中最常用的导航API分别是: ①this.$router.push('hash 地址') 跳转指定Hash地址,并增加一条历史记录 ②this.$router.replace('hash 地址') 跳转指定Hash地址,并替换当前的历史记录 ③this.$router.go(数值 n), 在历史记录中进行前进和后退 0 表示当前页 -1 后退一页 如果后退的页数超过了历史记录的上限,则原地不动 1 前进一页 在实际开发中,一般只会前进和后退一层页面。因此vue-router提供了如下两个便捷方法: ①$router.back() ②$router .forward() 导航守卫: 控制路由能否跳转 全局前置首位 --> <button @click="toMovie1"> 跳转到 电影1</button> <br> <button @click="toAbout"> 跳转到 关于</button> </div> </template> <script> export default { name: 'Movie', props: { id: { type: String, default: '' } }, methods: { toMovie1 () { // 直接在 <router-view> 标签中跳转 this.$router.push('/movie/1') }, toAbout () { this.$router.push('/about') } }, } </script>
9、路由跳转守卫:
import Vue from 'vue' import Router from 'vue-router' // 把路由对应的组件和Hash映射起来 import Home from '@/components/Index.vue' import Movie from '@/components/Movie.vue' import About from '@/components/About.vue' // 引入子组件 import SubPage1 from '@/components/about/SubPage1.vue' import SubPage2 from '@/components/about/SubPage2.vue' // 安装Router插件 Vue.use(Router) // 设定路由的配置项 const routes = [ { path: '/', redirect: '/index'}, { path: '/index', component: Home }, { path: '/movie/:id', component: Movie, props: true }, { path: '/about', component: About, redirect: '/about/tab1', children: [ { path: 'tab1', component: SubPage1 }, { path: 'tab2', component: SubPage2 } ] } ] const router = new Router({ routes }) /** * 全局前置守卫 * //调用路由实例对象的beforeEach 方法,即可声明“全局前置守卫” * //每次发生路由导航跳转的时候,都会自动触发fn这个“回调函数" */ router.beforeEach(function(to, from, next) { // to是将要访问的路由的信息对象 // from是将要离开的路由的信息对象 // next 是一个函数,调用next() 表示放行,允许这次路由导航 // console.log(`to -> ${JSON.stringify(to)}`) // console.log(`from -> ${JSON.stringify(from)}`) /** * 当前用户拥有后台主页的访问权限,直接放行: next() * 当前用户没有后台主页的访问权限,强制其跳转到登录页面: next('/login') * 当前用户没有后台主页的访问权限,不允许跳转到后台主页: next(false) */ next() }) export default router
9.1、局部组件路由配置:
https://www.cnblogs.com/mindzone/p/13910845.html