vue-router

在安装完依赖之后

全局路由守卫:

  • beforeEach –
  • beforeResolve –
  • afterEach –

局部路由守卫

  • beforeDestroy – 销毁前
  • beforeRouteEnter – 路由进入前(不可使用this,但可以使用vm)
  • beforeRouteUpdate – url更新前(本页面跳转本页面( EG:跳转不同商品,路由不变,改变id时), 要将生命周期函数内的数据控制,写到此 路由钩子内,因为生命周期此时不会再执行一次,一切生命周期内的方法不会再次执行)
  • beforeRouteLeave – 路由离开(监听到用户含有未提交的表单时候,可以在这里做个弹窗,提示用户是否要离开,具体的数据可以使用next(()=>{ // if(this.username){ //do somthing}})) ,以提高用户体验

router - index.js路由守卫是出现在 生命周期函数之前的

全局守卫 写在index.js中 ; 局部守卫 写在具体的component 中

❤ 全局守卫(router 下 的 index.js)

import Vue from 'vue'
import VueRouter from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import ElementDate from '@/components/elementDate'
import notFound from '@/components/notFound'
Vue.use(VueRouter)
const routes = [
    {
        path:'/',
        component:()=>import('@/components/HelloWorld'),
        meta:{title:"HelloWorld Title"}
    },
    {
        // path:'/a/:id',
        path:'/a',
        props:true,
        //  component:()=>import('XXXX') 的 好处是 减少首屏所需要花费的时间,提升速度 (类似按需加载)
        component:()=>import('@/components/HelloWorld'),
        name:"AAAAA",
        meta:{title:"HelloWorld Title"}
    },
    {
        // path:'/b/:id',  斜杠后的值会被传给组件,在跳转的时候也要写为 to="/b/123" 
        path:'/b',
        // props:true, // 表示冒号后面的 变量会被以 props 的形式,直接传递给页面   components 页直接 使用props 接受即可
        name:"i'm b",
        // component:{
        //     default:ElementDate,
        //     conA:HelloWorld
        // },
        component: ElementDate ,
        meta:{
            title:"ElementDate Title",
            description:"my description"
        },
        children:[{
            path:'/childrenPath',
            component:HelloWorld
        }]
    }
    // ,{
    //     path:'/*',
    //     component:notFound,
    //     meta:{title:"notFound Title"}
    // }
]

const router  = new VueRouter({
    routes,
    mode:'history', // 具体使用的模式
    base:'/hubinbing/', // 为url 添加protocal
    fallback:true // 若不支持history 则回到hash模式
})


console.log('router ',router)
// 路由全局守卫
router.beforeEach((to,from,next)=>{
    console.log('全局路由守卫--beforeEach',to,from)
    // 使用 routes 的 item中的 数据 统一改变 切换components 的每个 title
    if(to.meta.title)
        document.title = to.meta.title
    else
        document.title = "ch6-2"
    next()
})
router.beforeResolve((to,from,next)=>{
    console.log('全局路由守卫--beforeResolve',to,from)
    next()
})
router.afterEach((to,from)=>{
    // let bodySrcollTop = document.body.scrollTop
    // console.log("bodySrcollTop   ===>",bodySrcollTop)
    console.log('全局路由守卫--afterEach',to,from)
    // if (bodySrcollTop !== 0) {
    //     document.body.scrollTop = '210px'
    //     return
    // }
    // let docSrcollTop = document.documentElement.scrollTop
    // if (docSrcollTop !== 0) {
    //     document.documentElement.scrollTop = 0
    // }
})
export default router;

❤ 局部守卫

export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  beforeCreate () {
    console.log("beforeCreate")
  },
  created () {
    console.log("created")
  },
  beforeMount () {
    console.log("beforeMount")
  },
  mounted () {
    console.log("mounted")
  },
  beforeRouteEnter (to, from, next) {
  // 接着 全局守卫 - beforeEach 执行
    console.log('局部路由守卫--beforeRouteEnter --- 无法使用this,但可以用vm', to, from)
    next()
  },
  beforeRouteUpdate (to, from, next) {
  // 当 url 的path的params发生变化的时候执行此方法(参数更新value=2 --> value = 1)
    console.log('局部路由守卫--beforeRouteUpdate -- 可以用this', to, from)
    next()
  },
  beforeRouteLeave (to, from, next) {
  //当 url 的 path 变更的时候(页面跳转)
    console.log('局部路由守卫--beforeRouteLeave 可以用this', to, from)
    next()
  }
}

beforeDestroy 是在切换到下个页面的时候 , 上个页面的beforeDestroy 方法开始执行

  • 1.所有的前置守卫和beforeRouteEnter无法使用 “this”,因为在生命周期开始之前他们就调用了,此时的this并没有被挂载到具体的dom上
//如果要使用this 可以在守卫中写上 

 // router-index.js -----
  {
        path:'/a/:id', // :id 为传递给组件的query
        props:true,
        component:HelloWorld,
        name:"AAAAA",
        meta:{title:"HelloWorld Title"}
    },
 // -----
 // url: http://localhost:8080/hubinbing/a/678
 data(){return{numBers:159}},
 beforeRouteEnter (to, from, next) {
    console.log('局部路由守卫--beforeRouteEnter', to, from)
    next(vm => console.log("query 传递的值是 : ", vm.id, "本页面data的值 numBers :", vm.numBers))
  },
  • 2.如果需要在此时使用store中的数据, 可以在index.js 中引入 store ,
         import store from ‘@/store’
         router.beforeEach((to, form, next) => {
             console.log(store.getters)
          })

addRoute 用于向route中添加 路由项

  • 有一个问题:在最初的时候,我们会配置一个404的not found 路由,而addRoute而来的路由,是继续push的所以在not found 后面,因此会先被not found 匹配掉. 这种情况 该如何解决?
<div @click="addRoute"> addRoute </div>

import comC from '@/components/componetC'
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  methods: {
    addRoute () {
      this.$router.addRoutes([
        {
          path: '/c', component: comC, meta: { title: "ComponenetC Title" }
        }])
    }
  },
总体 demo 代码

app.js 代码

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
Vue.use(ElementUI);
new Vue({
  render: h => h(App),
  router
}).$mount('#app')

app.vue 代码


<template>
  <div id="app">
    <transition name="fade">
      <router-view></router-view>
      <!-- <router-view name="conA"> 只是一种小技巧 ,但是没实现 </router-view> -->
    </transition>
    <router-link to="/a">helloWorld</router-link>

    <router-link to="/b">element</router-link>
  </div>
</template>

<script>
export default {
  name: 'App',
  data () {
    return {

    }
  },
  components: {
  }
}
</script>

<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s;
}
.fade-enter,
.fade-leave-to {
  opacity: 0;
}
</style>

HelloWorld.vue 代码

<template>
  <div class="containerCLs">
    <h1>{{ msg }}</h1>
    HelloWorld
    <button @click="addRoute"> add routes</button>
    <br>
    <router-link to="/b">to B</router-link>
    <!-- <router-link :to="{path:'/b'}">to B</router-link> -->
  </div>
</template>

<script>
import comC from '@/components/componetC'
export default {
  name: 'HelloWorld',
  props: {
    msg: String,
    id: {
      default: "i'm default"
    }
  },
  data () {
    return {
      numBers: 159
    }
  },
  methods: {
    addRoute () {
      console.log(this.$router);
      this.$router.addRoutes([
        {
          path: '/c', component: comC, meta: { title: "ComponenetC Title" }
        }])
    }
  },
  beforeCreate () {
    console.log("beforeCreate")
  },
  created () {
    console.log("created")
  },
  beforeMount () {
    console.log("beforeMount")
  },
  mounted () {
    console.log("mounted")
  },
  beforeDestroy (to, from) {
    console.log('局部路由守卫--beforeDestroy  in A', to, from)
  },
  beforeRouteEnter (to, from, next) {
    console.log('局部路由守卫--beforeRouteEnter', to, from)
    next(vm => console.log("query 传递的值是 : ", vm.id, "本页面data的值 numBers :", vm.numBers))
  },
  beforeRouteUpdate (to, from, next) {
    console.log('局部路由守卫--beforeRouteUpdate', to, from)
    //  重点::! 当我们使用同一个路由 ,只是改变了后面的query,那么页面是不会重新走生命周期的
    //  这也意味着,一切在mounted 等生命周期钩子内的函数, 都不会再次执行,页面内的数据也不会再次刷新
    //  此情况应该将 周期钩子内的动作 ,放置到局部路由导航中去执行!! 
    next()
  },
  beforeRouteLeave (to, from, next) {
    console.log('局部路由守卫--beforeRouteLeave', to, from)
    console.log('为系统拥有更好的体验,在beforeLeave 钩子这,监听到用户有修改过的表单数据时,弹出弹窗,来让用户确认是否离开 使用v-m', to, from)
    // alert("离开?")
    next(()=>{if(this.userName){// dosonmething}})
    // next()
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.containerCLs {
  width: 10000px;
}
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

elementDate.vue 代码

<template>
  <div class="containerCLs">
    <!-- <br> <br> <br> <br> <br>
    <br> <br> <br> <br> <br>
    <br> <br> <br> <br> <br>
    <br> <br> <br> <br> <br>
    <br> <br> <br> <br> <br>
    <br> <br> <br> <br> -->
    <button>
      使用path 跳转
      <router-link :to="{path:'/a'}">:to="{path:'/a'}"</router-link>
    </button>
    <br>
    <hr>
    <div>使用name 跳转 此处的name 和 path一点关系也没有 ,可以重名 ,但最好不要,以免混淆</div>
    <router-link :to="{name:'AAAAA'}">:to="{name:'AAAAA'}"</router-link>
    <hr>
    <br>
    直接跳转(是否算path?)
    <router-link to="/a">to="/a"</router-link>
    <hr>

  </div>
</template>
<script>
export default {
  name: 'App',
  beforeCreate () {
    console.log("beforeCreate")
  },
  created () {
    console.log("created")
  },
  beforeMount () {
    console.log("beforeMount")
  },
  mounted () {
    console.log("this.$route")
    console.log(this.$route)
    console.log(this.$router)
    console.log("this.id" + this.id)
  },
  beforeDestroy (to, from) {
    console.log('局部路由守卫--beforeDestroy  in B', to, from)
  },
  beforeRouteEnter (to, from, next) {
    console.log('局部路由守卫--beforeRouteEnter', to, from)
    next()
  },
  beforeRouteUpdate (to, from, next) {
    console.log('局部路由守卫--beforeRouteUpdate', to, from)
    next()
  },
  beforeRouteLeave (to, from, next) {
    console.log('局部路由守卫--beforeRouteLeave', to, from)
    next()
  },
  props: ["id"],
  data () {
    return {
    }
  },
  components: {
  }
}
</script>
<style  scoped>
.containerCLs {
  width: 100000px;
}
</style>

在这里插入图片描述

参考

vue-router 官网文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值