Vue的路由整理

路由:一个路径对应一个组件

    1.创建组件    例如: let home 
    2.配置路由映射表
    3.注册路由映射表
    4. 把路由挂载到根实例上; 

基础路由

 <div id="app">
        <!-- to : 跳转的路由  tag:指定router-link渲染标签 -->
        <!-- router-link:固定的,link用于点击 -->
        <router-link to="/allhome" tag="button">首页</router-link>
        <router-link to="/allperson"  tag="button">个人中心</router-link>
        <!-- 用于显示路由对应组件的地方 -->
        <!-- 根据路由显示对应的组件 -->
        <router-view></router-view>
    </div>
   
    <script src="vue.js"></script>
    <script src="../vue-router/dist/vue-router.js"></script>
    <script>
         
        let home = {
            data(){
                return {
                    con:'首页'
                }
            },
            created(){
                // 显示组件时,需要再次创建组件实例;调用钩子函数;
                console.log("组件创建");
            },
            beforeDestroy(){
                console.log("销毁");
            },
            template:"<div>{{con}}</div>"
        }
        let person={
            data(){
                return {
                    con:'个人中心页'
                } 
            },
            template:"<div>{{con}}</div>"
        }
        // 配置路由映射表: 是路由和组件的配对情况
        let routes =[{path:"/allhome",component:home},{path:"/allperson",component:person}];
        // 注册映射表
        let router = new VueRouter({
            routes:routes//前面的属性名固定的不能变,属性值可以变
        })
        // 将路由挂载到根实例上
        let vm = new Vue({
            el:"#app",
            data:{

            },
            router:router//前面的属性名固定的不能变,属性值可以变
        })
    </script>

2.vue-router中的方法

vue-router一定要放vue.js的后面
当切换组件时,组件会销毁;
当每一个被路由渲染出来的组件上有一个$router属性,在这个属性的原型上有一些操作路由的方法,37行this的原型链上

1.push : 直接跳转到当前路径对应的路由上 push(路径)
2.back : 回退到上一次的路由上
3.go(number):可以往前可以往后回退后前进几个

<div id="app">
        <!-- to属性和路由映射表的path的属性值一样 -->
        <router-link to="/home" tag="button">首页</router-link>
        <router-link to="/list"tag="button">列表页</router-link>
        <!-- 展示路由对应的组件,当组件切换时,组件的DOM元素删除; -->
        <router-view></router-view>
    </div>
    <script src="vue.js"></script>
    <script src="../vue-router/dist/vue-router.js"></script>
    <script>
    
        let home={
            data(){
                return {
                }
            },
            created(){
                // 显示组件时,需要再次创建组件实例;调用钩子函数;
                console.log("组件创建");
            },
            methods:{
                goList(){
                    console.log(this);
                    //this.$router.push("/list")
                }
            },
            beforeDestroy(){
                console.log("销毁");
            },
            template:"<div>首页内容<button @click='goList'>去列表页</button></div>"
        };
        let list={
            data(){
                return {
                }
            },
            methods:{
                goback(){
                    console.log(this);
                    this.$router.go(-1);
                }
            },
            template:"<div>列表页内容<button @click='goback'>返回</button></div>"
        }
        // 路由映射表
        let routes = [{path:"/home",component:home},{path:"/list",component:list}];
        // 注册路由映射表
        let router = new VueRouter({
            routes
        });
        // 挂载到根实例上
        let vm  = new Vue({
            el:"#app",
            router
        });
        
   </script>

3.路由的嵌套

  1. detail 和login都是list组件的子路由组件
  2. 在组件路由配置是,对象中有children属性,属性值是一个数组,里面配置了子路由,路由中不需要加父路由路径地址,同时也不需要加"/",当子路由进行匹配式,会自动加上父路由和/到子路由的前面;
  3. 二级路由不能直接配置到routes,应该找到它对应的以及路由,配置到其children属性上;
 <div id="app">
        <router-link to="/home" tag="button" class="a">首页</router-link>
        <router-link to="/list" tag="button" class="b">列表页</router-link>
        <router-view></router-view>
    </div>
    <template id="list">
        <div>
            列表页
            <router-link to="/list/detail">详情页</router-link>
            <router-link to="/list/login">登录页</router-link>
            <router-view></router-view>
        </div>
    </template>  
    <script src="vue.js"></script>
    <script src="../vue-router/dist/vue-router.js"></script>
    <script>
        let home={
            template:"<div>首页</div>"
        }
        let list={
            template:"#list"
        };
        let detail = {
            template:"<div>详情页</div>"
        }
        let login = {
            template:"<div>登录注册页</div>"
        };
        // detail 和login都是list组件的子路由组件
        // 在组件路由配置是,对象中有children属性,属性值是一个数组,里面配置了子路由,路由中不需要加父路由路径地址,同时也不需要加"/",当子路由进行匹配式,会自动加上父路由和/到子路由的前面;
        // 二级路由不能直接配置到routes,应该找到它对应的以及路由,配置到其children属性上;
        let routes  =[
            {path:"/home",component:home},
            {path:"/list",component:list,children:[
                {path:"detail",component:detail},
                {path:"login",component:login}
            ]}
        ];
        let router = new VueRouter({
            routes
        })
        let vm = new Vue({
            el:"#app",
            data:{

            },
            router
        })
    
    </script>

4.命名路由

  <div id="app">
        <!-- 将to改成动态属性 :to={name:组件的name名称} -->
        <router-link :to="{name:'first'}">首页</router-link>
        <router-view></router-view>
    </div>
    <script src="node_modules/vue/dist/vue.js"></script>
    <script src="node_modules/vue-router/dist/vue-router.js"></script>
    <script>
        // 通过名字取匹配路由
        let home={
            template:"<div>首页</div>"
        }
        let routes  =[
            {path:"/home",component:home,name:"first"}
        ];
        let router = new VueRouter({
            routes
        })
        let vm = new Vue({
            el:"#app",
            data:{

            },
            router
        })
    
    </script>

5.动态路由

动态路由:路由传参;路径后面是一个:变量;这就是动态路由,也可以叫路由动态传参;会把id以属性方式放到$route的params属性上,属性值就是路由实际的路径值

1.代码量少
2. 由于动态路由渲染的是同一个home组件,所以home组件不再销毁,当然也不再创建,复用了之前的组件,性能高;但是生命周期的钩子函数也不再执行;

   <div id="app">
        <router-link to="/home/1">第一本</router-link>
        <router-link to="/home/2">第二本</router-link>
        <router-link to="/home/3">第三本</router-link>
        <router-view></router-view>
    </div>
    <script src="vue.js"></script>
    <script src="../vue-router/dist/vue-router.js"></script>
    <script>
        // $router:push go  back  forward
        
        let home={
            // created(){
            //     // 
            //     console.log(this.$route);
            // },
            // watch:{
            //     '$route'(to,from){
            //        console.log(to);// to: 要到达的组件的$route
            //        console.log(from);// from :上一个$route
            //     }
            // },
            // 路由守卫
            // 在路由更新之前会默认调用该钩子函数
            beforeRouteUpdate(to,from,next){
                console.log(to);// 即将进入的目标路由的对象信息
               console.log(from);// 即将离开路由的对象信息
                console.log(next);// 函数
                // 1. next 函数
                // next(): 会立即进入到目标路由
                // next(false):中断当前的导航;不再去访问下一个路由
                if(to.params.id==3){
                    next({path:"/home/1"});
                    return;
                }
                // 权限校验
                next();
            },
            template:"<div>这是我喜欢的第{{$route.params.id}}本书</div>"
        }
        
       
        let routes  =[
            {path:"/home/:id",component:home}
        ];
        let router = new VueRouter({
            routes
        })
        let vm = new Vue({
            el:"#app",
            data:{
            },
            router
        })
    
    </script>

6.路由传参

通过名字取匹配路由
1.:id 路由动态传参
2. query传参 这个用path传参
3. params传参 这个用name传参,通过冒号传的参都放在这个属性上了

 <div id="app">
        <router-link :to="{name:'first'}">首页</router-link>
        <router-link :to="{name:'second'}">列表页</router-link>
        <router-view></router-view>
    </div>
    <script src="vue.js"></script>
    <script src="../vue-router/dist/vue-router.js"></script>
    <script>
       
        let home={
            methods:{
                goList(){
                    // push("/list")
                    // push({path:"",query:{}})
                    //this.$router.push({path:"/list",query:{id:100}})
                    this.$router.push({name:"second",params:{id:500}})
                
                }
            },
            template:"<div>首页<button @click='goList'>去列表</button></div>"
        }
        let list={
            created(){
                //let id = this.$route.query.id;
                console.log(this.$route.params.id);
            },
            template:"<div>列表页</div>"
        }
        let routes  =[
            {path:"/home",component:home,name:"first"},
            {path:"/list",component:list,name:"second"}

        ];
        let router = new VueRouter({
            routes
        })
        let vm = new Vue({
            el:"#app",
            data:{

            },
            router
        })
    
    </script>

7.命名视图

 <div id="app">
        <!-- 将to改成动态属性 :to={name:组件的name名称} -->
        <router-link :to="{name:'first'}">首页</router-link>
        <!-- 没有name属性,会显示属性为default的组件 -->
        
        <router-view></router-view>
        <router-view name="b"></router-view>
        <router-view name="c"></router-view>
    </div>
    <script src="vue.js"></script>
    <script src="../vue-router/dist/vue-router.js"></script>
    <script>
        // 通过名字取匹配路由
        let home={
            template:"<div>首页</div>"
        }
        let foo = {
            template:"<div>foo</div>"
        }
        let bar={
            template:"<div>bar</div>"
        }
        let routes  =[
            {path:"/home",components:{//细节点,配置路由映射表的时候要加s,放对象
                default:home,// home对应没有name属性的router-view,走默认
                // 这个对象属性名和router-view的name属性值对应
                b:foo,
                c:bar
            },name:"first"}
        ];
        let router = new VueRouter({
            routes
        })
        let vm = new Vue({
            el:"#app",
            data:{

            },
            router
        })
    </script>

7.路由的守卫

守卫: 7个
router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
全局守卫: beforeEach afterEach beforeResolve
路由独享守卫: beforeEnter 在路由配置上直接定义 beforeEnter 守卫
组件内部守卫: beforeRouteEnter beforeRouteUpdate beforeRouteLeave

<div id="app">
        <router-link to="/home/1" tag="button">第一本</router-link>
        <router-link to="/home/2" tag="button">第二本</router-link>
        <router-link to="/home/3" tag="button">第三本</router-link>
        <router-link to="/list" tag="button">列表</router-link>
        <router-view></router-view>
    </div>
    <script src="vue.js"></script>
    <script src="../vue-router/dist/vue-router.js"></script>
    <script>
        //切换到另一个组件,组件时会销毁的;
        // 导航守卫:当切换导航时,会默认调用一些钩子函数,那么这些钩子函数就是导航的守卫;可以在进入这个导航或者离开这个导航时,在钩子函数中做一些事情
        // 生命周期 11个
        // 守卫: 7个
        //router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
        // 全局守卫: beforeEach  afterEach  beforeResolve
        // 路由独享守卫: beforeEnter 在路由配置上直接定义 beforeEnter 守卫
        // 组件内部守卫: beforeRouteEnter beforeRouteUpdate beforeRouteLeave
        let home = {
            beforeDestroy() {
                //同样用的都是一个组件,例如home组件,这个函数不执行,也不销毁,切换到另一个组件,组件时会销毁的;例如list
                // console.log(99)
            },
            beforeRouteEnter(to, from, next) {
                // 这个钩子函数执行时进入组件实例之前,此时组件实例还没有创建;
                console.log(this);// this==>window
                console.log("home beforeRouteEnter")
                next(vm => {
                    // 最后执行
                    // 当next执行传入回调函数,回调函数不能立即执行,等到组件实例创建好之后,才会触发这个回调函数;其中vm就是组件实例
                    //console.log(vm);
                })
            },
            beforeRouteUpdate(to, from, next) {
                // 
                console.log("home beforeRouteUpdate")
                next()
            },
            beforeRouteLeave(to, from, next) {
                // 当离开list这个组件时,会调用这个钩子函数
                console.log(" home beforeRouteLeave")
                next();
            },
            template: "<div>这是第{{$route.params.id}}本书</div>"
        };
        // 当第一次进入到list组件时,只触发了beforeRouteEnter;
        let list = {
            beforeRouteEnter(to, from, next) {
                // 这个钩子函数执行时进入组件实例之前,此时组件实例还没有创建;
                // console.log(this);// this==>window
                console.log("list beforeRouteEnter")
                next(vm => {
                    // 当next执行传入回调函数,回调函数不能立即执行,等到组件实例创建好之后,才会触发这个回调函数;其中vm就是组件实例
                    //console.log(vm);
                })
            },
            // beforeRouteUpdate(to,from,next){
            // 当复用这个组件并且更新了组件时,这个函数才会被调用;
            // this--> 当前的组件实例
            //     // 
            //     console.log("beforeRouteUpdate")
            //     next()
            // },
            beforeRouteLeave(to, from, next) {
                // 当离开list这个组件时,会调用这个钩子函数
                console.log(" list beforeRouteLeave")
                next();
            },
            template: "<div>列表页内容</div>"
        }
       
        
        let routes = [{
            path: "/home/:id", component: home, beforeEnter: (to, from, next) => {
                console.log("home beforeEnter");
                next();
            }
        }, {
            path: "/list", component: list, beforeEnter: (to, from, next) => {//这些守卫与全局前置守卫的方法参数是一样的。
                console.log("list beforeEnter");
                next();
            }
        }]
        let router = new VueRouter({
            routes
        });
        // 全局的前置钩子函数;只要切换组件,就会执行
        router.beforeEach((to, from, next) => {
            // console.log(to);// 到哪去
            // console.log(from);// 从哪来
            console.log(1);
            // 在这个钩子函数中获取到用户的信息,进行权限的校验,如果不符合要求,那么next不需要运行;或者直接跳转到首页或 403页面
            next();// 只有执行了next,才会往下继续跳转路由;
        });
        router.beforeResolve((to, from, next) => {
            // console.log(to);// 到哪去
            // console.log(from);// 从哪来
            console.log(2);
            next();// 只有执行了next,才会往下继续跳转路由;
        });
        // 全局后置的钩子函数
        router.afterEach((to, from) => {
            // console.log(to);
            console.log(3);
            // 路由切换成功以后执行的钩子函数
        });
        console.log(router);
        // 用户  /list   管理员 : /list   /edit  /home
        // 相同路由切换路由时:路由守卫执行顺序beforeEach==>beforeEnter==>beforeRouteUpdate==>beforeResolve==>afterEach==>beforeResolve
        //切换路由时执行顺序:beforeRouteLeave==>beforeEach==>beforeEnter==>beforeRouteEnter==>afterEach
        //当进入组件时,先触发全局的前置钩子,然后触发进入组件的路由独享守卫,然后触发组件内部的beforeRouteEnter,最后触发全局的beforeResolve和全局后置钩子函数

        let vm = new Vue({
            el: "#app",
            router
        });
        
        //导航被触发。
        // 在失活的组件里调用离开守卫。
        // 调用全局的 beforeEach 守卫。
        // 在重用的组件里调用 beforeRouteUpdate 守卫(2.2 +) 。
        // 在路由配置里调用 beforeEnter。
        // 解析异步路由组件。
        // 在被激活的组件里调用 beforeRouteEnter。
        // 调用全局的 beforeResolve 守卫(2.5 +) 。
        // 导航被确认。
        // 调用全局的 afterEach 钩子。
        // 触发 DOM 更新。
        // 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
    </script>

8.keep-alive

用于缓存组件,如果该组件还会再启用,那么可以使用keep-alive进行组件缓存和优化,提高性能,缓存的组件不需要销毁,也不需要再创建

   <div id="app">
        <button @click="fn">点一点</button>
        <!-- // component : 内置组件,根据is属性来显示对应的组件;is属性的属性值保持和组件名字一致;然后可以显示对应的组件
        // 如果是动态属性,那么会去data中取值 -->
        <!-- <component is="second"></component> -->
        <keep-alive>
            <!-- keep-alive:用于缓存组件,如果该组件还会再启用,那么可以使用keep-alive进行组件缓存和优化,提高性能,缓存的组件不需要销毁,也不需要再创建 -->
            <component v-bind:is="one"></component>
        </keep-alive>
        
    </div>
    <script src="vue.js"></script>
    <script src="../vue-router/dist/vue-router.js"></script>
    <script>
        // component 和keep-alive 都是内置组件,在VUE代码已经内置好的组件;
        // 闭合标签使用组件
        // component: 每次能动态显示一个组件,当切换下一个组件时,当前组件要销毁  把component放在keep-alive闭合标签中,就不销毁
        // keep-alive : keep: 保持  alive:活力 
        // VUE项目的优化: keep-alive
        let child={
            data(){
                return {
                    a:100
                }
            },
            template:"<div>{{a}}</div>"
        }
        let first = {
            destroyed(){
                console.log("销毁")
            },
            components:{
                child
            },
            // 生命周期的钩子函数
            //9.activated 10.deactivated :这两个钩子函数呢一般配合<keep-alive><keep-alive/>来使用。
            //11.errorCaptured
            activated(){
                // 当缓存组件有被显示出来时,会触发这个钩子函数
                console.log(100);
            },
            deactivated(){
                // 当缓存的组件隐藏时,会触发这个钩子函数;
                console.log(200);
            },
            // 当子孙组件出错时,会调用这个钩子函数
            errorCaptured(a,b,c){
                console.log(a);
                console.log(b);
                console.log(c);
                console.log("子组件报错")
            },
            template:"<div>我是老大<child></child></div>"
        };
        let second = {
            template:"<div>我是老二</div>"
        }
        let third = {
            template:"<div>我是老三</div>"
        }
        let vm = new Vue({
            el:"#app",
            data:{
                 one:"first"
            },
            methods:{
                fn(){
                    let  ary = ["first","second","third"];
                    let index = ary.indexOf(this.one);
                    if(index<2){
                        this.one = ary[index+1];
                    }else{
                        this.one = ary[0];
                    }
                }
            },
            components:{
                first,
                second,
                third
            }
            
        });
    </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值