zoukankan      html  css  js  c++  java
  • vue学习记录(四)---router的运用

    1、vue router 的入门案例

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
        </style>
        <script src="./lib/vue.js"></script>
        <script src="./lib/vue-router.js"></script>
        <script>
            window.onload = function () {
                let rout = new VueRouter({
                    routes: [
                        //传参时,注意是$route.params
                        {
                            path: '/user/:id', component: {
                                template: '<div>this is user,id is {{$route.params.id}}</div>',
                                beforeRouteUpdate(to, from, next) {
                                    console.log('to:', to);
                                    console.log(from);
                                    //如果没有next(),那么就不会往下走
                                    next();
                                }
                            }
                        }
                    ]
                });
    
                let VM = new Vue({
                    el: '#container',
                    router: rout,
                    methods: {
                        forward() {
                            //前进
                            this.$router.go(1);
                        },
                        backward() {
                            //后退
                            this.$router.go(-1);
                        },
                        push() {
                            //跳转
                            this.$router.push('/user/111');
                        }
                    }
                })
            }
        </script>
    </head>
    <body>
    <div id="container">
        <input type="button" value="前进" @click="forward">
        <input type="button" value="后退" @click="backward">
        <input type="button" value="跳转" @click="push"><br/>
        <router-link to="/user/111">user111</router-link>
        <router-link to="/user/222">user222</router-link>
        <router-link to="/user/333">user333</router-link>
        <router-view></router-view>
    </div>
    </body>
    </html>

    注意:在vuerouter里面用的component未必要在vue里面注册组件,可以独立的存在

    2、子路由的使用

      a、子路由使用一 => 在路由页面里面定义子路由

    <body>
    <div id="container">
        <router-link to="/">first</router-link>
        <router-link to="/second">second</router-link>
        <router-view></router-view>
    </div>
    <template id="first">
        <div>
            <h1>this is first</h1>
            <!--在这个子路由里面用的就是二级路径而不是全路径-->
            <router-link to="/">aaa</router-link>
            <router-link to="/bbb">bbb</router-link>
            <router-view></router-view>
        </div>
    </template>
    <script src="./vue.js"></script>
    <script src="./vue-router.js"></script>
    <script>
    let first = {
        template: '#first'
    };
    let second = {
        template: '<div>this is second</div>'
    };
    let fourth = {
        template: '<div>this is fourth</div>'
    };
    let fifth = {
        template: '<div>this is fifth</div>'
    };
    let routes = [
        {
            path: '/',
            component: first,
            children: [                 //注意子路由里面children接收的是一个数组,并且里面的子路由不能够带'/'符号
                {path:'', component: fourth},
                {path: 'bbb', component: fifth}
            ]
        },
        {path: '/second', component: second}
    ];
    let router = new VueRouter({
        routes
    });
    let app = new Vue({
        el: '#container',
        router
    });
    </script>
    export default [
        {
            path: '/',
            name: 'home',
            component: Home
        },
        {
            path: '/about',
            name: 'about',
            component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
        },
        {
            path: '/check',
            component: check,
            redirect: '/second',
            children: [
                { path: '/first', component: first },
                { path: '/second', component: second }
            ]
        }
    ]

       b、子路由的使用二  => 在路由页面外面定义子路由标签

    <body>
    <div id="container">
        <router-link to="/first">first</router-link>
        <router-link to="/first/aaa">aaa</router-link>      <!--页面会转到first页面下的aaa标签,注意这里的写法-->
        <router-link to="/first/bbb">bbb</router-link>      <!--页面会转到first页面下的bbb标签,注意这里的写法-->
        <router-link to="/second">second</router-link>
        <router-view></router-view>
    </div>
    <template id="first">
        <div>
            <h1>this is first</h1>
            <router-view></router-view>
        </div>
    </template>
    <script src="./vue.js"></script>
    <script src="./vue-router.js"></script>
    <script>
    let first = {
        template: '#first'
    };
    let second = {
        template: '<div>this is second</div>'
    };
    let fourth = {
        template: '<div>this is fourth</div>'
    };
    let fifth = {
        template: '<div>this is fifth</div>'
    };
    let routes = [
        {
            path: '/first',
            component: first,
            children: [                 //注意子路由里面children接收的是一个数组,并且里面的子路由不能够带'/'符号
                {path:'aaa', component: fourth},
                {path: 'bbb', component: fifth}
            ]
        },
        {path: '/second', component: second}
    ];
    let router = new VueRouter({
        routes
    });
    let app = new Vue({
        el: '#container',
        router
    });
    </script>
    </body>

    3、路由参数的传递

     路由接收参数需要用到$route,注意这里是$route而不是$router;

    <body>
    <div id="container">
    <!--    <router-link to="/first">first</router-link>传参可以用以下的写法-->
        <router-link :to="{name: 'aaa', params: {username: 'AAA', id: 123}}">first</router-link>
        <!--接收相应的数据用$route.name, $route.params.username或者$route.params.id-->
        <router-link to="/second">second</router-link>
        <router-view></router-view>
    </div>
    <script src="./vue.js"></script>
    <script src="./vue-router.js"></script>
    <script>
    let first = {
        template: '<div>this is first content--{{$route.params.username}}---{{$route.params.id}} <input type="button" value="btn" @click="check"></div>',
        methods: {
            check() {
                console.group('相应的参数');
                console.log(this.$route.params.username, this.$route.params.id); //注意这里的this.$route要和this.$router区分开
                console.groupEnd();
            }
        }
    };
    let second = {
        template: '<div>this is second content</div>'
    };
    let routes = [
        {path: '/first', name: 'aaa', component: first},
        {path: '/second', name: 'bbb', component: second}
    ];
    let app = new Vue({
        el: '#container',
        router: new VueRouter({routes})
    });
    </script>
    </body>

    通过url进行传值

    <body>
    <div id="container">
        <router-link to="/first/haha/123">first</router-link>
        <router-link to="/second/yes/111">second</router-link>
        <router-view></router-view>
    </div>
    <script src="./vue.js"></script>
    <script src="./vue-router.js"></script>
    <script>
    let first = {
        template: '<div>this is first content, str的值为{{$route.params.str}}, id的值为{{$route.params.id}}</div>',
    };
    let second = {
        template: '<div>this is second content</div>'
    };
    let routes = [
        {path: '/first/:str/:id(\d+)', name: 'aaa', component: first},   //当地址不完全匹配的时候不显示,只有完全匹配的时候会显示 #/first/haha/34
        {path: '/second/:str/:id', name: 'bbb', component: second}        //如果需要添加正则匹配的时候,可以用(\d+)或者其他方式进行添加
    ];
    let app = new Vue({
        el: '#container',
        router: new VueRouter({routes})
    });
    </script>
    </body>

     通过组件传值的方式传值

    {
        path: '/check',
        component: check,
        // redirect: '/first/yf',
        children: [
            { path: '/first/:name', name: 'first', component: first },
            { path: '/second', component: second }
        ],
        // props: true      // 方式一    这种情况假如路由下是/check/:name, 那么会自动的把name进行组件传值的
        // props: {         // 方式二
        //     name: 'test'
        // },
        props: route => {   // 方式三
            return { name: 'check' }
        }
    }

    那么接收和组件的接收方式是一样的, 在路由的view中写如下代码进行接收

    export default {
        props: {
            name: {
                type: String,
                default: ''
            }
        },
        methods: {
            getName () {
                console.log(this.name);
            }
        }
    }

    路由中还可以定义meta进行传值

    4、单页面多路由区域

    多个路由区域是指存在多个router-view的时候需要在router-view上声明name

    <body>
    <div id="container">
        <router-link :to="{name: 'aaa'}">first</router-link>
        <router-link :to="{name: 'bbb'}">second</router-link>
        <router-view></router-view>
        <router-view name="part"></router-view>     <!--存在多个router-view的时候要指定name-->
        <router-view name="block"></router-view>
    </div>
    <script src="./vue.js"></script>
    <script src="./vue-router.js"></script>
    <script>
    let first = {
        template: '<div>this is first content</div>',
    };
    let second = {
        template: '<div>this is second content</div>'
    };
    let routes = [
        {path: '/first', name: 'aaa', components: {
                default: first,             //指定默认的router-view的组件,即没有声明name的router-view
                part: second,               //指定名字为part的router-view的组件
                block: first                //指定名字为block的router-view的组件
            }
        },
        {path: '/second', name: 'bbb', components: {
                default: second,
                part: first,
                block: second
            }
        }
    ];
    let app = new Vue({
        el: '#container',
        router: new VueRouter({routes})
    });
    </script>
    </body>

     注意,当存在多个router-view的时候,里面的component需要转变为components

     5、路由的重定向

    正常的重定向,可以在route里面加配redirect这个配置,如果需要动态调用,可以用$router.push(路由),具体例子如下:

    <body>
    <div id="container">
        <router-link to="/first/haha/123">first</router-link>
        <router-link to="/second/yes/111">second</router-link>
        <router-view></router-view>
    </div>
    <script src="./vue.js"></script>
    <script src="./vue-router.js"></script>
    <script>
    let first = {
        template: '<div>this is first content, str的值为{{$route.params.str}}, id的值为{{$route.params.id}}</div>',
    };
    let second = {
        template: '<div>this is second content <input type="button" value="btn" @click="check"></div>',
        methods: {
            check() {
                this.$router.push('/first/haha/111', function(router) {
                    console.log(arguments);         //动态的转到某个路由上,可以用push这个方法
                });
            }
        }
    };
    let routes = [
        {path: '/first/:str/:id(\d+)', name: 'aaa', component: first}, 
        {path: '/second/:str/:id', name: 'bbb', component: second, redirect: '/first/yu/111'},        //如果需要添加正则匹配的时候,可以用(\d+)或者其他方式进行添加
        // {path: '/second/:str/:id', name: 'bbb', component: second, redirect: {name: 'aaa', params: {str: 'get', id: 111}}}        //如果需要添加正则匹配的时候,可以用(\d+)或者其他方式进行添加
    ];
    let app = new Vue({
        el: '#container',
        router: new VueRouter({routes})
    });
    </script>
    </body>

     6、alias 别名的用法

    <body>
    <div id="container">
        <router-link to="/">first</router-link>
        <router-link :msg=msg to="/bill">bill</router-link> <!--利用别名进行跳转-->
        <router-link :msg=msg to="/haha">second</router-link>
        <router-view></router-view>
    </div>
    <script src="./vue.js"></script>
    <script src="./vue-router.js"></script>
    <script>
    let first = {
        template: '<div>this is first content, str的值为{{$route.params.str}}, id的值为{{$route.params.id}}</div>',
    };
    let second = {
        template: '<div>this is second content</div>',
    };
    let routes = [
        {path: '/', name: 'aaa', component: first, alias: '/haha'},
        {path: '/second', name: 'bbb', component: second, alias: '/bill'},  //添加别名后,访问/bill可以跳转到/second这个路径下
    ];
    let app = new Vue({
        el: '#container',
        data: {
          msg: 'this is msg'
        },
        router: new VueRouter({routes})
    });
    </script>
    </body>

     7、路由过渡动画

    添加路由的过渡动画需要在router-view外层包一层的transition标签,如下例:

    <style>
       .fade-enter {            /*进入过渡的开始状态,元素插入时生效,只应用一帧后立刻删除*/
           opacity: 0;
       }
        .fade-enter-active {     /*进入过渡的结束状态,元素插入时生效,在过渡过程完成后删除*/
            transition: opacity 0.5s;
        }
        .fade-leave {            /*离开过渡的开始状态,元素被删除时触发,只应用一帧后立刻删除*/
            opacity: 1;
        }
        .fade-leave-active {     /*离开过渡的结束状态,元素被删除时生效,离开过渡完成后被删除*/
            opacity: 0;
            transition: opacity 0.5s
        }
    </style>
    </head>
    <body>
    <div id="container">
        <router-link to="/first">first</router-link>
        <router-link to="/second">second</router-link>
        <transition name="fade" mode="out-in">  <!--默认的mode是in-out表示进入后,再删除-->
            <router-view></router-view>
        </transition>
    </div>
    <script src="./vue.js"></script>
    <script src="./vue-router.js"></script>
    <script>
    let first = {
        template: '<div>this is first content</div>',
    };
    let second = {
        template: '<div>this is second content</div>',
    };
    let routes = [
        {path: '/first', name: 'aaa', component: first},
        {path: '/second', name: 'bbb', component: second},
    ];
    let app = new Vue({
        el: '#container',
        data: {
          msg: 'this is msg'
        },
        router: new VueRouter({routes})
    });
    </script>
    </body>

     8、history模式与配置404页面

     a、在配置路由后,访问路由的时候,在地址栏中会显示#相当符号,那么为了美观,可以选择另外一种显示方式history, router里的模式有hash与history,默认是hash

     b、如果访问了未知页面,为了友好的用户体验,可以配置404页面

    <body>
    <div id="container">
        <router-link to="/first">first</router-link>
        <router-link to="/second">second</router-link>
        <router-view></router-view>
    </div>
    <script src="./vue.js"></script>
    <script src="./vue-router.js"></script>
    <script>
    let first = {
        template: '<div>this is first content</div>',
    };
    let second = {
        template: '<div>this is second content</div>',
    };
    let error = {
        template: '<div>404, 没有找到相关的页面</div>'
    };
    let routes = [
        {path: '/first', name: 'aaa', component: first},
        {path: '/second', name: 'bbb', component: second},
        {path:'*', component: error}            //配置404页面的时候,path为*号
    ];
    let app = new Vue({
        el: '#container',
        data: {
          msg: 'this is msg'
        },
        router: new VueRouter({mode:'history', routes})         //注意使用history必需要在服务器的环境下进行配置,否则会报错
    });
    </script>
    </body>

    9、路由中的钩子函数

     有两种方式:一种方式,在component里面进行写beforeRouterEnter, beforeRouterLeave, 第二种方式, 在route里面定义相当的方法 beforeEnter,例子如下:

    <body>
    <div id="container">
        <router-link to="/first">first</router-link>
        <router-link to="/second">second</router-link>
        <router-view></router-view>
    </div>
    <script src="./vue.js"></script>
    <script src="./vue-router.js"></script>
    <script>
        let first = {
            template: '<div>this is first content</div>',
        };
        let second = {
            template: '<div>{{msg}}</div>',
            data: function() {
                return {
                    'msg': 'this is second content'
                }
            },
            //方法一, 写在component里面可以触发相应的钩子
            beforeRouteEnter(to, from, next){
                console.log('beforeRouteEnter', arguments);
                next()
            },
            beforeRouteLeave(to, from ,next) {
                console.log('beforeRouteLeave', arguments);
                next()
            }
        };
        //方法二:在router里面写钩子
        let routes = [
            {
                path: '/first', name: 'aaa', component: first, beforeEnter(to, from, next) {
                    //to表示来的路由,from表示目标路由,next表示执行跳转的函数
                    next();             //next表示执行跳转的动作,next里面接收一个参数,如果是true表示执行跳转,如果是false则表示不跳转
                }
            },
            {path: '/second', name: 'bbb', component: second},
        ];
        let app = new Vue({
            el: '#container',
            data: {
                msg: 'this is msg'
            },
            router: new VueRouter({mode: 'hash', routes})         //注意使用history必需要在服务器的环境下进行配置,否则会报错
        });
    </script>
    </body>

    beforeEach可以做登录页面的跳转  router.beforeEach() => {},     next()的括号里可以传boolean 也可以传string, 也可以传route对象实例,如{ name: 'home' } 等

    let router = new VueRouter({ routes });
    router.beforeEach((to, from, next) => {
        if (to.name === 'about') {
            next({ name: 'home' })
        } else {
            next();
        }
    })
    export default router;

    10、编程式导航

    <body>
    <div id="container">
        <div>
            <input type="button" value="前进" @click="forward">
            <input type="button" value="后退" @click="back">
            <input type="button" value="向后跳2" @click="skip">
            <input type="button" value="回首页" @click="gohome">
        </div>
        <router-link to="/first">first</router-link>
        <router-link to="/second">second</router-link>
        <router-view></router-view>
    </div>
    <script src="./vue.js"></script>
    <script src="./vue-router.js"></script>
    <script>
        let first = {
            template: '<div>this is first content</div>',
        };
        let second = {
            template: '<div>this is second content</div>',
        };
        let routes = [
            {path: '/first', name: 'aaa', component: first},
            {path: '/second', name: 'bbb', component: second},
        ];
        let app = new Vue({
            el: '#container',
            data: {
                msg: 'this is msg'
            },
            methods: {
                forward() {
                    this.$router.forward();     //向前跳转
                },
                back() {
                    this.$router.back();       //向后跳转
                },
                skip() {
                    this.$router.go(-2);      //跳转指定步数
                },
                gohome() {
                    //push的两种写法
                    // this.$router.push('/first').then(() => console.log('完成跳转')).catch(() => console.log('跳转失败')); //如果是replace的话,那么就不会生成记录
                    this.$router.push({name: 'aaa'}, ()=> console.log('ok'), ()=> console.log('no'));
    
                }
            },
            router: new VueRouter({mode: 'hash', routes})
        });
    </script>
    </body>

     11、如何配置页面刷新

    配置redirect的路由

      {
        path: '/redirect',
        component: Layout,       //如有外层框架
        hidden: true,
        children: [
          {
            path: '/redirect/:path*',
            component: () => import('@/views/redirect/index')
          }
        ]
      }        

    redirect组件内容

    <script>
    export default {
        created () {
            const { params, query } = this.$route
            const { path } = params
            this.$router.replace({ path: '/' + path, query })
        },
        render: h => h()    //阻止警示信息
    }
    </script>

    跳转:

    this.$router.replace({
         path: '/redirect' + fullPath
    })

     注意:在router-view外围需要配置keep-alive如下

    <transition name="fade-transform" mode="out-in">
        <keep-alive :include="cachedViews">
             <router-view :key="key"></router-view>
        </keep-alive>
    </transition>

    注意: keep-alive中有两个参数,include: 字符串或正则表达式。只有匹配的组件会被缓存。exclude: 字符串或正则表达式。任何匹配的组件都不会被缓存。

    exclude优先级大于include,例子中的cachedViews的类型是Array<string>

    <keep-alive include="test-keep-alive">
      <!-- 将缓存name为test-keep-alive的组件 -->
      <component></component>
    </keep-alive>
    
    <keep-alive include="a,b">
      <!-- 将缓存name为a或者b的组件,结合动态组件使用 -->
      <component :is="view"></component>
    </keep-alive>
    
    <!-- 使用正则表达式,需使用v-bind -->
    <keep-alive :include="/a|b/">
      <component :is="view"></component>
    </keep-alive>
    
    <!-- 动态判断 -->
    <keep-alive :include="includedComponents">
      <router-view></router-view>
    </keep-alive>
    
    <keep-alive exclude="test-keep-alive">
      <!-- 将不缓存name为test-keep-alive的组件 -->
      <component></component>
    </keep-alive>

     include 和 exclude 属性允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示:匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。

    也就相当于先匹配components里的name名字,所以取名的时候尽量与与过滤的一致

    重点:在hash环境下,刷新页面显示404,这个时候面beforeEach的时候更改为next({...to, replace: true})便可

  • 相关阅读:
    Docker 安装 MySQL
    Docker安装
    Thymeleaf语法总结
    SpringBoot总结之事务和AOP
    SpringBoot总结之Spring Data Jpa
    SpringBoot总结之属性配置
    Spring总结之SpringMvc下
    Spring总结之SpringMvc上
    Spring总结之事务
    在什么情况下使用@ResponseBody 注解?
  • 原文地址:https://www.cnblogs.com/rickyctbu/p/9750221.html
Copyright © 2011-2022 走看看