vue-router其实是我们的路由,当项目很大的时候,需要用到路由跳转。
目录
3.4 this.$router.push和this.$router.replace的区别
1.创建路由
当项目处于运行状态时,先在项目终端按ctrl+c,输入Y,终止操作,如图所示。
接着输入路由安装命令: 其中 -D 的意思是 对应package.json,安装好之后,我们可以在package.json文件里看到vue-router及它的版本。
npm install vue-router -D
接着,在项目的Router/index.js中导入Vue、Router,通过Vue.use(Router)调用Router
/**第一步 router/index.js*/
import Vue from "vue"; //导入Vue
import Router from "vue-router"; //导入Router
Vue.use(Router); //调用Router
const routes = [
{path:'/',component:()=>import('../components/a.vue')},
{path:'/b',component:()=>import('../components/b.vue')},
{path:'/c',component:()=>import('../components/c.vue')}
]
const router = new Router({
routes
})
export default router //导出路由
/**第二步 在main.js中 导入router,并把router加入到new Vue里面:*/
import router from "./router";
new Vue({
el: "#app",
router,
components: { App },
template: "<App/>"
});
/**第三步 在app.vue跟节点中 写路由出口 <router-view />*/
<template>
<div id="app">
<!-- App.vue里面显示的是一级路由 -->
<router-view />
</div>
</template>
<script>
export default {
name: "App"
};
</script>
<style></style>
这样就创建好路由了,可以在浏览器中输入路由地址,查看对应的组件页面了。
2.路由的配置
针对一级路由时:
2-1:当路由匹配不上时,我们可以重定向路由。
2-2:路由匹配的模式,有两种,分别是hash(默认是这种,带#号)、history(不带#号的)。
/**在 router/index.js 中配置重定向*/
import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);
const routes = [
{path:'/', component:()=>import('../components/a.vue')},
{path:'/b', component:()=>import('../components/b.vue')},
{path:'/c', component:()=>import('../components/c.vue')},
{path:'*', redirect:'/'} // 2-1当路由不匹配时,重定向到 '/',即a组件页面
]
const router = new Router({
routes,
mode:"hash" //2-2路由匹配的模式。默认是哈希值,哈希值就是路由里面带有#号的。带有#号,就代表我们使用的路由的形式是像a链接一样的本地跳转的形式,相当于是一个锚点。我们还有一种是history,如下
/**
mode:"history" // 它是一种H5方式的一种路由,是不带#号的。在真实的项目中,用这种方式向服务器发送请求时,需要后端配合做一些处理,不然会报404之类的请求错误。
*/
})
export default router //导出路由
针对二级路由时:在一级路由下,添加children
/**在 router/index.js 中配置重定向*/
import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);
const routes = [
{path:'/', component:()=>import('../components/a.vue'),
children:[
path:'aa',component:()=>import('../components/aa.vue'),
//注意:1.要先建有aa.vue页面,再在这里配置 2.要在父级组件a中加入<router-view><router-view/>路由出口,才可以渲染aa组件页面,不然地址栏输入“xxxxxxxx/aa”是不会渲染的,空白了
]},
{path:'/b', component:()=>import('../components/b.vue')},
{path:'/c', component:()=>import('../components/c.vue')},
{path:'*', redirect:'/'}
]
const router = new Router({
routes,
mode:"hash"
})
export default router
a.vue:
<template>
<div>a组件 <router-view></router-view></div>
</template>
export default{
created(){
//console.log(this.$router,this.$route);
}
}
3.路由的跳转
3.1 router-link
router-link本质上是一个a标签,a标签有的属性,router-link也可以设置。可以通过tag把它改成其他标签,比如div或者span等等。
target="_blank"表示在新窗口中打开页面。加上replace属性,表示当前跳转是不会有历史记录的,即没有“返回”。
app.vue:
<template>
<div id="app">
<!--<router-link to="/" tag="div"> 跳转到a页面<router-link> -->
<!--<router-link to="/b" target="_blank"> 跳转到b页面<router-link> -->
<!-- <router-link to="/c"> 跳转到c页面<router-link> -->
<router-link to="/" replace> 跳转到a页面<router-link>
<router-link to="/b" replace> 跳转到b页面<router-link>
<router-link to="/c" replace> 跳转到c页面<router-link>
<router-view><router-view />
</div>
</template>
<script>
export default {
name: "App"
};
</script>
<style></style>
3.2 通过 name来跳转
从下面代码中可以看到,to可以接收字符型的(to="/"),也可以接收对象型的(:to="{name:'c'}")。
app.vue
<template>
<div id="app">
<router-link to="/" replace> 跳转到a页面<router-link>
<router-link to="/b" replace> 跳转到b页面<router-link>
<router-link to="/c" replace> 跳转到c页面<router-link>
<router-link :to="{name:'c'}" replace> 跳转到cc<router-link>
<router-view><router-view />
</div>
</template>
<script>
export default {
name: "App"
};
</script>
<style></style>
router/index.js
import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);
const routes = [
{path:'/', component:()=>import('../components/a.vue'),
children:[
path:'aa',component:()=>import('../components/aa.vue'),
]},
{path:'/b', component:()=>import('../components/b.vue')},
{path:'/c', component:()=>import('../components/c.vue'),name:'c'}, <!--这里的c对应上面 :to{name:'c'}-->
{path:'*', redirect:'/'}
]
const router = new Router({
routes,
mode:"hash"
})
export default router
3.3 通过button来跳转
app.vue:
<template>
<div id="app">
<router-link to="/" replace> 跳转到a页面<router-link>
<router-link to="/b" replace> 跳转到b页面<router-link>
<router-link to="/c" replace> 跳转到c页面<router-link>
<router-link :to="{name:'c'}" replace> 跳转到cc<router-link>
<button @click="push"> push </button>
<button @click="get"> 取参数 </button>
<router-view><router-view />
</div>
</template>
<script>
export default {
name: "App",
components:{},
methods:{
push(){
//this.router.push("/");//写法一
//this.router.push({path:"/"});//写法二
//this.router.push({name:"/"});//写法三
//this.router.push({name:"/"},replace:true);//写法四,把replace改成true,记录历史记录,可以返回
//this.router.push({path:"/"},query:{value:2});//写法五,携带参数跳转,参数会直接拼接在地址后面。传参
//this.router.push({name:"b"},params:{value:2}); //写法六,这要注意,path是和query配合使用的,而name是和params配合使用的,不能搞反了。另外,要把路由改成path:'/b/:value'才可以把值传过来。第三,这种方式,参数依然是会暴露在地址栏上。
//this.$rouer.replace("/");//写法七,这种写法和上边的push是一样的,只是
let routerData = this.$router.resolve({ //写法八,带参跳转,且在新页面打开。
name:'c',
params:{value:2},
});
window.open(routerData.href,'_blank')
},
get(){
console.log(this.$route.query)
}
},
data(){
return{}},
};
</script>
<style></style>
router/index.js :
给a路由加上name:'/';
把b路由改成{path:'/b/:value', component:()=>import('../components/b.vue'),name:'b'},
import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);
const routes = [
{path:'/', component:()=>import('../components/a.vue'),name:'/',
children:[
path:'aa',component:()=>import('../components/aa.vue'),
]},
{path:'/b/:value', component:()=>import('../components/b.vue'),name:'b'},
{path:'/c', component:()=>import('../components/c.vue'),name:'c'}, <!--这里的c对应上面 :to{name:'c'}-->
{path:'*', redirect:'/'}
]
const router = new Router({
routes,
mode:"hash"
})
export default router
3.4 this.$router.push和this.$router.replace的区别
this.$router.push:
(1)跳转到指定URL,向history栈添加一个新的纪录,点击后退会返回到上一个页面。
(2)声明式:< router-link :to = “…” >
(3)编程式:< router.push(…) > // 该方法的参数可以是一个字符串路径,也可以是一个描述地址的对象。
// 字符串
this.$router.push('/index')
// 对象
this.$router.push({path:'/index'})
// 带查询参数,变成/sysDataValue/getValue/?typeId=1/,query传参
this.$router.push({path:'/index', query:{typeId: '1'} })
// 命名的路由 params传参
this.$router.push({name:'index', params:{typeId: '1'} })
this.$router.replace:
(1)跳转到指定的URL,替换history栈中最后一个记录,点击后退会返回至上一个页面。(a-->b-->c 结果b被c替换 a-->c)
(2)设置replace属性(默认值:false)的话,当点击时,会调用router.replace(),而不是router.push(),导航后不会留下history记录。即使点击返回按钮也不会回到这个页面。加上replace: true时,它不会向 history 添加新纪录,而是跟它的方法名一样——替换当前的history记录。
// 声明式
<reouter-link :to="..." replace></router-link>
// 编程式:
router.replace(...)
// push方法也可以传replace
this.$router.push({path: '/index', replace: true})
3.5 路由守卫
路由守卫相当于路由拦截,进入某个页面是需要登录的,如果你没有登录,你就进不到这个页面。
3.5.1 全局守卫
main.js:
import router from "./router";
/**全局钩子函数:*/
/**1.跳转之前*/
//router.beforeEach(to,form,next)=>{
// if(to.path=='c'){
// alert('你要登录后才能看');
// }
// next()
//}
/** 2. 跳转之后*/
router.afterEach(to,form){
console.log(to,form);
alert('2')
}
new Vue({
el: "#app",
router,
components: { App },
template: "<App/>"
});
app.vue: (把replace去掉,不然)
<template>
<div id="app">
<router-link to="/"> 跳转到a<router-link> <br/>
<router-link to="/b"> 跳转到b<router-link> <br/>
<router-link to="/c"> 跳转到c<router-link> </br>
<router-link :to="{name:'c'}" replace> 跳转到cc<router-link>
<router-view><router-view />
</div>
</template>
<script>
export default {
name: "App",
components:{},
methods:{
},
data(){
return{}},
};
</script>
<style></style>
3.5.2 在组件中的路由守卫
c.vue:
<template>
<div> c组件</div>
</template>
<script>
export default{
/** 进入组件的时候*/
beforeRouteEnter:(to,form,next)=>{
console.log(to,form);
next((vm)=>{ //回调
console.log(vm);
});
},
/**组件重新被渲染的时候,比如传参发生一些变化的时候,才跳转*/
beforeRouteUpdate(to,form,next){
console.log(to,form,next);
next();
},
/**离开组件的时候*/
beforeRouteLeave(to,form,next){
if(confirm("你确定要离开吗?")){
next();
} else{
next(false);
}
},
</script>
3.5.3 在路由配置中守卫
router/index.js: (示例是在c这里进行守卫)
import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);
const routes = [
{path:'/', component:()=>import('../components/a.vue'),name:'/',
children:[
path:'aa',component:()=>import('../components/aa.vue'),
]},
{path:'/b/:value', component:()=>import('../components/b.vue'),name:'b'},
{path:'/c', component:()=>import('../components/c.vue'),name:'c'}, name:'c' beforeEnter:(to,form,next)=>{
alter("与全局守卫一样");
next();}}
{path:'*', redirect:'/'}
]
const router = new Router({
routes,
mode:"hash"
})
export default router