VueRouter学习日志

1.入门


理解:
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 Home</router-link>
  <router-link to="/about">go to About</router-link>
  <router-view></router-view>
 </div>

//1.定义一些路由组件,也可以从其他文件中导入
 const Home={template:'<div>Home</div>'},
 const About={template:'<div>About</div>'}

 //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')

2.动态路由匹配


 1.带参数的动态路由匹配
 需要将给定匹配模式的路由映射到同一个组件
 比如说:有一个User组件,它应该对所有的用户进行渲染,但是用户Id不同      因此在VueRouter中,我们可以使用一个动态字段来实现 ==>路径参数
 

 const User = {
      template:'<div>User</div>',
  }

  const routes = [
      {path:'/users/:id',component:User},
  ]

动态字段以:开始,路径参数用:表示。当一个路由被匹配时,它的params的值将在每个组件中

this.$route.params的形式暴露出来 ==>可以通过更新User的模板来呈现当前用户的ID 

const User = {
      template:'<div>User{{$route.params.id}}</div>'
  }

  2.响应路由参数的变化:
  使用带有参数的路由时需要注意的是,当用户从/users/johnny导航到/users/jolyne时,相同的组件实例将被重复使用,因为两个路由都渲染同个组件,比起销毁再创建,复用更加高效。但是这意味这组件的生命周期钩子函数不会被调用。

 const User = {
    template:'...',
    created(){
        this.$watch(
            //要对同一个组件中的参数变化做出响应,可以简单的watch $route对象上的任意属性
            () =>this.$route.params,
            (toParams,previousParam)=>{
                //对路由变化做出响应
            }
        )
    }
  }

 

3.嵌套路由:

 <div id="app">
      <router-view></router-view>//这里的router-view是顶层
  </div>


对应的路由组件 

 const User = {
      template:'
      <div>
          <h2>User{{$route.param.id}}</h2>
          <router-view></router-view>//这里是app渲染的组件在渲染下一层组件
      </div>'
      
  }

 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命名等  这个没必要看 看了也不记得 直接用就好 

4.导航守卫

Vue 导航守卫_许你今世繁华的博客-CSDN博客_vue导航守卫

vue导航守卫_摩羯座**的博客-CSDN博客_vue导航守卫

VueRouter提供的导航守卫主要用于在导航的过程中重定向或取消路由,或添加权限验证,数据获取等业务逻辑===>监听每一个路由跳转的过程,然后提供一些钩子函数让你有机会在跳入过程中植入相关信息

导航守卫的分类(这三个守卫可以用于路由导航过程中的不同阶段):

  1. 全局守卫(全局前置守卫,全局解析守卫,全局后置钩子)
  2. 路由守卫(路由独享守卫)
  3. 组件内守卫(加载,离开,更新)

每一个导航守卫都有三个参数:to、from和next。

  • to:表示即将进入的目标路由对象
  • from:当前导航正要离开的路由对象
  • next:函数,以下是next的常用方法
  • next(): 进行管道中的下一个钩子
  • next(false): 中断当前导航
  • next( ./xx ): 中断当前导航,并跳转至设置好的路径

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
    }
}

5.路由元信息

将任意信息附加到路由上,如过渡名称,谁可以访问路由等

const routes = [
    ...

    meta:{
        //任何人都可以阅读文章
        requiresAuth:false
   }
]

6.数据获取

进入某个路由后,需要从服务器获取数据,我们可以通过两种方式来实现:

  • 导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示“加载中”之类的指示。

       当你使用这种方式时,我们会马上导航和渲染组件,然后在组件的 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()
    }
  },
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值