Vue路由

Vue路由

路由就是一组KV的对应关系,多个路由需要经过路由器的管理,然后路由的主要目的就是用来写单页面应用

Uncaught TypeError: (0 , vue__WEBPACK_IMPORTED_MODULE_0__.defineComponent) is not a function

如果遇到这个报错,多半是Vue的版本和Vue-Router的版本不一致导致的,选择正确版本即可

我们就写一个单页面,需要一个文件夹专门用来存放路由

在src/router/index.js下

import VueRouter from 'vue-router'
//这里的两个组件是我自己写的组件
import About from '../components/about'
import Home from '../components/home'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home
        }
    ]
})

然后我们在需要点击进行切换的a标签换成<router-link></router-link>标签,如果标签里面有需要那种选中后的样式那么我们可以使用active-class然后加上类即可,最后在需要展示路由页面内容的地方写上<router-view></router-view>即可显示内容

<router-link class="list-group-item" active-class="active" to="/about">About</router-link>
<router-link class="list-group-item" active-class="active" to="/home">Home</router-link>

然后组件之间的切换,首先会销毁当前组件,然后挂在新的组件

只要是使用了router的组件身上都会多两个东西$route$router,route每个组件都有一个,router只有一个,也就是共用一个

嵌套路由

套娃

import VueRouter from 'vue-router'
import About from '../pages/about'
import Home from '../pages/home'
import News from '../pages/News'
import Message from '../pages/Message'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
          	//对于组件的子组件,需要children这个配置项
            children: [ 
                {
                  	//这里不需要反斜杠 写了就G
                    path: 'news', 
                    component: News
                },
                {
                    path: 'message',
                    component: Message
                }
            ]
        }
    ]
})

然后在跳转的标签上

<router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
<!-- 这里的to一定要带上父组件的路径 -->

路由的query参数

$route属性里面有一个query,这个东西就是我们传参的关键

<router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link>

上面的代码解决了很多问题,比如传递参数的时候如果要使用插值语法该怎么办,当我们是有上面的语法后就可以使用$route.query.id这样去在其他路由里面拿参数

当然这样写可读性比较差,而且比较乱,Vue也提供了另外一种方式

<router-link :to="{
  path: '/home/message/detail',
  query: {
  id: m.id,
  	title: m.title
  }
}">{{m.title}}</router-link>

命名路由

上面我们会发现这个path有点长,我们就可以使用命名路由来解决这个问题

routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [
                {
                    path: 'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            name: 'check', //这里加了个name属性
                            path: 'detail',
                            component: Detail
                        }
                    ]
                }
            ]
        }
    ]
<router-link :to="{
  name: 'check',
  query: {
  id: m.id,
  	title: m.title
  }
}">{{m.title}}</router-link>

于是乎,我们就可以写成这样

路由的params参数

routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [
                {
                    path: 'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            name: 'check', 
                            path: 'detail/:id/:title', //这里添加了两个站位
                            component: Detail
                        }
                    ]
                }
            ]
        }
    ]
<router-link :to="{
  //这里必须使用name配置
  name: 'check',
  //这里把query改成params
  params: {
  	id: m.id,
  	title: m.title
  }
}">{{m.title}}</router-link>

然后就可以使用$route.params.id这样去在其他路由里面拿参数

注意:路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置!

路由的prop配置

​ 作用:让路由组件更方便的收到参数

{
	name:'xiangqing',
	path:'detail/:id',
	component:Detail,

	//第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
	// props:{a:900}

	//第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传给Detail组件
	// props:true
	
	//第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
	props(route){
		return {
			id:route.query.id,
			title:route.query.title
		}
	}
}

Router-link的replace属性

作用:控制路由跳转时操作浏览器历史记录的模式

说白了就是点完了之后能不能前进或者后退,然后有两个模式,一个是push,一个是replace,push是追加历史记录,replace是替换当前记录。路由跳转时候默认为push

Router-link标签加一个replace属性就开启了

编程式路由导航

作用:不借助<router-link> 实现路由跳转,让路由跳转更加灵活

具体编码(在methods里面:

//$router的两个API
this.$router.push({
	name:'xiangqing',
		params:{
			id:xxx,
			title:xxx
		}
})

this.$router.replace({
	name:'xiangqing',
		params:{
			id:xxx,
			title:xxx
		}
})
this.$router.forward() //前进
this.$router.back() //后退
this.$router.go() //可前进也可后退 参数为前进几层

缓存路由组件

作用:让不展示的路由组件保持挂载,不被销毁。

具体编码,不带include的话这个标签下所有的路由都不会被销毁,带上就只会保留对应的组件:

<keep-alive include="News"> 
    <router-view></router-view>
</keep-alive>

<!-- 多个写法 -->
<keep-alive :include="['News', 'Message']"> 
    <router-view></router-view>
</keep-alive>

和路由组件相关的生命周期钩子

  1. 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。
  2. 具体名字:
    1. activated路由组件被激活时触发。
    2. deactivated路由组件失活时触发。

路由守卫

  1. 作用:对路由进行权限控制

  2. 分类:全局守卫、独享守卫、组件内守卫

  3. 全局守卫:

    //全局前置守卫:初始化时执行、每次路由切换前执行
    router.beforeEach((to,from,next)=>{
    	console.log('beforeEach',to,from)
    	if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
    		if(localStorage.getItem('school') === 'scitc'){ //权限控制的具体规则
    			next() //放行
    		}else{
    			alert('暂无权限查看')
    			// next({name:'scitc'})
    		}
    	}else{
    		next() //放行
    	}
    })
    
    //全局后置守卫:初始化时执行、每次路由切换后执行
    router.afterEach((to,from)=>{
    	console.log('afterEach',to,from)
    	if(to.meta.title){ 
    		document.title = to.meta.title //修改网页的title
    	}else{
    		document.title = 'vue_test'
    	}
    })
    
  4. 独享守卫:

    注意啊,这个守卫没有后置的,只有前置的

    beforeEnter(to,from,next){
    	console.log('beforeEnter',to,from)
    	if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
    		if(localStorage.getItem('school') === 'scitc'){
    			next()
    		}else{
    			alert('暂无权限查看')
    			// next({name:'scitc'})
    		}
    	}else{
    		next()
    	}
    }
    
  5. 组件内守卫:

    这个是写在组件里面的

    //进入守卫:通过路由规则,进入该组件时被调用
    beforeRouteEnter (to, from, next) {
    },
    //离开守卫:通过路由规则,离开该组件时被调用
    beforeRouteLeave (to, from, next) {
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值