Vue Router

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面 SPA(Single Page Application)应用变得易如反掌。

什么是路由?

请看下面这个例子:通过 ajax 请求,更新页面局部内容

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <a href="#/login">登录页面</a>
        <a href="#/register">注册页面</a>

        <div id="app">
        </div>

        <script type="text/javascript">
            var oDiv = document.getElementById('app');
            window.onhashchange = function() {
                console.log(location.hash);

                switch (location.hash) {
                    case '#/login':
                        oDiv.innerHTML = '<h2>我是登录页面</h2>'
                        break;
                    case '#/register':
                        oDiv.innerHTML = '<h2>我是注册页面</h2>'
                        break;
                    default:
                        // statements_def
                        break;
                }
            }
        </script>
    </body>
</html>

那 Vue Router 能干什么?

它能使获取请求更新页面的过程更可配置,也就是简化上面的代码,提供更丰富的配置

看下面这个例子

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app"></div>
        <!-- 1.引入vue.js -->
        <script type="text/javascript" src="../js/vue.min.js"></script>
        <!-- 2.引入核心的插件vue-router -->
        <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script>
        <script type="text/javascript">
            // 2.让vue使用该VueRouter创建
            Vue.use(VueRouter);

            //声明组件
            var Login = {
                template: `<div>我是登录页面</div>`
            };
            var Register = {
                template: `<div>我是注册页面</div>`
            };

            // 3.创建路由对象
            var router = new VueRouter({
                // 4.配置路由对象
                routes: [
                    // 路由匹配的规则
                    {
                        path: '/login',
                        component: Login
                    },
                    {
                        path: '/register',
                        component: Register
                    }
                ]
            });

            // 4.使用两个全局的组件 router-link  router-view
            var App = {
                template: `
                    <div>
                        <!--router-link默认会被渲染成a标签,to默认会被渲染成href属性-->
                        <router-link to = '/login'>登录</router-link>
                        <router-link to = '/register'>注册</router-link>
                        
                        <!--路由组件的出口-->
                        <router-view></router-view>
                    </div>
                `
            }

            // Cannot read property 'matched' of undefined
            // 5.将配置好的路由对象关联到vue实例化对象中
            new Vue({
                el: '#app',
                router: router,
                template: `<App />`,
                components: {
                    App
                }
            });
        </script>
    </body>
</html>

如果 path 非常长的话,可以给路由的匹配规则起个别名,代码如下:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app"></div>
        <!-- 1.引入vue.js -->
        <script type="text/javascript" src="../js/vue.min.js"></script>
        <!-- 2.引入核心的插件vue-router -->
        <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script>
        <script type="text/javascript">
            // 2.让vue使用该VueRouter创建 如果vue是一个局部作用域的对象 那么必须Vue.use(VueRouter);
            // Vue.use(VueRouter);

            //声明组件
            var Login = {
                template: `<div>我是登录页面</div>`
            };
            var Register = {
                template: `<div>我是注册页面</div>`
            };
            // 3.创建路由对象

            var router = new VueRouter({
                // 4.配置路由对象
                routes: [
                    // 路由匹配的规则
                    {
                        path: '/login',
                        name: 'login',
                        component: Login
                    },
                    {
                        path: '/register',
                        name: 'register',
                        component: Register
                    }
                ]
            });

            // 4.抛出两个全局的组件 router-link  router-view
            var App = {
                template: `
                    <div>
                        <!--router-link默认会被渲染成a标签,to默认会被渲染成href属性-->
                        <router-link :to = "{name:'login'}">登录</router-link>
                        <router-link :to = "{name:'register'}">注册</router-link>
                        
                        <!--路由组件的出口-->
                        <router-view></router-view>
                    </div>
                `
            }

            // Cannot read property 'matched' of undefined
            // 5.将配置好的路由对象关联到vue实例化对象中
            new Vue({
                el: '#app',
                router: router,
                template: `<App />`,
                components: {
                    App
                }
            });
        </script>
    </body>
</html>

可以给路由绑定参数

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app"></div>
        <!-- 1.先引入vue.js -->
        <script type="text/javascript" src="../js/vue.min.js"></script>
        <!-- 2.引入核心的插件vue-router -->
        <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script>
        <script type="text/javascript">
            // 地址栏 路由范式

            //(1)xxxxx.html#/user/1    params 动态路由参数
            //(2)ooooo.html#/user?userId = 1  query


            // Vue.use(VueRouter);


            //声明组件  $router  $route (路由信息对象)
            var UserParams = {
                template: `<div>我是用户1</div>`,
                created() {
                    console.log(this.$router);
                    console.log(this.$route);
                }
            };
            var UserQuery = {
                template: `<div>我是用户2</div>`,
                created() {
                    console.log(this.$route);
                }
            };
            
            // 3.创建路由对象
            var router = new VueRouter({
                // 4.配置路由对象
                routes: [
                    // 路由匹配的规则
                    {
                        //动态路由参数 以冒号开头
                        path: '/user/:id',
                        name: 'userP',
                        component: UserParams
                    },
                    {
                        path: '/user',
                        name: 'userQ',
                        component: UserQuery
                    }
                ]
            });

            // 使用两个全局的组件 router-link  router-view
            var App = {
                template: `
                    <div>
                        <!--router-link默认会被渲染成a标签,to默认会被渲染成href属性-->
                        <router-link :to = "{name:'userP',params:{id:1}}">用户1</router-link>
                        <router-link :to = "{name:'userQ',query:{userId:2}}">用户2</router-link>
                        
                        <!--路由组件的出口-->
                        <router-view></router-view>
                    </div>
                `
            }

            // Cannot read property 'matched' of undefined
            // 5.将配置好的路由对象关联到vue实例化对象中
            new Vue({
                el: '#app',
                router: router,
                template: `<App />`,
                components: {
                    App
                }
            });
        </script>

    </body>
</html>

路由也可以嵌套使用

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app"></div>
        <!-- 1.先引入vue.js -->
        <script type="text/javascript" src="../js/vue.min.js"></script>
        <!-- 2.引入核心的插件vue-router -->
        <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script>
        <script type="text/javascript">
            // 地址栏 路由范式

            //(1)xxxxx.html#/user/1    params 动态路由参数
            //(2)ooooo.html#/user?userId = 1  query


            // Vue.use(VueRouter);


            //声明组件
            var Song = {
                template: `<div>我是歌曲组件</div>`,
                created() {
                    console.log(this.$router);
                    console.log(this.$route);
                }
            };
            var Movie = {
                template: `<div>电影组件</div>`,
                created() {
                    console.log(this.$route);
                }
            };
            // 3.创建路由对象

            // /home/song
            // /home/movie
            var Home = {
                template: `
                  <div>
                    首页内容
                    <br />

                    <router-link to = '/home/song'>歌曲</router-link>
                    <router-link to = '/home/movie'>电影</router-link>

                    <router-view></router-view>

                  </div>
                `
            };

            var router = new VueRouter({
                // 4.配置路由对象
                routes: [
                    // 路由匹配的规则
                    {
                        //动态路由参数 以冒号开头
                        path: '/home',
                        name: 'home',
                        component: Home,
                        children: [{
                                path: 'song',
                                component: Song
                            },
                            {
                                path: 'movie',
                                component: Movie
                            },

                        ]
                    }

                ]
            });

            // 使用两个全局的组件 router-link  router-view
            var App = {
                template: `
                <div>
                    <!--router-link默认会被渲染成a标签,to默认会被渲染成href属性-->
                    <router-link :to = "{name:'home'}">首页</router-link>
                    
                    <!--路由组件的出口-->
                    <router-view></router-view>
                </div>
            `
            }

            // Cannot read property 'matched' of undefined
            // 5.将配置好的路由对象关联到vue实例化对象中
            new Vue({
                el: '#app',
                router: router,
                template: `<App />`,
                components: {
                    App
                }
            });
        </script>
    </body>
</html>

动态路由匹配(地址栏中参数的变化和watch的使用)

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app"></div>
        <!-- 1.先引入vue.js -->
        <script type="text/javascript" src="../js/vue.min.js"></script>
        <!-- 2.引入核心的插件vue-router -->
        <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script>
        <script type="text/javascript">
            // 地址栏 路由范式

            //(1)xxxxx.html#/user/1    params 动态路由参数
            //(2)ooooo.html#/user?userId = 1  query

            // Vue.use(VueRouter);


            var ComDesc = {
                data() {
                    return {
                        msg: ''
                    }
                },
                template: `
                    <div>
                        {{ msg }}
                    </div>
                `,
                created() {
                    this.msg = 'andorid';
                    console.log(1);
                },
                watch: {
                    '$route'(to, from) {
                        // 对路由变化作出响应...
                        console.log(to);
                        console.log(from);

                        this.msg = to.params.id;
                    }
                }
            }
            
            // 3.创建路由对象
            // /timeline/andorid
            // /timeline/frontend
            var Timeline = {
                template: `
              <div id = 'timeline'>
                <router-link :to  ="{name:'comDesc',params:{id:'andorid'}}" >安卓</router-link>
                <router-link :to  ="{name:'comDesc',params:{id:'frontend'}}">前端</router-link>

                <router-view></router-view>

              </div>
            `
            };

            var Pins = {
                template: `
                <div>我是沸点</div>
                `
            }

            var router = new VueRouter({
                // 4.配置路由对象
                routes: [
                    // 路由匹配的规则
                    {
                        //动态路由参数 以冒号开头
                        path: '/timeline',
                        name: 'timeline',
                        component: Timeline,
                        children: [{
                                name: 'comDesc',
                                path: '/timeline/:id',
                                component: ComDesc
                            }

                        ]
                    },
                    {
                        path: '/pins',
                        component: Pins
                    }

                ]
            });

            // 使用两个全局的组件 router-link  router-view
            var App = {
                template: `
                    <div>
                        <!--router-link默认会被渲染成a标签,to默认会被渲染成href属性-->
                        <router-link to = '/timeline'>首页</router-link>
                        <router-link to = '/pins'>沸点</router-link>
                        
                        
                        <!--路由组件的出口-->
                        <router-view></router-view>
                    </div>
                `
            }

            // Cannot read property 'matched' of undefined
            // 5.将配置好的路由对象关联到vue实例化对象中
            new Vue({
                el: '#app',
                router: router,
                template: `<App />`,
                components: {
                    App
                }
            });
        </script>
    </body>
</html>

meta和全局路由的渲染前配置

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <!-- 声明式的导航 -->
            <router-link to='/home'>首页</router-link>
            <router-link to='/blog'>我的博客</router-link>
            <router-link to='/login'>登录</router-link>
            <a href="javascript:void(0);" @click='clear'>退出</a>
            <router-view></router-view>

        </div>
        <script type="text/javascript" src="../js/vue.min.js"></script>
        <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script>

        <script type="text/javascript">
            Vue.use(VueRouter);

            var Home = {
                template: `
                   <div>
                    我是首页
                   </div>
                `
            };
            var Blog = {
                template: `
                   <div>
                    我是博客
                   </div>
                `
            };
            var Login = {
                data() {
                    return {
                        name: '',
                        pwd: ''
                    }
                },
                template: `
                   <div>
                    <input type="text" v-model ='name'/>
                    <input type="text"  v-mode  = 'pwd'/>
                    <input type="button"  value ='登录' @click = 'login'/>
                   </div>
                `,
                methods: {
                    login() {
                        localStorage.setItem('user', {
                            name: this.name,
                            pwd: this.pwd
                        });


                        // 编程式导航
                        this.$router.push({
                            name: 'blog'
                        });
                    }
                }
            };

            var router = new VueRouter({
                routes: [{
                        path: '/',
                        redirect: '/home'
                    },
                    {
                        path: '/home',
                        component: Home
                    },
                    {
                        name: 'blog',
                        path: '/blog',
                        component: Blog,
                        // 给未来路由 做权限控制 全局路由守卫 来做参照条件
                        meta: {
                            // 表明用户访问该组件是需要登录,auth是自定义的参数
                            auth: true
                        }
                    },
                    {
                        path: '/login',
                        component: Login
                    }

                ]
            });

            router.beforeEach((to, from, next) => {
                console.log(to);
                console.log(from);

                if (to.meta.auth) { //用户点击了博客链接 该用户未登录 需要登录判断 准备跳转登录页面

                    if (localStorage.getItem('user')) {
                        // alert(1);
                        // 不为空 放行
                        next();
                    } else {
                        // alert(2);
                        // 用户需要登录
                        next({
                            path: '/login'
                        });
                    }


                } else {
                    // 直接放行
                    next(); //如果不调用next 就会卡住
                }
            });

            new Vue({
                el: '#app',
                router,
                methods: {
                    clear() {
                        localStorage.removeItem('user');
                        this.$router.push('/login');
                    }
                }
            });
        </script>
    </body>
</html>

keep-alive在路由中的使用

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
        </div>
        
        <script type="text/javascript" src="../js/vue.min.js"></script>
        <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script>

        <script type="text/javascript">
            Vue.use(VueRouter);

            var Series = {
                template: `
                    <div>付费栏目</div>
                `,
                created() {
                    console.log('付费栏目组件created');
                },
                mounted() {
                    console.log('付费栏目组件mounted');
                },
                destroyed() {
                    console.log('付费栏目组件被销毁了')
                }
            };
            var Topics = {
                template: `
                    <div>
                        <h3 @click = 'clickHandler'>我是专题广场</h3>
                    </div>
                `,
                methods: {
                    clickHandler(e) {
                        e.target.style.color = 'red';
                    }
                },
                created() {
                    console.log('专题广场组件created');
                },
                mounted() {
                    console.log('专题广场组件mounted');
                },
                destroyed() {
                    console.log('专题广场组件被销毁了')
                }
            };

            var router = new VueRouter({
                routes: [{
                        path: '/series',
                        component: Series
                    },
                    {
                        path: '/topics',
                        component: Topics
                    },
                ]
            });

            var App = {
                template: `
                    <div>
                        <router-link to = '/series'>付费栏目</router-link>
                        <router-link to = '/topics'>专题广场</router-link>
                        
                        <keep-alive>
                            <router-view></router-view>
                        </keep-alive>
                    </div>
                `
            }

            new Vue({
                el: '#app',
                template: `<App />`,
                components: {
                    App
                },
                router
            });
        </script>
    </body>
</html>
原文地址:https://www.cnblogs.com/jwen1994/p/10988481.html