理解:
1.Vue-Router是Vue.js官方的路由插件,它和vue.js是深度集成的,适用于构建单页面应用。vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。传统的页面应用,是用一些超链接实现页面切换和跳转的。在vue-router中,则是路径之间的切换,也就是组件间的切换。路由模块的本质 就是建立起url和页面之间的映射关系。
因为Vue做的是单页应用,就相当于只有一个主的index.html页面==>a标签不起作用
2.route,routes,router
route:首先它是个单数,我们可以理解为单个或某个路由
routes:它是个复数,表示多个集合才能为复数,即我们可以理解为多个路由的集合,routes表示多个数组的集合。
router:这个是路由器,用于管理上面两个路由,路由器会去路由集合中找对应的路由
代码:
- <div id="app">
- //1.router-link 中用于进行导航 to用于指定链接
- //2.router-view 是路由出口 显示router-link中的url对应的组件
- <router-link to="/">go to Homerouter-link>
- <router-link to="/about">go to Aboutrouter-link>
- <router-view>router-view>
- div>
- //1.定义一些路由组件,也可以从其他文件中导入
- const Home={template:'Home'},
- const About={template:'About'}
-
- //2.定义一些路由 每个路由都需要映射到一个组件
- const routes=[
- {path:'/',component:Home},
- {path:'/about',component:About},
- ]
-
- //3.创建路由实例并传递'routes'配置
- const router=VueRouter.createRouter({
-
- //4.内部提供了history模式的实现
- history:VueRouter.createWebHasHistory(),
- routes,
- })
-
- //5.创建并挂载根实例
- const app = Vue.createApp({})
-
- //6.通过调用app.use(router)使得我们可以在任意组件中以this.$router形式访问它,并且以this.$routes的形式访问当前路由
- app.use(router)
-
- app.mount('#app')
1.带参数的动态路由匹配
需要将给定匹配模式的路由映射到同一个组件
比如说:有一个User组件,它应该对所有的用户进行渲染,但是用户Id不同 因此在VueRouter中,我们可以使用一个动态字段来实现 ==>路径参数
- const User = {
- template:'User',
- }
-
- const routes = [
- {path:'/users/:id',component:User},
- ]
动态字段以:开始,路径参数用:表示。当一个路由被匹配时,它的params的值将在每个组件中
this.$route.params的形式暴露出来 ==>可以通过更新User的模板来呈现当前用户的ID
- const User = {
- template:'User{{$route.params.id}}'
- }
2.响应路由参数的变化:
使用带有参数的路由时需要注意的是,当用户从/users/johnny导航到/users/jolyne时,相同的组件实例将被重复使用,因为两个路由都渲染同个组件,比起销毁再创建,复用更加高效。但是这意味这组件的生命周期钩子函数不会被调用。
- const User = {
- template:'...',
- created(){
- this.$watch(
- //要对同一个组件中的参数变化做出响应,可以简单的watch $route对象上的任意属性
- () =>this.$route.params,
- (toParams,previousParam)=>{
- //对路由变化做出响应
- }
- )
- }
- }
- <div id="app">
- <router-view>router-view>//这里的router-view是顶层
- div>
对应的路由组件
- const User = {
- template:'
-
-
User{{$route.param.id}}
-
//这里是app渲染的组件在渲染下一层组件 - '
-
- }
-
- const routes = [{path:'/user/:id',component:User}]
要想实现路由组件,要在路由中配置childeren:
- const routes = [
- {
- path:'/user/id',
- components:User,
- children:[
- {
- path:'profile',
- component:UserProfile,
- },
- {
- path:'posts',
- component:UserPosts,
- },
- ],
-
- },
- ]
注意:以/开头的嵌套路劲将被视为根路径 这允许你利用组件嵌套 而不必使用url
还有一些vue-router低级部分没有看 比如vue-router命名等 这个没必要看 看了也不记得 直接用就好
Vue 导航守卫_许你今世繁华的博客-CSDN博客_vue导航守卫
vue导航守卫_摩羯座**的博客-CSDN博客_vue导航守卫
VueRouter提供的导航守卫主要用于在导航的过程中重定向或取消路由,或添加权限验证,数据获取等业务逻辑===>监听每一个路由跳转的过程,然后提供一些钩子函数让你有机会在跳入过程中植入相关信息
导航守卫的分类(这三个守卫可以用于路由导航过程中的不同阶段):
每一个导航守卫都有三个参数:to、from和next。
1.全局前置守卫:
当一个导航触发时,全局前置守卫按照创建的顺序调用。守卫可以是异步解析执行,此时导航在所有守卫解析完之前一直处于挂起状态。全局前置守卫使用router.beforeEach()注册
特点:可以拦截页面跳转
执行时间:在页面跳转完成之前
参数:to表示即将前往页面对应的路由对象,系统自动注入 // from 表示即将离开页面的路由对象,系统自动注入
- const router = new VueRouter({....});
- router.beforeEach((to,from,next)=>{
- // 用户验证登录身份
- if (to.name != 'Login' && !isAuthenticated) next({ name: 'Login' })
- else next();
- })
2.全局解析守卫
全局解析守卫是vue-router2.5.0版本新增的,使用【router.beforeResolve】注册。它和【router.beforeEach】类似,区域在于,在导航被确认之前,在所有组件内守卫和异步路由组件被解析之后,解析守卫被调用。
特点:可以拦截页面跳转
执行时间:在页面跳转完成之前
参数:to 表示即将前往页面对应的路由对象,系统自动注入// from 表示即将离开页面的路由对象,系统自动注入 // next 路由跳转方法
- const router = new VueRouter({....});
- router.beforeResolve((to,from,next)=>{
- //这里执行具体操作
- //next 调用
- if(to.meta.verification){
- try {
- // 验证正确
- await askForPage()
- }catch(error) {
- // 验证错误,取消导航
- return false
- }
- }
- }
3.全局后置钩子
全局后置钩子使用【router.afterEach】注册,它在导航被确认之后调用。
参数:to 表示即将前往页面对应的路由对象,系统自动注入// from 表示即将离开页面的路由对象,系统自动注入
- const router = new VueRouter({....});
- router.afterEach((to,from)=>{
- //这里执行具体操作
- })
4.路由守卫
路由独享守卫是在routes配置的路由对象中直接定义的beforeEnter守卫。
路由独享守卫只在进入路由时触发,参数改变时不会触发,它们只有在从一个不同的路由导航时,才会被触发
- const router = new VueRouter({
- routes: [
- {
- path: '/foo',
- component: Foo,
- beforeEnter: (to, from, next) => {
- // ...
- }
- }
- ]
- })
5.组件内守卫
共有三个组件内守卫:beforeRouteEnter、beforeRouterUpdate和beforeRouteLeave。
注意:
beforeRouterEnter守卫不能访问this,因为在守卫是在导航确认前被调用,这时新进入的组件实例还没有被创建。
不过beforeRouteEnter有一个特权,就是它的next函数支持回调,而其他的守卫则不行。可以把组件实例作为回调方式的参数,在导航被确认后执行回调,而这个时候,组件实例已经创建完成。利用这个特性,可以将created钩子用beforeRoute守卫来替换
- //
- const book = {
- template:"...",
- beforeRouteEnter (to, from, next) {
- //在渲染该组件的路由被确认之前调用
- //不能通过this来访问组件实例,因为在守卫执行前,组件实例还没有被创建
- },
- beforeRouteUpdate (to, from, next) {
- //在渲染该组件的路由改变,但是该组件被复用时调用
- //例如,对于一个带有动态参数的路由 /foo/:id,在/foo/1和/foo/2之间跳转的时候
- //相同的foo组件实例将会被复用,而这个守卫就会在这种情况下被调用。
- //可以访问组件实例的this
- },
- beforeRouteLeave (to, from, next) {
- //导航即将离开该组件的路由时调用
- //可以访问组件实例的this
- }
- }
将任意信息附加到路由上,如过渡名称,谁可以访问路由等
- const routes = [
- ...
-
- meta:{
- //任何人都可以阅读文章
- requiresAuth:false
- }
- ]
进入某个路由后,需要从服务器获取数据,我们可以通过两种方式来实现:
导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示“加载中”之类的指示。
当你使用这种方式时,我们会马上导航和渲染组件,然后在组件的 created 钩子中获取数据。这让我们有机会在数据获取期间展示一个 loading 状态,还可以在不同视图间展示不同的 loading 状态。假设我们有一个 Post
组件,需要基于 $route.params.id
获取文章数据
- <template>
- <div class="post">
- <div v-if="loading" class="loading">Loading...div>
-
- <div v-if="error" class="error">{{ error }}div>
-
- <div v-if="post" class="content">
- <h2>{{ post.title }}h2>
- <p>{{ post.body }}p>
- div>
- div>
- template>
- export default {
- data() {
- return {
- loading: false,
- post: null,
- error: null,
- }
- },
- created() {
- // watch 路由的参数,以便再次获取数据
- this.$watch(
- () => this.$route.params,
- () => {
- this.fetchData()
- },
- // 组件创建完后获取数据,
- // 此时 data 已经被 observed 了
- { immediate: true }
- )
- },
- methods: {
- fetchData() {
- this.error = this.post = null
- this.loading = true
- // replace `getPost` with your data fetching util / API wrapper
- getPost(this.$route.params.id, (err, post) => {
- this.loading = false
- if (err) {
- this.error = err.toString()
- } else {
- this.post = post
- }
- })
- },
- },
- }
导航完成之前获取:导航完成前,在路由进入的守卫中获取数据,在数据获取成功后执行导航。
通过这种方式,我们在导航转入新的路由前获取数据。我们可以在接下来的组件的 beforeRouteEnter
守卫中获取数据,当数据获取成功后只调用 next
方法:
- export default {
- data() {
- return {
- post: null,
- error: null,
- }
- },
- beforeRouteEnter(to, from, next) {
- getPost(to.params.id, (err, post) => {
- next(vm => vm.setData(err, post))
- })
- },
- // 路由改变前,组件就已经渲染完了
- // 逻辑稍稍不同
- async beforeRouteUpdate(to, from) {
- this.post = null
- try {
- this.post = await getPost(to.params.id)
- } catch (error) {
- this.error = error.toString()
- }
- },
- }