vue路由总结

1.简单路由

import Home from '../views/Home.vue'
import admin from '../components/CourseList.vue'
import detail from '../components/detail.vue'
import login from '../views/login.vue'
Vue.use(VueRouter)
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    // 懒加载
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },
]
const router = new VueRouter({
  routes
})
懒加载:单独打包,按需加载。
懒加载的作用: vue这种单页面应用,如果我们不去做路由懒加载,打包之后的文件将会异常的大,就会造成进入首页时,需要加载的内容过多,时间过长,会出现长时间的白屏,不利于用户体验,运用懒加载就可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时。
 

2.动态路由匹配

 
把某种模式匹配到所有的路由,全都映射到同个组件,使用动态路径参数(dynamic segment)
例如:添加详情页detail.vue
<div>
   <h1>detail page</h1>
   <h4>{{$route.params.name}}</h4>
</div>
其中,使用$route.params.name来接受路由传来的参数
 
课程列表中CourseList.vue,点击跳转:
      <div
        v-for="c in courses"
        :key="c.name"
        :
        @click="onClick(c)"
      >
      <router-link :to='`/detail/${c.name}`'>
        {{ c.name }} - {{ c.price | currency('¥') }}
      </router-link>
      </div>
router-link中的跳转,添加传参
 
路由中,router.js添加参数
  {
    path: '/detail/:name',
    name: 'detail',
    component: () => import ('../components/detail.vue')
  }
这样,点击时可跳转到指定动态路由中,并传参
 

3.嵌套路由

 
指的是,在当前列表页面下,显示点击的详情页面,相当于,父路由点击后在父路由下显示子路由
 
路由中,router.js
 
  {
    path: '/admin',
    name:'admin',
    component: admin,
    children: [
      {
        path: 'detail/:name',
        name: 'detail',
        component: detail
      }
    ],
    // 需要去认证
    meta:{
      auth: true
    },

 

形成了父子关系,注意,此时子路由中的path,千万不能写成'/detail/:name'  第一个/不需要,否则无法跳转,且不报错
 
course-list.vue:
 <router-link :to='`/admin/detail/${c.name}`'>
  {{ c.name }} - {{ c.price | currency('¥') }}
 </router-link>
 
  <!-- 嵌套路由的出口 -->
 <router-view></router-view>
 

 

需要注意的是,为了利于组件的重复使用,在使用嵌套或者动态路由匹配时,来回切换动态路由,该子路由中只会 创建一次,不会销毁,导致以下created中只触发切换的第一次,以后再切换时不会触发,
解决方法:使用watch监听路由变化
detail.vue:
        // router来回切换时,只会调用第一次,以后切换不会再触发
        // 原因是:组件的复用,不会销毁该组件
        created(){
            console.log('发送一次请求')
        },
        // 处理办法watch监听
        watch: {
            $route: {
                immediate: true,
                handler (){
                    console.log('详情获取')
                }
            }
        }
 

4.编程导航

 
之前的跳转是通过<router-link :to="路由"/>来进行跳转,也可以通过点击后代码实现跳转
router.push({name: '路由名称',params: {参数}, query: {查询字符串}})
例如:
列表页中 course-list.vue
    <div class="course-list" v-else>
      <div
        v-for="c in courses"
        :key="c.name"
        :
        @click="onClick(c)"
      >
      {{ c.name }} - {{ c.price | currency('¥') }}
      </div>
    <router-view></router-view>
    </div>
 
    <script>
    onClick(c){
      this.selectedCourse = c;
      // 编程导航方式
      // this.$router.push(`/admin/detail/${c.name}`)
      // 命名路由方式
      this.$router.push({
        name: 'detail',
        params: {name: c.name}
      })
    }
    </script>
 

5.路由守卫

路由守卫分为三个: 全局路由守卫,单个路由守卫、组件级路由守卫
路由守卫作用: 主要用来通过跳转或取消的方式守卫导航。
例如:权限设置。
新建login.vue,进入主页时给与判断,是否登录,如果没登录,跳转至登录页,登录后再进入主页
 
login.vue
<template>
    <div>
        <button @click="login" v-if="!isLogin">登录</button>
        <button @click="logout" v-else>注销</button>
    </div>
</template>
<script>
    export default {
        methods: {
            login(){
                window.isLogin = true;
                // 跳转回跳转过来的那个页面
                console.log(this.$route)
                this.$router.push(this.$route.query.redirect)
            },
            logout(){
                window.isLogin = false;
                this.$router.push(this.$route.query.redirect)
            }
        },
        computed: {
            isLogin() {
                return window.isLogin
            }
        },
    }
</script>
<style lang="scss" scoped>
</style>
        以上this.$route的打印内容:

5.1全局守卫

     全局守卫包括:
            router.beforeEach(是全局前置守卫)、
            router.beforeResolve(是全局解析守卫)、
            router.afterEach(是全局后置钩子)
    每个导航守卫都接受3个参数 from 、to、next() ,参数的定义如下:
  • to:  Route: 即将要进入的目标 路由对象
  • from:  Route: 当前导航正要离开的路由
  • next:  Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
 router.js:    在路由中设置meta,守卫中获取其内的值,表示需要进行守卫
const routes = [
  {
    path: '/admin',
    name:'admin',
    component: admin,
    children: [
      {
        path: 'detail/:name',
        name: 'detail',
        component: detail
      }
    ],
    // 需要去认证
    meta:{
      auth: true
    },
  },
  {
    path: '/login',
    name: 'login',
    component: login,
  },
]
 
 
const router = new VueRouter({
  routes
})
// 全局守卫
router.beforeEach((to, from , next) =>{
  // 判断是否需要守卫
  // meta数据
  if (to.meta.auth) {
    // 是否登录
    if (window.isLogin) {
      next();
    } else {
      next('/login?redirect='+ to.fullPath)
    }
  } else {
    next()
  }
})

 

 

5.2单个路由守卫

    含有一个守卫 : beforeEnter(to, from , next)守卫,使用情况如下:
 const routes = [
  {
    path: '/admin',
    name:'admin',
    component: admin,
    children: [
      {
        path: 'detail/:name',
        name: 'detail',
        component: detail
      }
    ],
    // 局部守卫
    beforeEnter(to, from ,next){
      // 是否登录
      console.log(to)
      if (window.isLogin) {
        next();
      } else {
        next('/login?redirect='+ to.fullPath)
      }
    }
  },
  {
    path: '/login',
    name: 'login',
    component: login,
  }
]
const router = new VueRouter({
  routes
})
export default router
 以上的to的打印内容

 

 

5.3 组件内守卫

    直接在该组件中使用。
    三个组件内守卫:
  •         beforeRouteEnter(to, from ,next)  前置,进入路由前调用
  •         beforeRouteUpdate(to, from , next) 更新,组件复用,路由跳转,比如:对于一个带有动态参数的路径,/foo/:id,在/foo/1和/foo/2之间跳转时,由于会渲染同样的Foo组件,因此这个组件实例会被复用,这个钩子函数就在这时使用。
  •         beforeRouteLeave(to, from, next) 后置,离开路由前调用
    
    course-list.vue:
<script>
export default {
  data() {
    return {
      selectedCourse: "",
      courses: [
        { name: "javascript", price: 12324 },
        { name: "python", price: 8989 }
      ],
      course: ''
    };
  },
  filters: {
    currency(value, symbol = "¥") {
      return symbol + value;
    }
  },
  methods: {
    addCourse (){
      this.courses.push({name: this.course, price: 1432})
    },
    onClick(c){
      this.selectedCourse = c;
      // 编程导航
      // this.$router.push(`/admin/detail/${c.name}`)
      this.$router.push({
        name: 'detail',
        params: {name: c.name}
      })
    }
  },
  // 该组件内的路由守卫
  beforeRouteEnter(to,from, next) {
      if (window.isLogin) {
        // 此时data还未创建,无法使用this
        next(vm => {
            console.log(vm.courses)
        });
      } else {
        next('/login?redirect='+ to.fullPath)
      }
  }
};
</script>
注意:beforeRouteEnter()内,无法调用this,因为我们使用的是进入路由之前,那会组件还没创建,得不到this这个属性,所有我们只能使用过vm异步语句来让节点上树

6.动态路由

 
通过router.addRoutes(routes)方式动态添加路由
例如:上例中,不将路由admin放入router.js中,如果登录了的话,动态的添加该路由,可以不通过路由守卫完成。
删除router.js中的admin路由,改至在登录页动态添加。
login.vue:
 
<template>
    <div>
        <button @click="login" v-if="!isLogin">登录</button>
        <button @click="logout" v-else>注销</button>
    </div>
</template>

<script>
    export default {
        methods: {
            login(){
                window.isLogin = true;
                // console.log(this.$route,'123')
                // 动态添加路由
                this.$router.addRoutes([
                    {
                        path: '/admin',
                        name:'admin',
                        component: () => import('../components/CourseList.vue'),
                        children: [
                            {
                            path: 'detail/:name',
                            name: 'detail',
                            component: () => import('../components/detail.vue')
                            }
                        ]
                    }
                ])
                this.$router.push(this.$route.query.redirect)
            },
            logout(){
                window.isLogin = false;
                this.$router.push(this.$route.query.redirect)
            }
        },
        computed: {
            isLogin() {
                return window.isLogin
            }
        },
    }
</script>

7.路由缓存

    <keep-alive>
        <router-view></router-view>
    </keep-alive>

 

 keep-alive:保持缓存,切换时不会改变其状态,不会加载。
同时,如果想保持某一个组件状态,可以在该组件中设置name,并在keep-alive中设置include,
exclude与include相反,表示除了该组件外的其他组件保持keep-alive.
例如:保持admin状态
admin中:
export default {
  name: 'admin',
  data() {
    return {
      selectedCourse: "",
      courses: [
        { name: "javascript", price: 12324 },
        { name: "python", price: 8989 }
      ],
      course: ''
    };
  },

 

admin父组件中:
 
    <keep-alive include="admin">
        <router-view/>
    </keep-alive>
 

 

同时,keep-alive含有两个钩子函数
     actived 和 deactived,使用keep-alive包裹的组件在切换时不会被销毁,而是缓存到内存中并执行 deactived 钩子函数,命中缓存渲染后会执行 actived 钩子函数。
 
 
 
 
posted @ 2020-04-10 21:15  whale~alince  阅读(269)  评论(0编辑  收藏  举报