路由可以分为前端路由和后端路由
后端路由:
- 概念:根据不同的用户url请求,返回不同的内容
- 本质:URL请求地址和服务器资源之间的对应关系
为什么要有前端路由:
前端路由
- 概念:前端路由指的是根据不同的,显示不同的页面内容
- 本质:用户事件与事件处理函数之间的对应关系
实现简单前端路由
一个简单的模拟路由代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./js/vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="app">
<a href="#/index">主页</a>
<a href="#/tecn">科技</a>
<a href="#/economic">财经</a>
<a href="#/joy">娱乐</a>
<component :is="comName"></component>
<!-- 这个component是用来占位的,为了可以更换组件 -->
</div>
<script>
const index = {
template:`<h1>主页</h1>`
}
const tecn = {
template:`<h1>科技</h1>`
}
const economic = {
template:`<h1>财经</h1>`
}
const joy = {
template:`<h1>娱乐</h1>`
}
var app = new Vue({
el:'#app',
data:{
comName:'index'
},
components:{
index,
tecn,
economic,
joy
}
})
window.onhashchange = function(){//检测hash的改变但是不刷新页面
console.log(location.hash);//新的hash存储在这儿
// var str = location.hash
// var path = ''
// for(var i = 2;i<str.length;i++){
// path+=str[i]
// }
// app.comName = path
app.comName = location.hash.slice(2)
//用slice做字符串截取比较的方便
}
</script>
</body>
</html>
这样子做的网页,可以是回退的
vue-router
vue-router是Vue官方提供的路由管理器
其支持的功能有:
- 支持HTML5 历史模式或hash模式
- 支持嵌套路由
- 支持路由参数
- 支持编程式路由
- 支持命名路由
vue-router的基本使用
1 引入相关库文件
2 添加路由链接
3 添加路由填充位
4 定义路由组件
5 配置路由规则并创建路由实例
6 把路由挂载到Vue根实例中
一个例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./js/vue.js"></script>
<script src="./js/vue-router.js"></script>
<title>Document</title>
</head>
<body>
<div id="app">
<router-link to='/user'>User</router-link>
<router-link to='/register'>Register</router-link>
<!-- 路由填充位(路由占位符):将来通过路由匹配到的组件都会被填充到这里 -->
<router-view></router-view>
</div>
<script>
const User = {
template:`<h1>User</h1>`
}
const Register = {
template:`<h1>Register</h1>`
}
const router = new VueRouter({
routes: [
//每个路由规则都是一个配置对象,其中至少包含path和component两个属性
//pash表示当前路由规则说匹配的hsah地址
//component表示当前路由规则对应要展示的组件
{path:'/user',component:User},
{path:'/Register',component:Register}
]
})
var vm = new Vue({
el:'#app',
data:{},
//挂载路由
// router:router
router//在ES6中,属性名和属性对象是同名的话,可以直接这么简写
})
</script>
</body>
</html>
路由重定向:
通过路由规则的redirect属性,指向一个新的路由地址。
比如刚才的案例,我们想要实现一上来展示的默认组件就是User,就可以用到路由重定向
const router = new VueRouter({
routes: [
//每个路由规则都是一个配置对象,其中至少包含path和component两个属性
//pash表示当前路由规则说匹配的hsah地址
//component表示当前路由规则对应要展示的组件
{path:'/',redirect:User},
{path:'/user',component:User},
{path:'/Register',component:Register}
]
})
vue-router嵌套路由
对之前的案例做如下改进
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./js/vue.js"></script>
<script src="./js/vue-router.js"></script>
<title>Document</title>
</head>
<body>
<div id="app">
<router-link to='/user'>User</router-link>
<router-link to='/register'>Register</router-link>
<!-- 路由填充位(路由占位符):将来通过路由匹配到的组件都会被填充到这里 -->
<router-view></router-view>
</div>
<script>
const User = {
template:`<h1>User</h1>`
}
const Register = {
template:`
<div>
<h1>Register组件</h1>
<hr>
<router-link to='/register/tab1'>tab1</router-link>
<router-link to='/register/tab2'>tab2</router-link>
<router-view></router-view>
</div>
`
}
const Tab1 = {
template:`<h3>tab1</h3>`
}
const Tab2 = {
template:`<h3>tab2</h3>`
}
const router = new VueRouter({
routes: [
//每个路由规则都是一个配置对象,其中至少包含path和component两个属性
//pash表示当前路由规则说匹配的hsah地址
//component表示当前路由规则对应要展示的组件
{path:'/',redirect:User},
{path:'/user',component:User},
{path:'/register',component:Register,
children:[
{path:'/register/tab1',component:Tab1},
{path:'/register/tab2',component:Tab2}
]
},
]
})
var vm = new Vue({
el:'#app',
data:{},
//挂载路由
// router:router
router//在ES6中,属性名和属性对象是同名的话,可以直接这么简写
})
</script>
</body>
</html>
vue-router路由动态匹配
eg:
var router = new VueRouter({
routers:[
//动态路由参数,以冒号开头
{path:'/user/:id',component:User}
]
})
const User = {
template:`<div>User {{ $route.params.id }}</div>` //使用刚刚从路由中获取到的id
}
像上面那种写法,确实可以做到路由传参,但是$route与对应的路由高度耦合,不够灵活,所以可以使用props将组件和路由解耦合
props路由传参
三种方法:
1 传递路由参数
var User = {
props:['id'],
template: "<h1>User {{id}}</h1>"
}
{path:'/User/:id',component:User,props:true},
2 传递静态资源
{path:'/User/:id',component:User,props:{uname:'zhangsan',age:22}},
3 同时传递路由参数和静态资源
{path:'/User/:id',component:User,
props:(route)=>({ //这样写会直接返回一个对象给props
uname:'zhangsan',
age:22,
id:route.params.id
})
},
注:箭头函数的后面不用花括号,而是直接用小括号包裹一个对象会直接返回这个对象
vue-router命名路由
<router-link :to='{name:"user",params:{id:3}}'>User3</router-link>
{
path:'/user/:id',
name:"user",
component:User
},
编程式导航
页面导航的两种方式
- 声明式导航:
如<a>标签,<router-link>标签等 - 编程式导航:
通过调用JS的API实现导航的方式
例如:普通网页中的location.href
Vue中常用的编程式导航基本用法:
- this.$router.push('hash地址')
-
this.$router.go(n) //这是前进或后退的,n是数字,如果填1,就代表在历史记录中向前走一位
push的使用规则:
路由导航守卫
场景:我们希望必须已经登陆后才能访问home页面,可是默认情况下直接在浏览器url地址栏输入localhost:8080/home还是能进入home页面,显然这是不符合需求的。
因此需要添加路由导航守卫
目标:如果用户没有登陆,但是通过url访问特定页面,则直接重新导航到login页面去