美文网首页
05Vue的前端路由

05Vue的前端路由

作者: 攻城老狮 | 来源:发表于2021-02-02 10:05 被阅读0次

Vue的前端路由


一 路由基本概念

路由的本质就是对应关系。

路由可分为:

  • 后端路由:URL请求地址与服务器资源之间的对应关系。
image-20210127111943936.png
  • 前端路由:用户事件与事件处理函数之间的对应关系。
image-20210127112121083.png

二 手写路由

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <!-- 导入 vue 文件 -->
    <script src="./js/vue.js"></script>
  </head>
  <body>
    <!-- 被 vue 实例控制的 div 区域 -->
    <div id="app">
      <!-- 切换组件的超链接 -->
      <a href="#/zhuye">主页</a> 
      <a href="#/keji">科技</a> 
      <a href="#/caijing">财经</a>
      <a href="#/yule">娱乐</a>

      <!-- 根据 :is 属性指定的组件名称,把对应的组件渲染到 component 标签所在的位置 -->
      <!-- 可以把 component 标签当做是【组件的占位符】 -->
      <component :is="comName"></component>
    </div>

    <script>
      // #region 定义需要被切换的 4 个组件
      // 主页组件
      const zhuye = {
        template: '<h1>主页信息</h1>'
      }

      // 科技组件
      const keji = {
        template: '<h1>科技信息</h1>'
      }

      // 财经组件
      const caijing = {
        template: '<h1>财经信息</h1>'
      }

      // 娱乐组件
      const yule = {
        template: '<h1>娱乐信息</h1>'
      }
      // #endregion

      // #region vue 实例对象
      const vm = new Vue({
        el: '#app',
        data: {
          comName: 'zhuye'
        },
        // 注册私有组件
        components: {
          "zhuye":zhuye,
          "keji":keji,
          "caijing":caijing,
          "yule":yule
        }
      })
      // #endregion

      // 监听 window 的 onhashchange 事件,根据获取到的最新的 hash 值,切换要显示的组件的名称
      window.onhashchange = function() {
        // 通过 location.hash 获取到最新的 hash 值
        console.log(location.hash);
        switch(location.hash.slice(1)){
          case '/zhuye':
            vm.comName = 'zhuye'
          break
          case '/keji':
            vm.comName = 'keji'
          break
          case '/caijing':
            vm.comName = 'caijing'
          break
          case '/yule':
            vm.comName = 'yule'
          break
        }
      }
    </script>
  </body>
</html>

三 Vue-Router使用

3.1 基本使用步骤

路由的使用一共分为六步

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <script src="./js/vue_2.5.22.js"></script>
    <!-- 1.导入Vue-router组件 -->
    <script src="./js/vue-router_3.0.2.js"></script>
  </head>
  <body>
    <div id="app">
        <!-- 2.添加路由链接 -->
        <router-link to="/user">User</router-link>
        <router-link to="/register">Register</router-link>

        <!-- 3.路由占位符 -->
        <router-view></router-view>
    </div>

    <script>
        // 4.定义路由组件
        var User = {
            template: '<h1>用户组件</h1>'
        };
        var Register = {
            template: '<h1>注册组件</h1>'
        };

        // 5.配置路由规则
        var router = new VueRouter({
            routes: [
                {path:"/user",component:User},
                {path:"/register",component:Register}
            ]
        });

        // 6.路由挂载到Vue
        var vm = new Vue({
            el:"#app",
            data:{},
            router:router
        });
    </script>
  </body>
</html>

3.2 路由重定向

路由重定向操作,将访问根路径时候,重定向到访问/user路径

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <script src="./js/vue_2.5.22.js"></script>
    <script src="./js/vue-router_3.0.2.js"></script>
  </head>
  <body>
    <div id="app">
        <router-link to="/user">User</router-link>
        <router-link to="/register">Register</router-link>

        <router-view></router-view>
    </div>

    <script>
        var User = {
            template: '<h1>用户组件</h1>'
        };
        var Register = {
            template: '<h1>注册组件</h1>'
        };

        var router = new VueRouter({
            routes: [
                // 路由重定向操作,将访问根路径时候,重定向到访问/user路径
                {path:"/",redirect:"/user"},
                {path:"/user",component:User},
                {path:"/register",component:Register}
            ]
        });

        var vm = new Vue({
            el:"#app",
            data:{},
            router:router
        });
    </script>
  </body>
</html>

3.3 嵌套路由

在Register这个父组件中,加入Tab1和Tab2两个子组件

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <script src="./js/vue_2.5.22.js"></script>
    <script src="./js/vue-router_3.0.2.js"></script>
  </head>
  <body>
    <div id="app">
        <router-link to="/user">User</router-link>
        <router-link to="/register">Register</router-link>

        <router-view></router-view>
    </div>

    <script>
        var User = {
            template: '<h1>用户组件</h1>'
        };
        var Register = {
            template: `
            <div>
                <h1>注册组件</h1>
                <hr/>
                <router-link to="/register/tab1">Tab1</router-link>
                <router-link to="/register/tab2">Tab2</router-link>
                <router-view></router-view>
            </div>
            `
        };
        var Tab1 = {
            template: "<h3>Tab1</h3>"
        };
        var Tab2 = {
            template: "<h3>Tab2</h3>"
        };

        var router = new VueRouter({
            routes: [
                {path:"/",redirect:"/user"},
                {path:"/user",component:User},
                {path:"/register",component:Register,children:[
                    {path:"/register/tab1",component:Tab1},
                    {path:"/register/tab2",component:Tab2}
                ]}
            ]
        });

        var vm = new Vue({
            el:"#app",
            data:{},
            router:router
        });
    </script>
  </body>
</html>

3.4 动态路由

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <script src="./js/vue_2.5.22.js"></script>
    <script src="./js/vue-router_3.0.2.js"></script>
  </head>
  <body>
    <div id="app">
        <!-- 定义多个链接 -->
        <router-link to="/user/1">User1</router-link>
        <router-link to="/user/2">User2</router-link>
        <router-link to="/user/3">User3</router-link>

        <router-view></router-view>
    </div>

    <script>
        var User = {
            //获取动态的路由数据
            template: '<h1>用户组件,id:{{$route.params.id}}</h1>'
        };

        var router = new VueRouter({
            routes: [
                //动态部分
                {path:"/user/:id",component:User},
            ]
        });

        var vm = new Vue({
            el:"#app",
            data:{},
            router:router
        });
    </script>
  </body>
</html>

3.5 路由组件传递参数

$route与对应路由高度耦合,需要进行改进props的形式解除组件和路由之间的耦合关系。

  • props的值为布尔类型(常用,用于接收路径中的动态参数)
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <script src="./js/vue_2.5.22.js"></script>
    <script src="./js/vue-router_3.0.2.js"></script>
  </head>
  <body>
    <div id="app">
        <!-- 定义多个链接 -->
        <router-link to="/user/1">User1</router-link>
        <router-link to="/user/2">User2</router-link>
        <router-link to="/user/3">User3</router-link>

        <router-view></router-view>
    </div>

    <script>
        var User = {
            //props接收参数
            props:["id"],
            template: '<h1>用户组件,id:{{id}}</h1>'
        };

        var router = new VueRouter({
            routes: [
                //增加props的布尔值开启
                {path:"/user/:id",component:User,props:true},
            ]
        });

        var vm = new Vue({
            el:"#app",
            data:{},
            router:router
        });
    </script>
  </body>
</html>
  • props的值为对象类型(用于传递静态参数,此时无法传递路径中的动态参数)
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <script src="./js/vue_2.5.22.js"></script>
    <script src="./js/vue-router_3.0.2.js"></script>
  </head>
  <body>
    <div id="app">
        <!-- 定义多个链接 -->
        <router-link to="/user/1">User1</router-link>
        <router-link to="/user/2">User2</router-link>
        <router-link to="/user/3">User3</router-link>

        <router-view></router-view>
    </div>

    <script>
        var User = {
            //props接收静态参数
            props:["uname","age"],
            template: '<h1>用户组件,姓名:{{uname}},年龄:{{age}}</h1>'
        };

        var router = new VueRouter({
            routes: [
                //传递静态参数
                {path:"/user/:id",component:User,props:{uname:"yorick",age:23}},
            ]
        });

        var vm = new Vue({
            el:"#app",
            data:{},
            router:router
        });
    </script>
  </body>
</html>
  • props的值为函数类型(既可以传递静态参数,也可以传递动态参数)
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <script src="./js/vue_2.5.22.js"></script>
    <script src="./js/vue-router_3.0.2.js"></script>
  </head>
  <body>
    <div id="app">
        <!-- 定义多个链接 -->
        <router-link to="/user/1">User1</router-link>
        <router-link to="/user/2">User2</router-link>
        <router-link to="/user/3">User3</router-link>

        <router-view></router-view>
    </div>

    <script>
        var User = {
            //props接收静态和动态参数
            props:["id","uname","age"],
            template: '<h1>用户组件,id:{{id}},姓名:{{uname}},年龄:{{age}}</h1>'
        };

        var router = new VueRouter({
            routes: [
                //传递静态参数和动态参数
                {path:"/user/:id",component:User,props:route=>({uname:"yorick",age:"23",id:route.params.id})},
            ]
        });

        var vm = new Vue({
            el:"#app",
            data:{},
            router:router
        });
    </script>
  </body>
</html>

3.6 命名路由

通过给路由起名字,使用该名称来作为链接的传递形式。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <script src="./js/vue_2.5.22.js"></script>
    <script src="./js/vue-router_3.0.2.js"></script>
  </head>
  <body>
    <div id="app">
        <router-link to="/user/1">User1</router-link>
        <router-link to="/user/2">User2</router-link>
        <!-- 改为命名路由的链接形式 -->
        <router-link :to="{name:'user',params:{id:3}}">User3</router-link>

        <router-view></router-view>
    </div>

    <script>
        var User = {
            props:["id"],
            template: '<h1>用户组件,id:{{id}}</h1>'
        };

        var router = new VueRouter({
            routes: [
                //添加路由的name
                {name:"user",path:"/user/:id",component:User,props:true},
            ]
        });

        var vm = new Vue({
            el:"#app",
            data:{},
            router:router
        });
    </script>
  </body>
</html>

3.7 编程式导航

image-20210127144324697.png
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <script src="./js/vue_2.5.22.js"></script>
    <script src="./js/vue-router_3.0.2.js"></script>
  </head>
  <body>
    <div id="app">
        <router-link to="/user">User</router-link>
        <router-link to="/register">Register</router-link>

        <router-view></router-view>
    </div>

    <script>
        var User = {
            template: `
            <div>
                <h1>用户组件</h1>
                <button @click="goRegister">跳转到注册页面</button>
            </div>
            `,
            methods: {
                goRegister: function(){
                    this.$router.push("/register");
                }
            }
        };
        var Register = {
            template: `
            <div>
                <h1>注册组件</h1>
                <button @click="goBack">回退</button>
            </div>
            `,
            methods: {
                goBack: function(){
                    this.$router.go(-1);
                }
            }
        };

        var router = new VueRouter({
            routes: [
                {path:"/user",component:User},
                {path:"/register",component:Register}
            ]
        });

        var vm = new Vue({
            el:"#app",
            data:{},
            router:router
        });
    </script>
  </body>
</html>

四 案例

功能点:

  • 抽离并渲染App根组件
  • 将左侧菜单改造为路由链接
  • 创建左侧菜单对应的路由组件
  • 在右侧主题区域添加路由占位符
  • 添加子路由规则
  • 通过路由重定向默认渲染用户组件
  • 渲染用户列表数据
  • 编程式导航跳转到用户详情页
  • 实现后退功能
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>基于vue-router的案例</title>
    <style type="text/css">
      html,
      body,
      #app {
        margin: 0;
        padding: 0px;
        height: 100%;
      }
      .header {
        height: 50px;
        background-color: #545c64;
        line-height: 50px;
        text-align: center;
        font-size: 24px;
        color: #fff;
      }
      .footer {
        height: 40px;
        line-height: 40px;
        background-color: #888;
        position: absolute;
        bottom: 0;
        width: 100%;
        text-align: center;
        color: #fff;
      }
      .main {
        display: flex;
        position: absolute;
        top: 50px;
        bottom: 40px;
        width: 100%;
      }
      .content {
        flex: 1;
        text-align: center;
        height: 100%;
      }
      .left {
        flex: 0 0 20%;
        background-color: #545c64;
      }
      .left a {
        color: white;
        text-decoration: none;
      }
      .right {
        margin: 5px;
      }
      .btns {
        width: 100%;
        height: 35px;
        line-height: 35px;
        background-color: #f5f5f5;
        text-align: left;
        padding-left: 10px;
        box-sizing: border-box;
      }
      button {
        height: 30px;
        background-color: #ecf5ff;
        border: 1px solid lightskyblue;
        font-size: 12px;
        padding: 0 20px;
      }
      .main-content {
        margin-top: 10px;
      }
      ul {
        margin: 0;
        padding: 0;
        list-style: none;
      }
      ul li {
        height: 45px;
        line-height: 45px;
        background-color: #a0a0a0;
        color: #fff;
        cursor: pointer;
        border-bottom: 1px solid #fff;
      }

      table {
        width: 100%;
        border-collapse: collapse;
      }

      td,
      th {
        border: 1px solid #eee;
        line-height: 35px;
        font-size: 12px;
      }

      th {
        background-color: #ddd;
      }
    </style>
    <script src="./js/vue_2.5.22.js"></script>
    <script src="./js/vue-router_3.0.2.js"></script>
  </head>
  <body>
    <div id="app">
      <router-view></router-view>
    </div>

    <script>

      var App = {
        template: `
        <div>
          <!-- 头部区域 -->
          <header class="header">传智后台管理系统</header>
          <!-- 中间主体区域 -->
          <div class="main">
            <!-- 左侧菜单栏 -->
            <div class="content left">
              <ul>
                <li><router-link to="/users">用户管理</router-link></li>
                <li><router-link to="/rights">权限管理</router-link></li>
                <li><router-link to="/goods">商品管理</router-link></li>
                <li><router-link to="/orders">订单管理</router-link></li>
                <li><router-link to="/settings">系统设置</router-link></li>
              </ul>
            </div>
            <!-- 右侧内容区域 -->
            <div class="content right"><div class="main-content">
              <router-view />
            </div></div>
          </div>
          <!-- 尾部区域 -->
          <footer class="footer">版权信息</footer>
        </div>`
      }

      var Users = {
        data: function(){
          return {
            userList:[
              {id:1,username:"Yorick",age:23},
              {id:2,username:"Tom",age:24},
              {id:3,username:"Jerry",age:25},
              {id:4,username:"Smith",age:26}
            ]
          }
        },
        template: `
        <div>
          <h1>用户管理</h1>
          <table>
            <thead>
              <tr>
                <th>编号</th>
                <th>用户名</th>
                <th>年龄</th>
                <th>操作</th>  
              </tr>
            </thead>
            <tbody>
              <tr :key="item.id" v-for="item in userList">
                <td>{{item.id}}</td>
                <td>{{item.username}}</td>
                <td>{{item.age}}</td>
                <td><a href="javascript:;" @click="userDetail(item.id)">操作</a></td>
              </tr>  
            </tbody>
          </table>
        </div>
        `,
        methods:{
          userDetail: function(id){
            this.$router.push("/userDetail/"+id);
          }
        }
      }
      var UserDetail = {
        props:["id"],
        template: `
        <div>
          <h2>用户详情页</h2>  
          <h3>用户编号:{{id}}</h3>
          <button @click="goBack">回退</button>
        </div>
        `,
        methods: {
          goBack: function(){
            this.$router.go(-1);
          }
        }
      }
      var Rights = {
        template: `
        <div>
          <h1>权限管理</h1>
        </div>
        `
      }
      var Goods = {
        template: `
        <div>
          <h1>商品管理</h1>
        </div>
        `
      }
      var Orders = {
        template: `
        <div>
          <h1>订单管理</h1>
        </div>
        `
      }
      var Settings = {
        template: `
        <div>
          <h1>系统管理</h1>
        </div>
        `
      }
      

      var router = new VueRouter({
        routes:[
          {path:"/",component:App,redirect:"/users", children:[
            {path:"/users",component:Users},
            {path:"/userDetail/:id",component:UserDetail,props:true},
            {path:"/rights",component:Rights},
            {path:"/goods",component:Goods},
            {path:"/orders",component:Orders},
            {path:"/settings",component:Settings}
          ]}
        ]
      })

      var vm = new Vue({
        el:"#app",
        router:router
      })
    </script>
  </body>
</html>

相关文章

  • 05Vue的前端路由

    Vue的前端路由 一 路由基本概念 路由的本质就是对应关系。 路由可分为: 后端路由:URL请求地址与服务器资源之...

  • 第三十一节:Vue路由:前端路由vs后端路由的了解

    1. 认识前端路由和后端路由 前端路由相对于后端路由而言的, 在理解前端路由之前先对于路由有一个基本的了解 路由:...

  • 前端微服务化解决方案5 - 路由分发

    路由分发式微前端 从应用分发路由到路由分发应用 用这句话来解释,微前端的路由,再合适不过来. 路由分发式微前端,即...

  • vue - 路由模式

    1 路由的基本概念与原理 路由的本质就是对应关系; 在开发中, 路由分为前端路由和后端路由. 1.1 前端路由 概...

  • react-router-dom

    一、什么是前端路由 在我看来,前端路由和网络上的路由器功能很像。前端路由也是进行分发操作,只不过其分发的是页面跳转...

  • vue基础-路由(重要)

    前端路由的概念与原理 什么是前端路由 Hash 地址与组件之间的映射关系,前端路由可以将hash地址和组件关联起来...

  • CreateReactApp+ReactRouter4的使用

    路由基础介绍1,什么是前端路由? 路由是根据不同的 url 地址展示不同的内容或页面 前端路由就是把不同路由对应不...

  • 面试:谈谈对前端路由的理解?

    面试官想听到什么答案呢? 1、为什么会出现前端路由。 2、前端路由解决了什么问题。 3、前端路由实现的原理是什么。...

  • vue学习笔记——vue-router

    1.什么是前端路由? 前端路由是根据不同的URL地址显示不同的内容或页面。 2.什么时候使用前端路由? 在单页面应...

  • 前端路由(一)

    前端路由之变化url不发送请求 什么是路由?为什么要有前端路由? 首先,域名的组成:http://(协议)www....

网友评论

      本文标题:05Vue的前端路由

      本文链接:https://www.haomeiwen.com/subject/nsxdtltx.html