1.动态路由参数匹配
如果是一级参数可以不加/ 如果是二级参数必须在前面加/
<!-- 这两个路由跳转的是相同页面 :id 就是二级传递的参数 -->
<!-- 这两个组件跳转 是复用同一个组件效率更高当时生命周期不会重新执行 -->
<router-link to="/router1/user">Router一级传参</router-link>
<router-link to="/router1/admin">Router一级传参</router-link>
<!-- 还可以传递多段参数 -->
<router-link to="/router2/admin/post/aaaaa">Router多级传参</router-link>
相应路由参数的写法
{
path: '/router1/:id',
name: 'router1',
component:router1
},{
path: '/router2/:params1/post/:params2',
name: 'router2',
component:router2,
redirect: { name: 'router3' }
}
/* 只有在组件复用的时候才可以监听路由 */
watch:{
$route(to,from){
console.log(to,from);
}
},
// 监听,当路由发生变化的时候执行
watch: {
$route: {
handler: function(val, oldVal){
console.log(val);
},
// 深度观察监听
deep: true
}
},
只有在复用组件来回切换的时候执行
watch: {
'$route':'getPath'
},
methods: {
getPath(){
console.log(this.$route.path);
}
}
Vue 为你提供了一种方式来声明“这两个元素是完全独立的——不要复用它们”。
只需添加一个具有唯一值的 key 属性即可 ==:key是用来阻止“复用”的
<router-view :key="key"></router-view>
路由切换的时候就执行改方法
computed: {
key() {
return this.$route.name !== undefined? this.$route.name +new Date():
this.$route +new Date()
}
}
<!-- 2.嵌套路由 -->
<router-link to="/router3/admin/child">Router嵌套路由</router-link>
{
path: '/router3/:params1',
name: 'router2',
component:router3,
redirect:'red',// /router3/admin这样当前就会直接显示 router3和red 的组件
children:[{
path:'child',//如果为空父级路径正确就会把子渲染到父中 否则只有/routr3/params/child 才会实现效果
在path里面加上斜杠是用于父级:to={path:child}直接跳转路由的不加斜杠父级会直接拼上子级用于其他地方跳转 :to="/router3"
component:router2
},{
path:'red',
component:red
}]
}
<!-- 3\编程式路由 -->
<el-button @click="sendHref">编程式路由</el-button>
sendHref(){
const userId='123'
//编程式路由
// 字符串
// this.$router.push('bc')
// 对象
// this.$router.push({ path: 'bc' })
// 命名的路由 params 提供path,params 会被忽略,
// this.$router.push({ name: 'bc', params: { userId: '123' }})
this.$router.push({ name: 'bc', params: {userId}})//在导航栏看不到但是传过去了
// this.$router.push({ path: 'bc', params: {userId}})//传过去空对象 params不生效
// 带查询参数,变成 /register?plan=private
// this.$router.push({ path: 'bc', query: { plan: 'private' }})
// this.$router.push({ path: `bc/${userId}`})//只有写在path 上才可以传过去
}
send(){
// 通过点击实现跳转页面n代表数字 正前进 负后退 router.go(-1) 相当于router.back( )
//跳转到上一次浏览的页面 this.$router.go(-1)
// this.$router.go(-1)
//指定跳转的地址 this.$router.replace('/menu')
// this.$router.replace('/Style')
//指定跳转的路由的名字下 this.$router.replace({name:'menu'})替换掉之前history的URL 无法返回
// this.$router.replace({name:'Style'})
//通过push进行跳转
this.$router.push('/Style')
//这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
}
<!-- 4、命名路由 -->
根据name名字进行跳转 params传递的参数无法在地址栏中看到
<router-link :to="{name:'menu',params:{'id':233}}">命名嵌套路由</router-link>
{
path: '/',
name: 'menu',
component:menu
},
<!-- 5、命名视图 -->
<router-link to="/bc/child">命名视图</router-link>
<!-- 路由匹配到的子组件将渲染在这里 通过给视图容器添加名字来实现同时将多个组件渲染-->
<router-view></router-view>
<router-view name="a"></router-view>
{
path: '/bc',
name: 'bc',
component:router3,
children:[{
path:'child',
components:{
default:router1,
"a":touter4
}
}]
}
1.别名
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
2.重定向
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }}
]
})
## 导航守卫的一些相应的方法
全局守卫
全局前置路由守卫
//全局守卫
// to 进入到那个路由 from 从哪个路由离开
next()继续执行函数next(false)中断当前路由 里面可以填一个对象{path:"/"}
// 或者说直接 跳转路径next("/denglu")
//beforeEach 全局的 私有的是beforeEnter
全局前置路由守卫在main.js 里面
const router=new VueRouter({
routes:routers,
mode:"history"
})
全局路由用作页面初始化的时候的判断
全局前置路由守卫用来做商城网站没有登录的时候无法看其他页面
判断to.path当前将要进入的路径是否为登录或注册,如果是就执行next(),展示当前界面。
如果不是,就弹出alert,然后移至登录界面。
router.beforeEach((to,from,next)=>{
//判断是否是登陆和注册 页面
if(to.path=="/denglu"||to.path=="/zhuce"){
next()
}else{
console.log("还没有登录请先登录")
next("/denglu")
}
//我在这里模仿了一个获取用户信息的方法
let isLogin = window.sessionStorage.getItem('userInfo');
if (isLogin) {
//如果用户信息存在则往下执行。
next()
} else {
//如果用户token不存在则跳转到login页面
if (to.path === '/login') {
next()
} else {
next('/login')
}
}
})
next(false) 阻止跳转 中断导航
next("/login") 进入指定的组件的钩子函数
全局后置钩子
只有两个参数,to:进入到哪个路由去,from:从哪个路由离。
如下,每次切换路由时,都会弹出alert,点击确定后,展示当前页面。满足条件之后展示当前页面
判断store.gettes.isLogin === false 是否登录
router.afterEach((to,from)=>{
alert("after each");
})
组件内的守卫链接
// 在组件内访问不到这个name 和生命周期有关
data(){
return {
name:"sunhaojie"
}
},
//组件内守卫
进入组件的守卫
当前name 还没有渲染出来
beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,
因此即将登场的新组件还没被创建。
//可以通过next()回调函数获得组件实例
//进入组件之前
beforeRouteEnter:(to,from,next)=>{
alert("hello......."+this.name)
//next 异步执行
next(vm =>{
alert("hello......."+vm.name)
})
}
路由更新
beforeRouteUpdate (2.2 新增)
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
console.log('update方法触发', this.msg);
next();
},
// 离开组件之前的守卫
点击其他组件时,判断是否确认离开。确认执行next();取消执行next(false),留在当前页面
// beforeRouteLeave(to,from,next){
// // console.log(confirm("确认离开吗")) true==确认 false==取消
// if(confirm("确认离开吗")==true){
// next()
// }else{
// next(false)
// }
// }
路由独享的守卫
1. beforeEnter:(to,from,next)=>{},用法与全局守卫一致。只是,
将其写进其中一个路由对象中,只在这个路由下起作用。
{path:"/second",name:"secondLink",components:
{default:second,
"history":kuaidi,
"caidan":diancan,
"lianxi":lianxi
},
beforeEnter:(to,from,next)=>{
// 路由独享守卫
alert("非登录状态,不能访问此页面");
// next()
},
},
路由组件的引入方式(实现按需加载,不会 一下全加载上)
第一种在router.js里面
import home from './components/导航/home'
第二种
var aaa = () => import(/* webpackChunkName: "group-foo" */ './components/导航/about/contect/phonename')
这样做的结果就是webpack在npm run build的时候会打包成一个整个的js文件,如果页面一多,
会导致这个文件非常大,加载缓慢,为了解决这个问题,需要将他分成多个小文件,
而且还要实现异步按需加载,即用到了再加载,而不用一股脑全部加载
1.webpack提供的require.ensure(),这样可以实现按需加载,
并且你可以将多个相同类的组件打包成一个文件,只要给他们指定相同的chunkName即可,
如示例中的demo将会打包成一个文件。
第三种:
按需加载需要的时候加载打包到相同js
{
path: '/promisedemo',
name: 'PromiseDemo',
component: r => require.ensure([], () => r(require('../components/PromiseDemo')), 'demo')
},
{
path: '/hello',
name: 'Hello',
// component: Hello
component: r => require.ensure([], () => r(require('../components/Hello')), 'demo')
}
第四种:
{//按需加载 一个组件会打包成一个js文件
path: '/axjz3',
name: 'axjz3',
component: resolve => require(['./components/导航/about/lishi'], resolve)
},
第五种:
{
path: '/import',
name: 'import',
component:()=>import(/* webpackChunkName: "group-foo" */ './components/导航/about/contect/phonename')
},
路由元信息链接