文章目录
vue路由基本使用
1.在new路由对象的时候,可以为构造函数,传递一个配置对象。
//创建一个路由对象,当导入 vue-router 包之后,在window 全局对象中,就有了一个路由的构造函数。叫做VueRouter.
1.1.route这个配置对象中的routes表示路由匹配规则的意思,不能修改且必传
//每个路由规则,都是一个对象,这个规则对象,有两个必须属性。
//属性一:path,表示监听哪个路由链接地址。
//属性二:component,表示如果路由是前面匹配得来的path,则展示component属性对应的那个组件
const routerObj = new VueRouter({
routes:[
{path:'/login',component:login},
{path:'/register',component:register}
]
});
1.2vue实例中导入router键
const vm = new Vue({
el:"#app",
router:routerObj
})
2.定义路由组件
<script>
let login = {
template:"<h1>登陆组件</h1>"
}
let register = {
template:"<h1>注册组件</h1>"
}
</script>
3.页面中导入路由,vue-router专门提供用来占位符的,将来路由规则匹配到的组件就会展示到这个router-vue中。。。所以可以将router-view看作占位符
<div id="app">
<router-view></router-view>
3.1 a标签跳转,不推荐使用
<a href="#/login">登录</a>
<a href="#/register">注册</a>
3.2vue提供了标签
①to="/path" ②tag="标签名" 渲染为其他标签
③router-link-active 这个类名用于tab切换,需要在style中使用
<router-link to="/login" tag="span">登录</router-link>
<router-link to="/register">注册</router-link>
</div>
4.可以使用过渡与动画
<transition mode="out-in">
<router-view></router-view>
</transition>
5.页面初始化显示--重定向 redirect:"路径" ,在routes下
routes:[
{path:'/',redirect:"/login"},
]
6.// 自定义选中类名,默认是router-link-active 与routes同级
linkActiveClass:"active"
路由query传参
1.直接在router-link标签中的地址后传入 格式: ?键=值 routes中path路径无需修改
<router-link to="/login?id=10">登录</router-link>
对象形式传参:
<router-link :to="{path:'/home',query:{id:1,name:'张三'}}">home</router-link>
2.在组件中created钩子函数中使用this. r o u t e 获 取 , 获 得 一 个 对 象 , 常 利 用 其 中 的 q u e r y 属 性 t h i s . route获取,获得一个对象,常利用其中的query属性 this. route获取,获得一个对象,常利用其中的query属性this.route.query。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r9fU50aA-1605878737233)(C:\Users\A\AppData\Roaming\Typora\typora-user-images\1605787691329.png)]
3.使用:直接在当前组件中的中
<p>用户id:{{this.$route.query.id}}</p>
(this.可以省略){{$route.query.id}}
路由params传参 (常用⭐)
1.组件中routes中路径加 /:键
{path:'/home/:id',component:home},
{path:'/home/:id/:name',component:home},
设置name属性
{path:'/news',component:news,name:'news'},
2.router-link中传入数据 方法: /值
<router-link to="/home/10">home</router-link>
<router-link to="/home/10/张三">home</router-link>
对象形式,使用name属性获取
<router-link :to="{name:'news',params:{id:1}}">news</router-link>
3.解析传入的参数
在组件中created钩子函数中使用this.$route获取,获得一个对象,常利用其中的params属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zgNg4Xec-1605878737239)(C:\Users\A\AppData\Roaming\Typora\typora-user-images\1605788732056.png)]
4.使用:直接在当前组件中的中
<p>用户id:{{this.$route.params.id}}</p>
<p>用户名:{{$route.params.name}}</p>
(this.可以省略)常用:{{$route.params.id}}
5.动态路由 监听 路由 参数(动态路由 传的动态的值)的 变化
watch:{
"$route"(to, from){ // to去哪 from 从哪来
console.log('变化了')
console.log(to,from)
}
}
解决404路由
{
path:"*", // *匹配任意路由 尽量将404页面 路由规则放到最后
component: NoutFound
}
⭐children路由嵌套
1.创建父组件,路由
<div id="app">
<router-link to="/account">Account</router-link>
<router-view></router-view>
</div>
<template id='tmp1'>
<div>
<h4>这是account组件</h4>
</div>
</template>
const account = {
template:"#tmp1"
}
const router = new VueRouter({
routes:[
{
path:'/account',
component:account,
}
]
})
const vm=new Vue({
el:"#app",
router
})
2.创建子组件路由(略)
3.将子组件导入父组件,需要写在父组件的template中,
//直接导入,地址需要加上父组件的前缀
<router-link to="">""<router-link>
//同时需要占位
<router-view></router-view>
<template id='tmp1'>
<div>
<h4>这是account组件</h4>
<router-link to="/account/login">登录</router-link>
<router-link to="/account/register">注册</router-link>
<router-view></router-view>
</div>
</template>
4.父组件的路由中导入子组件路由
除了path和component还需要导入children属性,数组,可以导入多个
children:[
//里面传的是对象,路径中注意不要传"/",会自动加入根路径
{path:'login',component:login},
{path:'register',component:register}
]
const router = new VueRouter({
routes:[
{
path:'/account',
component:account,
children:[
{path:'login',component:login},
{path:'register',component:register}
]
}
]
})
5.父组件-子组件-子组件的儿子
1.子组件中
加入:
<router-link to="/account/login/register">注册</router-link>
<router-view></router-view>
2.父组件中:同样不要再加"/"
children:[
{path:'login',
component:login,
children:[{path:'register',component:register}]
]
命名路由
给,每个路由规则新增name属性,相当于给每个路由起个名字
routes = [
{
path:'/home',
name:'首页', //给这个路由新增name属性
component:xxx
}
]
命名视图 一个实例导入显示多个路由
路由1 路由2
routes = [
{
path:'/home',
name:'首页', //给这个路由新增name属性
components:{
a:路由1,
b:路由2,
}
}
]
别名
“重定向”的意思是,当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b,那么“别名”又是什么呢?
/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。
上面对应的路由配置为:
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
编程式导航
声明式导航 利用组件 跳转路由(router-link)
编程式导航 js内部通过 方法 来控制路由跳转 俗话:使用button @click方法进行跳转
当 引入 vue-router后 构造函数中还灌入一个 对象 $router
$router 其实就是 路由对象实例 new VueRouter()
<button @click='goLogin'>登录</button>
如果是childen路由嵌套,方法要加在父组件中,而非实例之中。
methods:{
goLogin(){
// this.$router.replace('/account/login')
this.$router.push('/account/login')
}
}
this.$router.push() // 跳转路由的 参数同 router-link的to属性 栈
// 跳转路由 并往历史记录 中 添加一条新的记录
this.$router.replace() // 跳转路由 参数同router-link 的to 属性
// 跳转路由,不添加新记录 而是 覆盖当前的记录
this.$router.go(n)
0 //刷新
-1 //回退一步
1 // 前进一步
n // 前进n步
所有方法中都可以传入参数:
this.$router.push({
path:'',
query:{}
})
this.$router.replace({
name:'',
params:{}
})
路由模式
1,hash模式
原理:利用 浏览器的url 的hash值得变化(url加hash值 #/home)
利用 window.onhashchange 当地址栏的hash值改变时触发
优势:
地址栏的 路径指向不会改变
缺点:丑
2,history模式
#/home #/news 变成 xxx/home xxx/news
原理:h5新增的api history pushState方法和 replaceState()方法
优点:好看 没有讨厌的#
缺点:/写在最前面 代表根路径,
导航守卫 、 导航钩子函数
监听,拦截路由变化
- 全局守卫 (拦截所有的路由)
// 全局前置 守卫
组件实例.beforeEach((to,from,next)=>{
// to 目标路由
// from 从哪来路由
// next 拦截器 不调用next()路由无法进入,next参数同router-link to属性的值,重定向地址
next()
})
- 路由独享的 (定义在路由规则中,只拦截这个路由)
- 组件内部
注意:
1.要注意,注册登录直接放行
if(to.fullPath==='/login' || to.fullPath==='/login/register') {
next()
}
2.其他页需要登陆鉴权时时
else{
const token = localStorage.getItem('access-token')
if (token) {
next()
}else{
next({
path:'/login',
query:{from:to.fullPath}
})
next({
name:'login',
params:{from:to.fullPath}
})
//使用query要小心,最开始的判定就要改一下判定
if(to.fullPath.slice(0,6)==='/login' || to.fullPath==='/login/register') {
next()
}
}
}
3.登录成功后跳转页面判断:若由上一级,跳转至上一级,若无,跳转到首页。
在点击函数中设置
goLogin(){
localStorage.setItem("access-token",'爱情36计')
//判定是否有上一级目录
if(this.$route.params.from){
//从哪里重定向来,就到那里去,从上一级的params中或者query中获取
this.$router.push(this.$route.params.from)
}else{
//没有跳转到首页
this.$router.push("/")
}
//query写法
if(this.$route.query.from){
//从哪里重定向来,就到那里去
this.$router.push(this.$route.query.from)
}else{
this.$router.push("/login/register")
}
}
路由元信息
定义路由的时候可以配置 meta
字段:
const router = new VueRouter({
routes: [
{
path: 'path',
component: ,
// meta中属性名是自定义的
meta: { needLogin: true }
}
]
})
//在导航全局守卫中进行判定
router.beforeEach((to,from,next)=>{
if (to.fullPath.slice(0,6)==='/login' || to.fullPath==='/login/register' || to.fullPath==='/'){
next()
}else{
//判定属性是否为真
if (to.meta.needLogin) {
const token = localStorage.getItem('access-token');
if(token){
next();
}else{
next({
path:'/login',
query:{from:to.fullPath}
})
}else{
next()
}
}
//登陆成功后同上一节的第三步