Vue路由系统

一切分离都是为了更好的结合,本文详细介绍了前后端分离架构之后,前端如何实现路由控制,即Vue路由系统。

一、VueRouter实现原理

VueRouter的实现原理是根据监控锚点值的改变,从而不断修改组件内容来实现的,我们来试试不使用VueRouter,自己实现路由控制,如下代码:

<!DOCTYPE html>
<html >
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="../statics/vue.min.js"></script>
  <script src="../statics/vue-router.js"></script>
  <style>
    body {
      margin: 0;
    }
    .login {
      width: 100%;
      height: 1200px;
      background-color: #0FC57C;
    }
    .register {
      width: 100%;
      height: 1200px;
      background-color: yellow;
    }
    .home {
      width: 100%;
      height: 1200px;
      background-color: #2aabd2;
    }
    a {
      text-decoration: none;
    }
  </style>
</head>
<body>

    <div >
      <a href="#/home">首页</a>
      <a href="#/login">登录</a>
      <a href="#/register">注册</a>
    </div>

    <script>
        let oDiv = document.getElementById("app");

        window.onhashchange = function () {
            console.log(location.hash);
            // vue-router的实现原理是根据锚点值的改变
            // 对页面进行切换
            switch (location.hash) {
                case "#/login":
                    oDiv.innerHTML = `<h3 class='login'>这是登录页面</h3>`;
                    break;
                case "#/register":
                    oDiv.innerHTML = `<h3 class='register'>这是注册页面</h3>`;
                    break;
                default:
                    oDiv.innerHTML = `<h3 class='home'>这是首页</h3>`;
                    break;
            }
        };
    </script>

</body>
</html>

可以看到,通过监控锚点值的改变,页面上面的内容可以跳转到我们需要显示的页面。

二、VueRouter安装使用

<!DOCTYPE html>
<html >
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="../statics/vue.min.js"></script>
  <!--1. 引入vue-router-->
  <script src="../statics/vue-router.js"></script>
</head>
<body>

  <div >

  </div>

  <script>
    let Home = {
      template: `
        <div>这是首页</div>
      `
    };

    let Login = {
      template: `
          <div>登录页面</div>
      `
    };

      let Register = {
        template: `
            <div>注册页面</div>
        `
      };

      let App = {
        template: `
          <div>
            <router-link to="/home">首页</router-link>
            <router-link to="/login">登录</router-link>
            <router-link to="/register">注册</router-link>

            <router-view></router-view>
          </div>
        `
      };

      // 2. 在vue中中使用vue-router对象
      Vue.use(VueRouter);

      // 3. 创建一个vue-router对象
      let router = new VueRouter({
        // 此处要特别注意是routes,不是routers
        routes: [
          {
            path: '/home',
            component: Home,
          },
            {
              path: "/login",
              component: Login
            },
            {
              path: "/register",
              component: Register,
            }
        ]
      });

      // 4. 在vue实例中使用新创建的vue-router对象
      new Vue({
        el: "#app",
        template: `<app></app>`,
        components: {
          "app": App,
        },
        router: router
      })
  </script>

</body>
</html>

三、VueRouter命名路由

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../statics/vue.min.js"></script>
    <!--1. 引入vue-router-->
    <script src="../statics/vue-router.js"></script>
</head>
<body>

    <div ></div>

    <script>
        let Login = {
            template: `
                <div>登录页面</div>
            `
        };

        let Register = {
            template: `
                <div>注册页面</div>
            `
        };

        let App = {
            template: `
                <div>
                    <router-link :to="{ name: 'login'}">登录</router-link>
                    <router-link :to="{ name: 'register'}">注册</router-link>

                    <router-view></router-view>
                </div>
            `
        };

        // 在vue中中使用vue-router对象
        Vue.use(VueRouter);

        // 创建一个vue-router对象
        let router = new VueRouter({
            // 此处要特别注意是routes,不是routers
            routes: [
                {
                    name: 'login',
                    path: "/login",
                    component: Login
                },
                {
                    name: 'register',
                    path: "/register",
                    component: Register,
                }
            ]
        });

        // 在vue实例中使用新创建的vue-router对象
        new Vue({
            el: "#app",
            template: `<app></app>`,
            components: {
                "app": App,
            },
            router: router
        })
    </script>

</body>
</html>

此外,还有另一种命名路由方式,如下所示:

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../statics/vue.min.js"></script>
    <!--1. 引入vue-router-->
    <script src="../statics/vue-router.js"></script>
</head>
<body>

    <div ></div>

    <script>
        let App = {
            template: `
                <div>
                    <router-link to="/">首页</router-link>

                    <router-view name="header"></router-view>
                    <router-view name="footer"></router-view>
                </div>
            `
        };

        Vue.use(VueRouter);

        let router = new VueRouter({
            routes: [
                {
                    path: '/',
                    components: {
                        header: {
                            template: `
                                <div>头部</div>
                            `
                        },
                        footer: {
                            template: `
                                <div>底部</div>
                            `
                        }
                    }
                }
            ]
        });

        new Vue({
            el: "#app",
            template: `<app></app>`,
            router: router,
            components: {
                'app': App
            }
        })
    </script>

</body>
</html>

四、VueRouter路由中使用参数

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../statics/vue.min.js"></script>
    <!--1. 引入vue-router-->
    <script src="../statics/vue-router.js"></script>
</head>
<body>

    <div ></div>

    <script>
        // 常用的两种查询方式
        // xxx.html/user/1
        // xxx.html/user/id=1

        let userParams = {
            template: `
                <div>用户一信息</div>
            `
        };

        let userQuery = {
            template: `
                <div>用户二信息</div>
            `
        };

        let App = {
            template: `
                <div>
                    <router-link :to="{ name: 'userParams', params: { userId: 1} }">用户一</router-link>
                    <router-link :to="{ name: 'userQuery', query: { userId: 2 } }">用户二</router-link>

                    <router-view></router-view>

                </div>
            `,
        };

        // 在vue中使用vue-router
        Vue.use(VueRouter);

        // 创建一个VueRouter对象
        let router = new VueRouter({
            routes: [
                {
                    name: 'userParams',
                    path: '/users/:userId',
                    component: userParams
                },
                {
                    name: 'userQuery',
                    path: '/users',
                    component: userQuery,
                }
            ]
        });

        // 在vue中使用vue-router
        new Vue({
            el: "#app",
            template: `<app></app>`,
            components: {
                'app': App,
            },
            router: router
        })
    </script>

</body>
</html>

五、VueRouter参数实现原理

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../statics/vue.min.js"></script>
    <!--1. 引入vue-router-->
    <script src="../statics/vue-router.js"></script>
</head>
<body>

    <div ></div>

    <script>
        // 常用的两种查询方式
        // xxx.html/user/1
        // xxx.html/user/id=1

        let userParams = {
            template: `
                <div>用户一信息</div>
            `,
            created () {
              console.log('this: ', this);
              console.log(this.$route);
              console.log(this.$route.params.userId);
            }
        };

        let userQuery = {
            template: `
                <div>用户二信息</div>
            `,
            created () {
              console.log(this.$route);
              console.log(this.$route.query.userId);
            }
        };

        let App = {
            template: `
                <div>
                    <router-link :to="{ name: 'userParams', params: { userId: 1} }">用户一</router-link>
                    <router-link :to="{ name: 'userQuery', query: { userId: 2 } }">用户二</router-link>

                    <router-view></router-view>

                </div>
            `,
        };

        // 在vue中使用vue-router
        Vue.use(VueRouter);

        // 创建一个VueRouter对象
        let router = new VueRouter({
            routes: [
                {
                    name: 'userParams',
                    path: '/users/:userId',
                    component: userParams
                },
                {
                    name: 'userQuery',
                    path: '/users',
                    component: userQuery,
                }
            ]
        });

        // 在vue中使用vue-router
        new Vue({
            el: "#app",
            template: `<app></app>`,
            components: {
                'app': App,
            },
            router: router,
          created () {
              console.log('this: ', this);
              console.log(this.$route);
            }
        })
    </script>

</body>
</html>

六、VueRouter子路由

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .home {
            width: 500px;
            height: 500px;
            background-color: #0FC57C;
        }
        .courses {
            width: 500px;
            height: 500px;
            background-color: #5b80b2;
        }

    </style>
    <script src="../statics/vue.min.js"></script>
    <!--1. 引入vue-router-->
    <script src="../statics/vue-router.js"></script>
</head>
<body>

    <div ></div>

    <script>
        let Home = {
            template: `
                <div class="home">这是首页</div>
            `
        };

        let Courses = {
            template: `
                <div class="courses">课程页面
                    <div class="details">
                        <router-link to="details">课程详情</router-link>
                        <router-link to="students">学员故事</router-link>

                        <router-view></router-view>
                    </div>
                </div>
            `
        };

        let Details = {
            template: `
                <div>课程详情页</div>
            `
        };

        let Students = {
            template: `
                <div>学员故事</div>
            `
        };

        let App = {
            template: `
                <div>
                    <router-link to="/">首页</router-link>
                    <router-link to="/courses">课程页面</router-link>

                    <router-view></router-view>
                </div>
            `
        };

        let routes = [
            {
                path: '/',
                component: Home
            },
            {
                path: '/courses',
                component: Courses,
                children: [
                    {
                        path: 'details',
                        component: Details,
                    },
                    {
                        path: 'students',
                        component: Students
                    }
                ]
            }
        ];

        Vue.use(VueRouter);

        let router = new VueRouter({
            routes: routes,
        });

        new Vue({
            el: "#app",
            template: `<app></app>`,
            router: router,
            components: {
                'app': App,
            }
        })

    </script>

</body>
</html>

七、VueRouter子路由append

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .home {
            width: 500px;
            height: 500px;
            background-color: #0FC57C;
        }
        .courses {
            width: 500px;
            height: 500px;
            background-color: #5b80b2;
        }

    </style>
    <script src="../statics/vue.min.js"></script>
    <!--1. 引入vue-router-->
    <script src="../statics/vue-router.js"></script>
</head>
<body>

    <div ></div>

    <script>
        let Home = {
            template: `
                <div class="home">这是首页</div>
            `
        };

        let Courses = {
            template: `
                <div class="courses">课程页面
                    <div class="details">
                        <router-link to="details" append>课程详情</router-link>
                        <router-link to="students">学员故事</router-link>

                        <router-view></router-view>
                    </div>
                </div>
            `
        };

        let Details = {
            template: `
                <div>课程详情页</div>
            `
        };

        let Students = {
            template: `
                <div>学员故事</div>
            `
        };

        let App = {
            template: `
                <div>
                    <router-link to="/">首页</router-link>
                    <router-link to="/courses">课程页面</router-link>

                    <router-view></router-view>
                </div>
            `
        };

        let routes = [
            {
                path: '/',
                component: Home
            },
            {
                path: '/courses',
                component: Courses,
                children: [
                    {
                        path: 'details',
                        component: Details,
                    },
                    {
                        path: 'students',
                        component: Students
                    }
                ]
            }
        ];

        Vue.use(VueRouter);

        let router = new VueRouter({
            routes: routes,
        });

        new Vue({
            el: "#app",
            template: `<app></app>`,
            router: router,
            components: {
                'app': App,
            }
        })

    </script>

</body>
</html>

使用以上方式,路径是写死在属性中的,所以子路径会不断的append到最后,导致访问不到相应页面。可以采用另一种,动态绑定属性,如下代码所示:

<!DOCTYPE html>
<html >
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="../statics/vue.min.js"></script>
  <script src="../statics/vue-router.js"></script>
  <style>
    body {
      margin: 0;
    }
    .all {
      width: 500px;
      height: 500px;
    }
    .home {
      background-color: #2aabd2;
    }
    .login {
      background-color: #7acce4;
    }
    .register {
      background-color: #4cae4c;
    }
    .courses {
      background-color: #0FC57C;
    }
  </style>
</head>
<body>

  <div ></div>

  <script>
    Vue.use(VueRouter);

    let Home = {
      template: `
        <div class="home all">
          <h1>这是首页页面</h1>
        </div>
      `
    };

    let Login = {
      template: `
        <div class="login all">
          <h1>这是登录页面</h1>
        </div>
      `
    };

    let Register = {
      template: `
        <div class="register all">
          <h1>这是注册页面</h1>
        </div>
      `
    };

    let Courses = {
      template: `
        <div class="courses all">
          <h1>这是课程页面</h1>
          <router-link :to="{ name: 'lightcourses' }" append>轻课</router-link>
          <router-link :to="{ name: 'degreecourses' }">学位课</router-link>

          <router-view><router-view>
        </div>
      `
    };

    let LightCourses = {
      template: `
        <div>
          <h1>这是学位课程页面</h1>
        </div>
      `
    };

    let DegreeCourses = {
      template: `
        <div>
          <h1>这是轻课课程页面</h1>
        </div>
      `
    };

    let App = {
      template: `
        <div>
          <router-link :to="{ name: 'home' }">首页</router-link>
          <router-link :to="{ name: 'login' }">登录</router-link>
          <router-link :to="{ name: 'register' }">注册</router-link>
          <router-link :to="{ name: 'courses' }">课程</router-link>

          <router-view><router-view>
        </div>
      `,
    };

    let routes = [
      {
        name: 'home',
        path: '/home',
        component: Home,
      },
      {
        name: 'login',
        path: '/login',
        component: Login,
      },
      {
        name: 'register',
        path: '/register',
        component: Register
      },
      {
        name: 'courses',
        path: '/courses',
        component: Courses,
        children: [
          {
            name: 'lightcourses',
            path: 'lightcourses',
            component: LightCourses
          },
          {
            name: 'degreecourses',
            path: 'degreecourses',
            component: DegreeCourses
          }
        ]
      }
    ];

    let router = new VueRouter({
      routes: routes,
      mode: 'history',
    });

    new Vue({
      el: "#app",
      template: `<App></App>`,
      components: {
        App,
      },
      router: router,
    })
  </script>

</body>
</html>

注意,必须使用name查找组件和路径的对应关系,而不能使用path。

八、VueRouter子路由非append

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .home {
            width: 500px;
            height: 500px;
            background-color: #0FC57C;
        }
        .courses {
            width: 500px;
            height: 500px;
            background-color: #5b80b2;
        }

    </style>
    <script src="../statics/vue.min.js"></script>
    <!--1. 引入vue-router-->
    <script src="../statics/vue-router.js"></script>
</head>
<body>

    <div ></div>

    <script>
        let Home = {
            template: `
                <div class="home">这是首页</div>
            `
        };

        let Courses = {
            template: `
                <div class="courses">课程页面
                    <div class="details">
                        <router-link to="/courses/details">课程详情</router-link>
                        <router-link to="/courses/students">学员故事</router-link>

                        <router-view></router-view>
                    </div>
                </div>
            `
        };

        let Details = {
            template: `
                <div>课程详情页</div>
            `
        };

        let Students = {
            template: `
                <div>学员故事</div>
            `
        };

        let App = {
            template: `
                <div>
                    <router-link to="/">首页</router-link>
                    <router-link to="/courses">课程页面</router-link>

                    <router-view></router-view>
                </div>
            `
        };

        let routes = [
            {
                path: '/',
                component: Home
            },
            {
                path: '/courses',
                component: Courses,
                children: [
                    {
                        path: '/courses/details',
                        component: Details,
                    },
                    {
                        path: '/courses/students',
                        component: Students
                    }
                ]
            }
        ];

        Vue.use(VueRouter);

        let router = new VueRouter({
            routes: routes,
        });

        new Vue({
            el: "#app",
            template: `<app></app>`,
            router: router,
            components: {
                'app': App,
            }
        })

    </script>

</body>
</html>

九、VueRouter路由重定向redirect

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .home {
            width: 500px;
            height: 500px;
            background-color: #0FC57C;
        }
        .login {
            width: 500px;
            height: 500px;
            background-color: #5b80b2;
        }

    </style>
    <script src="../statics/vue.min.js"></script>
    <!--1. 引入vue-router-->
    <script src="../statics/vue-router.js"></script>
</head>
<body>

    <div ></div>

    <script>
        let Home = {
            template: `
                <div class="home">这是首页</div>
            `
        };

        let Login = {
            template: `
                <div class="login">这是登录页面</div>
            `
        };

        let Details = {
            template: `
                <div>课程详情页</div>
            `
        };

        let App = {
            template: `
                <div>
                    <router-link to="/">首页</router-link>
                    <router-link to="/login">登录页面</router-link>
                    <router-link to="/details">课程详情页</router-link>

                    <router-view></router-view>
                </div>
            `
        };

        let routes = [
            {
                path: '/',
                component: Home
            },
            {
                path: '/login',
                component: Login,
            },
            {
                path: '/details',
                redirect: '/login',
                component: Details
            }
        ];

        Vue.use(VueRouter);

        let router = new VueRouter({
            routes: routes,
        });

        new Vue({
            el: "#app",
            template: `<app></app>`,
            router: router,
            components: {
                'app': App,
            }
        })

    </script>

</body>
</html>

十、VueRouter手动路由

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .home {
            width: 500px;
            height: 500px;
            background-color: #0FC57C;
        }
        .details {
            width: 500px;
            height: 500px;
            background-color: #5b80b2;
        }
    </style>
    <script src="../statics/vue.min.js"></script>
    <!--1. 引入vue-router-->
    <script src="../statics/vue-router.js"></script>
</head>
<body>

    <div ></div>

    <script>
        let Home = {
            template: `
                <div>
                    <div class="home">这是首页</div>
                </div>
            `,
        };

        let Details = {
            template: `
                <div class="details">课程详情页</div>
            `
        };

        let App = {
            template: `
                <div>
                    <router-link to="/">首页</router-link>
                    <button @click="myClick">点击跳转到课程详情页面</button>

                    <router-view></router-view>
                </div>
            `,
            methods: {
                myClick: function () {
                    this.$router.push('/details');
                }
            }
        };

        let routes = [
            {
                path: '/',
                component: Home
            },
            {
                path: '/details',
                component: Details
            }
        ];

        Vue.use(VueRouter);

        let router = new VueRouter({
            routes: routes,
        });

        new Vue({
            el: "#app",
            template: `<app></app>`,
            router: router,
            components: {
                'app': App,
            }
        })

    </script>

</body>
</html>

十一、VueRouter路由钩子

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .home {
            width: 500px;
            height: 500px;
            background-color: #0FC57C;
        }
        .login {
            width: 500px;
            height: 500px;
            background-color: #5b80b2;
        }
        .user {
            width: 500px;
            height: 500px;
            background-color: #5b80b2;
        }

    </style>
    <script src="../statics/vue.min.js"></script>
    <!--1. 引入vue-router-->
    <script src="../statics/vue-router.js"></script>
</head>
<body>

    <div ></div>

    <script>
        let homePage = {
            template: `
                <div class="home"><h3>这是首页</h3></div>
            `
        };

        let loginPage = {
            template: `
                <div class="login"><h3>这是登录页面</h3></div>
            `
        };

        let userPage = {
            template: `
                <div class="user"><h3>这是用户管理页面</h3></div>
            `
        };

        let App = {
            template: `
                <div>
                    <router-link to="/">首页</router-link>
                    <router-link to="/login">登录</router-link>
                    <router-link to="userinfo">用户</router-link>

                    <router-view></router-view>
                </div>
            `
        };

        let routes = [
            {
                path: '/',
                component: homePage
            },
            {
                path: '/login',
                component: loginPage,
            },
            {
                path: '/userinfo',
                component: userPage,
            }
        ];

        Vue.use(VueRouter);

        let router = new VueRouter({
            routes: routes,
        });

        router.beforeEach(function (to, from, next) {
            // 如果next的参数是具体的路径,则跳转到该路径
            // 如果next没有被传入参数,则什么都不做,保持原来不变
            // 如果next的参数是一个error实例,跳转终止
            next();
        });

        new Vue({
            el: "#app",
            template: `<app></app>`,
            components: {
                'app': App
            },
            router: router,
        })
    </script>

</body>
</html>

十二、VueRouter在路径中去掉#号

在创建路由实例时,我们可以新增一个属性,该属性用来去掉在路径中显示#号,它的属性名为mode,属性值为’history’

<!DOCTYPE html>
<html >
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="../statics/vue.min.js"></script>
  <script src="../statics/vue-router.js"></script>
  <style>
    body {
      margin: 0;
    }
    .box {
      line-height: 100px;
      text-align: center;
    }
    .home {
      background-color: #2aabd2;
      width: 500px;
      height: 500px;
    }
    .login {
      background-color: #2b9b2d;
      width: 500px;
      height: 500px;
    }
    .register {
      background-color: #4cae4c;
      width: 500px;
      height: 500px;
    }
  </style>
</head>
<body>

  <div ></div>

  <script>
    Vue.use(VueRouter);

    let Home = {
      template: `
        <div class="home">
          <h1>这是首页页面</h1>
        </div>
      `
    };

    let Login = {
      template: `
        <div class="login">
          <h1>这是登录页面</h1>
        </div>
      `
    };

    let Register = {
      template: `
        <div class="register">
          <h1>这是注册页面</h1>
        </div>
      `
    };

    let App = {
      template: `
        <div>
          <router-link :to="{ name: 'home' }">首页</router-link>
          <router-link :to="{ name: 'login' }">登录</router-link>
          <router-link :to="{ name: 'register' }">注册</router-link>

          <router-view><router-view>
        </div>
      `,
    };

    let routes = [
      {
        name: 'home',
        path: '/home',
        component: Home,
      },
      {
        name: 'login',
        path: '/login',
        component: Login,
      },
      {
        name: 'register',
        path: '/register',
        component: Register
      }
    ];

    let router = new VueRouter({
      routes: routes,
      mode: 'history',
    });

    new Vue({
      el: "#app",
      template: `<App></App>`,
      components: {
        App,
      },
      router: router,
    })
  </script>

</body>
</html>