文章目录
Vue2,VueRouter的基本使用
VueRouter的下载安装
-
Vue-router 要单独引用,版本3.x以上
-
需要先引用Vue再引用Vue Router
VueRouter创建的五个步骤
1.定义组件
// 1.定义组件
let findMusic={
template:'<div>发现音乐的内容</div>'
}
let myMusic={
template:'<div>我的音乐的内容</div>'
}
let friend={
template:'<div>关注</div>'
}
2.定义路径
// 2.定义路径,路径是个数组,存着一个个对象
const routes=[
{
path:"/findMusic",
component:findMusic
},
{
path:"/myMusic",
component:myMusic
},
{
path:"/friend",
component:friend
}
]
3.生成router实例对象
// 3.生成Router实例对象
const router=new VueRouter({
routes
})
4.将路由挂载到Vue中
// 4.将路由挂载到Vue实例中
const app=new Vue({
el:'#app',
router,
components:{
myNav
}
})
5.占据坑位
<div id="app">
<!-- 顶部导航栏 -->
<my-nav></my-nav>
<!-- 5.占坑位 -->
<router-view></router-view>
</div>
详细代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.nav ul{
display: flex;
list-style: none;
}
.nav ul li {
margin: 20px
}
</style>
</head>
<body>
<div id="app">
<!-- 顶部导航栏 -->
<my-nav></my-nav>
<!-- 5.占坑位 -->
<router-view></router-view>
</div>
<!-- 导航栏的模板 -->
<template id="mynav">
<div class="nav">
<ul>
<li>
<router-link to="/myMusic"> 我的音乐</router-link>
//链接到/myMusic路线
</li>
<li>
<router-link to="/findMusic">查询音乐</router-link>
</li>
<li>
<router-link to="/friend">我的关注</router-link>
</li>
</ul>
</div>
</template>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script>
//导航栏组件
let myNav={
template:"#mynav"
}
//好,我们开始路由的创建
// 1.定义组件
let findMusic={
template:'<div>发现音乐的内容</div>'
}
let myMusic={
template:'<div>我的音乐的内容</div>'
}
let friend={
template:'<div>关注</div>'
}
// 2.定义路径,路径是个数组,存着一个个对象
const routes=[
{
path:"/findMusic",
component:findMusic
},
{
path:"/myMusic",
component:myMusic
},
{
path:"/friend",
component:friend
}
]
// 3.生成Router实例对象
const router=new VueRouter({
routes
})
// 4.将路由挂载到Vue实例中
const app=new Vue({
el:'#app',
router,
components:{
myNav
}
})
</script>
</html>
效果如下:
当你点击不同的链接会跳转到不同的内容。
注意:router-link
可以当做一个链接,to
后面是链接跳转的地址,这是VueRouter中的方法。
动态路由
动态路由实际上就是我们每次接受到的地址都是变化的,我们去获取到这个变化的地址,从而在不同的路由间实现跳转。通过前面Vue的学习我们知道了属性变成动态属性的方法,这里也是一样,我们将to写成:to
。我们来看演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.nav ul {
display: flex;
list-style: none;
}
.nav ul li {
margin: 20px
}
</style>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in articleList">
<router-link :to="'/detail/'+item.id">{{item.name}}</router-link>
<!-- 这里每次的to对应的地址不同 -->
</li>
</ul>
<!-- 占据坑位 -->
<router-view></router-view>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script>
// 开始创建路由
// 1.定义组件
let articleDetail = {
template: '<div>这是文章{{$route.params.id}}的详情页面</div>'
}
// 2.定义路径
const routes = [
{
path: '/',
redirect: "/detail/1" //重定向
},
{
path: "/detail/:id",
component: articleDetail
},
{
path: '*',
redirect: "/detail/1"
}
]
// 3.创建router实例对象
const router = new VueRouter({
routes
})
const app = new Vue({
el: '#app',
router, //挂载
data: {
articleList: [
{
name: 'Javascript基础',
id: 1
},
{
name: 'Vue项目实战开发',
id: 2
}
]
}
})
</script>
</body>
</html>
效果图如下:
注意:
-
注意我们的
to="/detail/'item.id'"
,这就是一个动态的地址,我们在下面路由的描述中也是接收了该变量,/detail/:id
。 -
注意这里在定义路径的时候我们写到了重定向,意思就是当为path地址时自动跳转到重定向的位置。
嵌套路由
嵌套路由就是在一条路由线上增加子路由,就像是子组件一样,我们来直接看代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<ul>
<li>
<router-link to="/home">首页</router-link>
</li>
<li>
<router-link to="/login"> 登录</router-link>
</li>
</ul>
<router-view></router-view>
</div>
<template id="login">
<div>
<router-link to="/login/duanxin">短信登录</router-link>
<router-link to="/login/account">账号密码登录</router-link>
<router-view></router-view>
<!-- 这里注意也要写一个坑,因为是嵌套路由有一层需要在这里显现 -->
</div>
</template>
<script src="../node_modules/vue/dist/vue.js"></script>
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script>
//定义组件
let home = {
template: '<div>首页</div>'
}
let login = {
template: '#login'
}
let duanxinLogin = {
template: '<div>这是短信登录界面</div>'
}
let accountLogin = {
template: '<div>这是账号密码登录界面</div>'
}
// 定义路线
const routes = [
{
path: "/home",
component: home
},
{
path: "/login",
component: login,
children: [ //这里开始嵌套,就是作为该组件的儿子存在
{
path:"duanxin",
component: duanxinLogin
},
{
path: "account",
component: accountLogin
}
]
}
]
// 创建实例
const router = new VueRouter({
routes
})
const app = new Vue({
el: '#app',
router //挂载
})
</script>
</body>
</html>
效果图如下:
注意:
- 注意我们的嵌套路由写法,是在
routes
中的单个路由线路中定义children
- 以“/login”开头的嵌套路径会被当作根路径,所以子路由上不用加“/login”;在生成路由时,主路由上的path会被自动添加到子路由之前,所以子路由上的path不用在重新声明主路由上的path了。
- 别忘记我们的最后一步占坑位,并且注意到
<router-view></router-view>
的位置,这里我们写到login
组件的template的模板中。
编程式导航
router.push()
- 除了使用
<router-link>
创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。 - 想要导航到不同的 URL,则使用
router.push
方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。 - 当你点击
<router-link>
时,这个方法会在内部调用,所以说,点击<router-link :to="...">
等同于调用router.push(...)
。
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
我们直接上实例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.nav ul {
display: flex;
list-style: none;
}
.nav ul li {
margin: 20px
}
</style>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in articleList">
<!-- <router-link :to="'/detail/'+item.id">{{item.name}}</router-link>
-->
<!-- 这里每次的to对应的地址不同 -->
<button @click="gotoDetail(item.id)">点击跳转到文章{{item.name}}详情页</button>
</li>
</ul>
<!-- 占据坑位 -->
<router-view></router-view>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script>
// 开始创建路由
// 1.定义组件
let articleDetail = {
template: '<div>这是文章{{$route.query.id}}的详情页面</div>'
}
// 2.定义路径
const routes = [
{
path: '/',
redirect: "/detail/1" //重定向
},
{
path: "/detail/:id",
component: articleDetail,
name: 'detail'
},
{
path: '*',
redirect: "/detail/1"
}
]
// 3.创建router实例对象
const router = new VueRouter({
routes
})
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
const app = new Vue({
el: '#app',
router, //挂载
data: {
articleList: [
{
name: 'Javascript基础',
id: 1
},
{
name: 'Vue项目实战开发',
id: 2
}
]
},
methods: {
gotoDetail(id) { //定义方法
this.$router.push({ //路由跳转
// name: 'detail',
path:'/detail',
query: {
id
}
})
}
}
})
</script>
</body>
</html>
效果图如下:
注意:
- 这里用的是编程式导航,我们将
push
放入到了点击事件当中,效果和<router-link>
一样,不仅如此两者的参数要求和写法也是一样的。 - 跳转路径可以写
name
,也可以使用path
,不过写name
在routes
的时候必须定义好哪个线路的name
是什么,这就是命名路由。 - 关于传值我们后面会讲解,会讲解
params
,querry
,props
的方法和使用场景。
router.replace()
- 跟
router.push
很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。 - 声明式:
<router-link :to="..." replace>
,编程式:router.replace(...)
router.go()
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)
// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)
命名路由
有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes
配置中给某个路由设置名称。
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: User
}
]
})
要链接到一个命名路由,可以给 router-link
的 to
属性传一个对象,或者是编程式路由中的router.push。
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
router.push({ name: 'user', params: { userId: 123 } })
命名视图
这就很像我们命名插槽了,我们可以讲视图命名,这样我们就能将不同路由根据我们想要的应用场合使用。
来看实例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- 内容的坑 -->
<router-view name="default"></router-view>
<!-- 导航坑 -->
<router-view name="nav"></router-view>
</div>
<template id="mynav">
<ul>
<li>
<router-link to="/home">首页</router-link>
</li>
<li>
<router-link to="/login">登录</router-link>
</li>
</ul>
</template>
<script src="./node_modules/vue/dist/vue.js"></script>
<script src="./node_modules/vue-router/dist/vue-router.js"></script>
<script>
let myNav = {
template: "#mynav"
}
let home = {
template: "<div>home</div>"
}
let login = {
template: "<div>这是Login页面</div>"
}
const routes = [
{
path: "/home",
components: {
nav: myNav,
default: home
}
},
{
path: "/login",
component: login,
},
{
path:'/',
redirect:'/home'
}
]
const router = new VueRouter({
routes
})
const app = new Vue({
el: "#app",
router
})
</script>
</body>
</html>
效果图如下:
注意:
- 注意命名视图的时候在
routes
里的定义 - 我们命名好视图可以根据要求在html中摆放
路由的重命名和别名
重定向官方描述:
当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b,然后匹配路由为 /b
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' }
]
})
重定向的目标也可以是一个命名的路由:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }}
]
})
甚至是一个方法,动态返回重定向目标:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: to => {
// 方法接收 目标路由 作为参数
// return 重定向的 字符串路径/路径对象
}}
]
})
常用场景:vue router 重定向的作用是为了防止用户乱输文件名,当用户输入与系统无关路径会跳转到指定的页面。
别名的官方描述:
/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
常用场景:
- 对外隐藏路径
- 写代码的时候可以用别名代替实际路径,到时候如果项目中跳转页面需要变更,只需要更改路由配置即可,可以当成路径的变量看代。
路由组件传参
- props设置为true,可以接受
params
的方法进行传递
{
path:"login/:username/:password",
compotent:content,
props:true
}
props
为函数
时进行传值,此时用的query
方式进行参数的传递
{
path:"login",
compotent:content,
props(route){
username:route.query.name,
password:route.query.password
}
}
props
为对象
的方式进行处理静态数据
{
path:"login",
compotent:content,
props:{
username:'admin',
password:'123456'
}
}
params和query的区别
-
params进行路由传参的时候只能由name引入
-
query进行路由传参的时候name和path都可以使用
-
-params的参数是URL不可或缺的一部分,但是query的参数是拼接起来的,没有也不影响
-
query传递参数会在url后面用?连接起来,且参数之间用&&符号连接然后显示在页面的url中,params传递参数不会显示在页面中;query有点像ajax中的get请求,而params像post请求。
-
他们的引用方法
$route.params
$route.query
-
使用props的时候两者的写法区别,上文中提到
History
vue-router
默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。
如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState
API 来完成 URL 跳转而无须重新加载页面。
const router = new VueRouter({
mode: 'history',
routes: [...]
})
当你使用 history 模式时,URL 就像正常的 url,例如 http://yoursite.com/user/id
,也好看!
不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id
就会返回 404,这就不好看了。
所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html
页面,这个页面就是你 app 依赖的页面.
常用history API 介绍
window.history.back(); //后退
window.history.forward() //前进
window.history.go(-3) //后退3个界面