vue router 路由
简介
vue-router 路由:路径和组件的映射关系
Vue.js 官方的路由管理器。vue-router 本质是一个第三方包。
官网:vue-router
优点:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
路由 - 基础使用
效果
代码
步骤:
- 下载 vue-router 模块到当前工程
yarn add vue-router
- 在 main.js 中引入 VueRouter 函数
- 添加到 Vue.use() 身上-注册全局 RouterLink 和 RouterView 组件
- 创建路由规则数组–路径和组件名对应关系
- 用规则生成路由对象
- 把路由对象注入到 new Vue 实例中
- 用 router-view 作为挂载点,切换不同的路由页面
// main.js
import Vue from 'vue'
import App from './App.vue'
import Find from '@/views/Find' // @是src的绝对路径
import My from '@/views/My'
import Part from '@/views/Part'
// 目标:vue-router基础使用
// 1.下载vue-router (yarn add vue-router)
// 2.引入
import VueRouter from 'vue-router'
// 3.注册全局组件
Vue.use(VueRouter)
// 4.规则数组
const routes = [
{
path: '/find',
component: Find
},
{
path: '/my',
component: My
},{
path: '/part',
component: Part
},
]
// 5.生成路由对象
const router = new VueRouter({
routes // routes是固定key(传入规则数组)
})
Vue.config.productionTip = false
// 6.路由对象注入到vue实例中,this可以访问到$route和$touter
new Vue({
router,
render: h => h(App),
}).$mount('#app')
// App.vue
<template>
<div>
<div class="footer_wrap">
<a href="#/find">发现音乐</a>
<a href="#/my">我的音乐</a>
<a href="#/part">朋友</a>
</div>
<div class="top">
<!-- 7.设置挂载点 - 当url的hash值路径切换,显示规则里对应的组件到这 -->
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {};
</script>
【示例】
组件分类:.vue 文件分2类,一个是页面组件,一个是复用组件
- src / views文件夹
页面组件 - 页面展示 - 配合路由用 - src / components文件夹
复用组件 - 展示数据/常用于复用
声明式导航
可用组件router-link来替代a标签
- vue-router 提供了一个全局组件 router-link
- router-link 实质上最终会渲染成 a 链接 to 属性等价于提供 href 属性(to无需#)
- router-link 提供了声明式导航高亮的功能(自带类名)
效果
代码
// App.vue
<template>
<div>
<div class="footer_wrap">
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/part">朋友</router-link>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
// App.vue style - 激活时样式
/* 激活时样式 */
.footer_wrap .router-link-active {
color: white;
background: black;
}
声明式导航 - 页面传值
需求:在跳转路由时,可以给路由对应的组件内传值
方式一:to="/path?参数名=值"
效果
代码
// App.vue
<template>
<div>
<div class="footer_wrap">
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/part">朋友</router-link>
<router-link to="/part?name=259">关于259</router-link>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
// Part.vue
<template>
<div>
<p>关注明星</p>
<p>发现精彩</p>
<p>寻找伙伴</p>
<p>加入我们</p>
<p>by:{{$route.query.name}}</p>
</div>
</template>
方式二 - to="/path/值"(动态传值)
前提:需要在路由规则里配置/path/:参数名
效果
代码
// main.js
// 4.规则数组
const routes = [
{
path: '/find',
component: Find
},
{
path: '/my',
component: My
},{
path: '/part',
component: Part
}, {
path: '/part/:username',
// 有 : 的路径代表要接收具体的值
component: Part
}
]
// App.vue
<template>
<div>
<div class="footer_wrap">
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/part?name=259">By:259</router-link>
<router-link to="/part/zsq">关于 - zsq</router-link>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
// Part.vue
<template>
<div>
<p>关注明星</p>
<p>发现精彩</p>
<p>寻找伙伴</p>
<p>加入我们</p>
<p>by:{{$route.query.name}}</p>
<p>关于 - {{$route.params.username}}</p>
</div>
</template>
重定向和模式
匹配 path 后,强制跳转 path 路径
重定向路由路径
效果
代码
步骤:
- 规则里定义 path: ‘/’
- redirect 配置项,值为要强制切换的路由路径
// main.js
// 4.规则数组
const routes = [
{
path: "/", // 默认hash值路径
redirect: "/find" // 重定向到 /find
// 浏览器url中#后的路径被改变成/find-重新匹配规则
},
{
path: '/find',
component: Find
},
{
path: '/my',
component: My
}, {
path: '/part',
component: Part
}, {
path: '/part/:username',
// 有 : 的路径代表要接收具体的值
component: Part
}
]
路由 - 404设置
访问不存在的页面或访问路由路径有误,去提示页面
效果
代码
// main.js
// 4.规则数组
const routes = [
{
path: "/", // 默认hash值路径
redirect: "/find" // 重定向到 /find
// 浏览器url中#后的路径被改变成/find-重新匹配规则
},
{
path: '/find',
component: Find
},
{
path: '/my',
component: My
}, {
path: '/part',
component: Part
}, {
path: '/part/:username',
// 有 : 的路径代表要接收具体的值
component: Part
},
// 404 在最后(规则是从前往后逐个比较path)
{
path: '*',
component: NotFound
}
]
路由 - 模式修改
简介
修改路由在地址栏的模式
- hash 路由
http://localhost:8080/#/home - history 路由
http://localhost:8080/home (以后上线需要服务器端支持,否则找的是文件夹)
效果
代码
// main.js
// 5.生成路由对象
const router = new VueRouter({
routes, // routes是固定key(传入规则数组)
mode: "history" // 默认不写就是hash
})
编程式导航
简介
用 JS 代码来进行跳转
语法:
- this. $ router.push({path:“路由路径”})
- this. $ router.push({name:“路由名”})
效果
方法一:
this. $ router.push({path:"路由路径"})
代码
// App.vue
<template>
<div>
<div class="footer_wrap">
<span @click="btn('/find')">发现音乐</span>
<span @click="btn('/my')">我的音乐</span>
<span @click="btn('/part')">传值</span>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
// this.$router.push({path:"路由路径"})
export default {
methods: {
btn(targetPath) {
// 方式一:path跳转
this.$router.push({
path: targetPath
})
},
}
};
</script>
方法二:
this. $ router.push({name:"路由名"})
注意:
虽然用 name 跳转,但是 url 的 hash 值还是切换 path 路径(name 路由名,方便修改)
代码
// main.js
// 4.规则数组
const routes = [
{
path: "/", // 默认hash值路径
redirect: "/find" // 重定向到 /find
// 浏览器url中#后的路径被改变成/find-重新匹配规则
},
{
path: '/find',
name: "Find",
component: Find
},
{
path: '/my',
name: "My",
component: My
}, {
path: '/part',
name: "Part",
component: Part
}, {
path: '/part/:username',
// 有 : 的路径代表要接收具体的值
component: Part
},
// 404 在最后(规则是从前往后逐个比较path)
{
path: '*',
component: NotFound
}
]
// App.vue
<template>
<div>
<div class="footer_wrap">
<span @click="btn('/find', 'Find')">发现音乐</span>
<span @click="btn('/my', 'My')">我的音乐</span>
<span @click="btn('/part', 'Part')">传值</span>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
methods: {
btn (targetPath, targetName) {
this.$router.push({
// path: targetPath
name: targetName
})
},
}
};
</script>
编程式导航 - 传值
JS跳转路由,传参
方法一:params
效果
代码
// App.vue
<template>
<div>
<div class="footer_wrap">
<span @click="btn('/find', 'Find')">发现音乐</span>
<span @click="btn('/my', 'My')">我的音乐</span>
<span @click="oneBtn">by:259</span>
<span @click="twoBtn">关于 - zsq</span>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
methods: {
btn (targetPath, targetName) {
// 方式一:path跳转
this.$router.push({
// path: targetPath
name: targetName
})
},
oneBtn () {
this.$router.push({
name: 'Part',
params: {
username: 'zsq'
}
})
},
twoBtn () { },
}
};
// Part.vue
<template>
<div>
<p>关注明星</p>
<p>发现精彩</p>
<p>寻找伙伴</p>
<p>加入我们</p>
<p>by:{{$route.query.name}}</p>
<p>关于 - {{$route.params.username}}</p>
</div>
</template>
方法二:query
path 会自动忽略 params
推荐 :name + query 方式传参
效果
代码
// App.vue
<template>
<div>
<div class="footer_wrap">
<span @click="btn('/find', 'Find')">发现音乐</span>
<span @click="btn('/my', 'My')">我的音乐</span>
<span @click="oneBtn">by:259</span>
<span @click="twoBtn">关于 - zsq</span>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
methods: {
btn (targetPath, targetName) {
// 方式一:path跳转
this.$router.push({
// path: targetPath
name: targetName
})
},
oneBtn () {
this.$router.push({
name: 'Part',
params: {
username: 'zsq'
}
})
},
twoBtn () { },
}
};
// main.js
<script>
export default {
methods: {
btn (targetPath, targetName) {
// 方式一:path跳转
this.$router.push({
// path: targetPath
name: targetName
})
},
oneBtn () {
this.$router.push({
name: 'Part',
params: {
username: 'zsq'
}
})
},
twoBtn () {
this.$router.push({
name: 'Part',
query: {
name: '259'
}
})
},
}
};
</script>
其它
Exception:如果当前 url 上" hash 值和?参数"与你要跳转到的" hash 值和?参数"一致,爆出冗余导航的问题,不会跳转路由
路由 - 嵌套
在现有的一级路由下,再嵌套二级路由
效果
代码
步骤:
- 创建需要的二级页面组件
- 路由规则里 childern 中配置二级路由规则对象(二级路由 path 一般不写根路径 / )
// main.js
import Vue from 'vue'
import App from './App.vue'
import Find from '@/views/Find' // @是src的绝对路径
import My from '@/views/My'
import Part from '@/views/Part'
import NotFound from '@/views/NotFound'
import Recommend from '@/views/Second/Recommend'
import Ranking from '@/views/Second/Ranking'
import SongList from '@/views/Second/SongList'
// 目标:vue-router基础使用
// 1.下载vue-router (yarn add vue-router)
// 2.引入
import VueRouter from 'vue-router'
// 3.注册全局组件
Vue.use(VueRouter)
// 4.规则数组
const routes = [
{
path: "/", // 默认hash值路径
redirect: "/find" // 重定向到 /find
// 浏览器url中#后的路径被改变成/find-重新匹配规则
},
{
path: '/find',
name: "Find",
component: Find,
children: [
{
path: "recommend",
component: Recommend
},
{
path: "ranking",
component: Ranking
},
{
path: "songList",
component: SongList
}
]
},
{
path: '/my',
name: "My",
component: My
}, {
path: '/part',
name: "Find",
component: Part
}, {
path: '/part/:username',
// 有 : 的路径代表要接收具体的值
name: "Part",
component: Part
},
// 404 在最后(规则是从前往后逐个比较path)
{
path: '*',
component: NotFound
}
]
- 一级页面中设置 router-view 显示二级路由页面(跳转时路径要从 / 开始写)
// Find.vue
<template>
<div>
<div class="nav_main">
<!-- 从根路径开始写 -->
<router-link to="/find/recommend">推荐</router-link>
<router-link to="/find/ranking">排行榜</router-link>
<router-link to="/find/songlist">歌单</router-link>
</div>
<div style="1px solid red;">
<router-view></router-view>
</div>
</div>
</template>
问点
- 二级路由:
- 二级路由 path 一般不写根路径 /
- 跳转时,路径要从 / 开始写
路由 - 激活类名的区别
自动添加的2个类名的区别:
- router-link-exact-active — url 的 hash 值和 href(完全匹配)
- router-link-active — url 的 hash 值包含 href 路径值(模糊匹配)
路由 - 守卫
全局前置守卫:给路由添加一个权限判断
简介
效果
代码
// main.js
router.beforeEach((to, from, next) => {
console.log(to);
console.log(from);
console.log(next);
})
示例
效果
代码
// main.js - 登录失败
const isLogin = false // 登录状态(未登录)
router.beforeEach((to, from, next) => {
if (to.path === '/my' && isLogin === false) {
alert("请登录")
next(false) // 阻止路由跳转
} else {
next() // 正常放行
}
})
// main.js - 登录成功
const isLogin = true // 登录状态(已登录)
router.beforeEach((to, from, next) => {
if (to.path === '/my' && isLogin === false) {
alert("请登录")
next(false) // 阻止路由跳转
} else {
next() // 正常放行
}
})
- 语法: router.beforeEach((to, from, next)=> {})
定调next(),才会跳转下一页 - 路由在真正跳转前,会执行一次 beforeEach 函数,next 调
用则跳转,也可以强制修改要跳转的路由
其它
【扩展】
单页面应用(SPA):所有功能在一个html页面上实现
前端路由作用:实现业务场景切换
优点:
- 整体不刷新页面,用户体验更好
- 数据传递容易,开发效率高
缺点:
- 开发成本高(需要学习专门知识)
- 首次加载会比较慢一点。不利于seo(搜索排名)