• Vue 路由 基本操作 路由模式 hash路由模式的实现原理


    1-路由

    1.1-路由的概念

    • 页面访问路径和组件之间的对应关系

    1.2-路由的安装

    npm i vue-router -S	
    

    1.3-路由的基本使用流程

    1.3.1-第一步

    • 配置路由规则(数组)
    import Home from './pages/Home'
    import Login from './pages/Login'
    const rotues=[
        {
            // 页面访问路径
            path:'/home',
            // 页面组件对象
            component:Home
        },
        {
            // 页面访问路径
            path:'/login',
            // 页面组件对象
            component:Login
        }
    ]
    

    1.3.2-第二步

    • 根据路由规则数组, 创建路由实例对象
    import Vue from 'vue';
    // 1-导入路由模块
    import VueRouter from 'vue-router';
    // 2-将路由模块注册成vue的插件
    Vue.use(VueRouter);
    // 3-创建路由实例对象
    const  router=new VueRouter({
        // 路由规则数组
        routes:routes
    });
    // 4-导出路由对象
    

    1.3.3-第三步

    • 将路由实例挂在到vue上
    import router from './router/index';
    new Vue({
        el:'#app',
        // 挂载路由实例
        router:router
    });
    

    1.3.4-第四步

    • 在根组件App.vue中添加路由占位符合路由导航链接
    <template>
      <!-- 必须有一个唯一的根标签 -->
      <div id="app">
        <!-- 导航链接 -->
        <!-- to属性: 指定页面的跳转地址, 必须和路由规则数组中的path属性保持一致 -->
        <router-link to="/home">首页</router-link>
        <router-link to="/reg">注册</router-link>
        <router-link to="/login">登录</router-link>
        <hr>
        <!-- 路由占位符: 访问地址匹配到的路由组件的显示位置 -->
        <router-view></router-view>
       </div>
    </template>
    

    1.4-路由模式

    • hash模式:

      • 页面访问地址中带有#, 默认路由模式
      • hash路由模式, 通过npm run build打包之后, 不需要web服务器的支持
      new  VueRouter({
          // 路由规则数组
          routes,
          // mode可选值: hash, history
          mode:'hash'		
      });
      
    • history模式:

      • 页面访问地址中不带#
      • history路由模式, 通过npm run build打包之后,需要web服务器的支持
      new  VueRouter({
          // 路由规则数组
          routes,
          // mode可选值: hash, history
          mode:'history'		
      });
      

    1.5-路由导航高亮

    1. 给默认的路由导航高亮类名router-link-active添加对应css属性, 使其高亮显示即可

    2. 自定义导航链接高亮类名

      new  VueRouter({
          // 自定义导航链接高亮类名
          linkActiveClass:''
      });
      

    1.6-路由重定向

    • router/index.js
    // 3-定义路由规则数组
    const  routes=[
        {
            path:'/',
            // component:Home
            // 重定向
            redirect:'/login'
        }
    ]
    

    1.7-命名路由

    • router/index.js

      // 3-定义路由规则数组
      const  routes=[
          {
              name:'index',
              path:'/',
              // component:Home
              // 重定向
              redirect:'/login'
          },
          {
              name:'home',
              path:'/home',
              component:Home
          },
          {
              name:'login',
              path:'/login',
              component:Login
          },
          {
              name:'reg',
              path:'/reg',
              component:Reg
          }
      ];
      
    • App.js

      <router-link class="nav-btn" v-bind:to="{name:'home'}" tag="div">首页</router-link>
      

    1.8-编程式导航

    • 通过js的方式实现页面跳转

    • this.$router: 包含和页面跳转相关的方法

      • push(): 实现页面跳转, 追加一条访问历史

        • 路由字符串

          this.$router.push('/home');
          
        • 路由对象

          this.$router.push({name:'home'});
          
      • replace: 实现页面跳转, 覆盖前一次的访问历史

        • 路由字符串

          this.$router.replace('/home');
          
        • 路由对象

          this.$router.replace({name:'home'});
          
      • go(): 实现页面前进后者回退

        • 正数: 前进
        • 负数: 回退
      • forward(): 实现页面前进一步

      • back(): 实现页面回退一步


    1.9-路由元信息

    • 定义

      router/index.js

      // 3-定义路由规则数组
      const  routes=[
          {
              name:'index',
              path:'/',
              // component:Home
              // 重定向
              redirect:'/login'
          },
          {
              name:'home',
              path:'/home',
              component:Home,
              // 路由元信息
              meta:{
                  title:'网站首页'
              }
          },
          {
              name:'login',
              path:'/login',
              component:Login,
              meta:{
                  title:'登录页面'
              }
          },
          {
              name:'reg',
              path:'/reg',
              component:Reg,
              meta:{
                  title:'注册页面'
              }
          }
      ];
      
    • 调用

      • 使用路由元信息, 实现更新页面标题
      • this.$route: 存储的是和路由相关的属性(包含路由元信息)

      页面组件中: 通过this.$route.meta读取路由元信息

      export default {
        created(){
          // this.$route: 存储的是和路由相关的属性(包含路由元信息)
          // 通过this.$route对象读取路由元信息
          const title=this.$route.meta.title;
          // 通过操作真实dom, 实现更新页面标题
          document.title=title;
        }
      }
      

    1.10-命名视图

    • 应用场景: 一个路由访问地址, 对应多个视图组件

    1.10.1-配置命名视图路由规则

    router/index.js

    import Home from '../pages/Home';
    import Aside from '../components/Aside';
    // 3-定义路由规则数组
    const  routes=[
        // 一个访问路径, 对应多个组件, 需要用到命名视图
        {
            name:'home',
            path:'/home',
            // component:Home,
            components:{
                // aside: 要和插入的router-view的name属性保持一致
                // Aside: 组件对象
                aside:Aside,
                // content: 要和插入的router-view的name属性保持一致
                // Home: 组件对象
                content:Home
            }
        }
    }
    

    1.10.2-在根组件中添加命名视图

    App.vue

    <template>
      <!-- 必须有一个唯一的根标签 -->
      <div id="app" class="container">
        <!-- 命名视图aside -->
        <router-view name="aside"></router-view>
        <div class="right">
          <!-- 导航链接 -->
          <router-link class="nav-btn" v-bind:to="{name:'home'}" tag="div">首页</router-link>
          <router-link class="nav-btn" :to="{name:'reg'}" tag="div">注册</router-link>
          <router-link class="nav-btn" to="/login" tag="div">登录</router-link>
          <router-link class="nav-btn" to="/ucenter" tag="div">我的</router-link>
          <hr />
          <!-- 命名视图content -->
          <router-view name="content"></router-view>
          <!-- 默认视图: 默认路由出口 -->
          <router-view></router-view>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      // 组件名字
      name: "App"
    };
    </script>
    
    <style>
    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    #app {
       1000px;
      margin: 20px auto;
    }
    h1 {
      margin-bottom: 10px;
    }
    /* 路由导航链接高亮显示 */
    .nav-btn {
      background: #ddd;
      border: 1px solid #eee;
      display: inline-block;
       80px;
      height: 40px;
      line-height: 40px;
      text-align: center;
      text-decoration: none;
    }
    /* 默认高亮类名:router-link-active */
    /* 自定义导航链接高亮类名 */
    .active {
      background: brown;
      color: #fff;
    }
    
    /* 命名视图对应样式 */
    .container {
      display: flex;
      height: 600px;
    }
    .right {
      flex: 1;
      background: lightgreen;
    }
    </style>
    

    1.11-动态路由

    • 定义动态路由规则

      // 3-定义路由规则数组
      const  routes=[
          // 动态路由, id动态路由参数
          {
              path:'/goods/:goodsId',
              component:Goods,
              // 路由元信息的定义
              meta:{
                  title:'商品详情',
                  // 自定义属性, auth:true,表示必须登录之后, 才能访问
                  auth:false
              }
          }
      ];
      
    • 动态路由链接

      <router-link class="nav-btn" to="/goods/100" tag="div">商品详情</router-link>
      
    • 动态路由参数的获取

      this.$route.params
      

    1.11.1-动态路由参数的解耦

    1. 在路由规则对象中添加如下配置

      {
          path:'/goods/:goodsId',
          component:Home
          // 路由参数解耦
          props:true
      }
      
    2. 在组件配置对象中添加如下配置

      {
          data(){
            return {}  
          },
          props:['goodsId']
      }
      
    3. 在组件视图层直接通过goodsId获取动态路由参数

      <h1>{{goodsId}}</h1>
      <!--完整写法-->
      <h1>{{$route.params.goodsId}}</h1>
      

    1.12-通过查询字符串的方式实现路由传参

    1. 通过查询字符串传递数据

      <router-link class="nav-btn" to="/news?newsId=1&wd=vue" tag="div">新闻详情</router-link>
      
    2. 组件内通过this.$route.query获取查询字符串对象

      this.$route.query
      

    1.13-路由懒加载

    • 作用: 提升页面渲染性能

      const Home=()=>import('../pages/Home');
      const Login=()=>import('../pages/Login');
      const Reg=()=>import('../pages/Reg');
      const Ucenter=()=>import('../pages/Ucenter');
      const Goods=()=>import('../pages/Goods');
      const News=()=>import('../pages/News');
      

    1.14-路由匹配模式

    • 默认是模糊匹配: 访问地址中只要包含路由对象中的path, 就认为是匹配成功(所以会自动电量对应的导航链接)
    启用路由严格匹配模式
    • 在路由导航链接组件上添加exact属性

      <router-link exact tag="li" to="/">管理中心</router-link> 
      

    2-hash路由模式实现原理

    1. 监听页面锚点字符串的更新

      <component :is="page"></component>
      
      // 导入页面组件
      import Home from './pages/Home';
      import Reg from './pages/Reg';
      import Login from './pages/Login';
      export default {
        // 组件名字
        name: "App",
        data(){
          return {
            page:'Home'
          }
        },
        // 注册子组件
        components: {Home,Reg,Login},
        created(){
          window.addEventListener('hashchange',()=>{
            // console.log('hashchange',location.hash.split('/')[1]);
            // 更新page变量的值
            this.page=location.hash.split('/')[1];
          });
        }
      };
      
    2. 根据锚点字符串, 显示对应的组件

    3-案例

    3.1-后台管理系统

    • 根组件

      App.vue

      <template>
        <div class="container">
          <div class="left">
            <ul class="navbar">
              <!-- <li :class="page==='Main'?'active':''" @click="changePage('Main')">管理中心</li>
              <li :class="page==='Goods'?'active':''" @click="changePage('Goods')">商品管理</li>
              <li :class="page==='User'?'active':''" @click="changePage('User')">会员管理</li>
              <li :class="page==='Order'?'active':''" @click="changePage('Order')">订单管理</li> -->
              <!-- 启用路由严格匹配模式 -->
              <router-link exact tag="li" to="/">管理中心</router-link> 
              <router-link tag="li" to="/goods">商品管理</router-link> 
              <router-link tag="li" to="/user">会员管理</router-link> 
              <router-link tag="li" to="/order">订单管理</router-link> 
      
            </ul>
          </div>
          <div class="right">
            <!-- 头部 -->
            <Header></Header>
            <div class="content">
              <!-- <component :is="page"></component> -->
              <!-- 路由占位符 -->
              <router-view></router-view>
            </div>
            <!-- 底部 -->
            <Footer />
          </div>
        </div>
      </template>
      
      <script>
      // 1-导入页组件
      // import Main from "./pages/Main";
      // import Goods from "./pages/Goods";
      // import Order from "./pages/Order";
      // import User from "./pages/User";
      // 导入功能组件
      import Header from "./components/Header";
      import Footer from "./components/Footer";
      
      export default {
        // 2-注册组件
        components: {
          // Main,
          // Goods,
          // Order,
          // User,
          Header,
          Footer
        },
        data() {
          return {
            // 页面组件名称
            page: "Order"
          };
        },
        methods: {
          // 切换页面
          changePage(page) {
            this.page = page;
          }
        }
      };
      </script>
      
      <style>
      *{
        padding: 0;
        margin: 0;
        box-sizing: border-box;
      }
      .container {
        background-color: #ddd;
        /* vh:相对单位; 100vh=屏幕的高度  1vh==1/100屏幕高度; viewport height */
        height: 100vh;
        display: flex;
      }
      /* 左侧导航栏 */
      .container .left {
         226px;
        background: #00152a;
      }
      .left .navbar li {
        list-style: none;
        line-height: 50px;
        color: #fff;
        text-align: center;
        cursor: pointer;
      }
      .left .navbar li:hover {
        background: #0077b8;
      }
      .left .navbar li.active {
        background: #0077b8;
      }
      
      .container .right {
        flex: 1;
        display: flex;
        flex-direction: column;
      }
      .right .header {
        height: 60px;
        line-height: 60px;
        text-align: center;
        background: #fff;
      }
      .right .content {
        margin: 10px;
        background: #fff;
        height: 300px;
        text-align: center;
        flex: 1;
      }
      .right .footer {
        line-height: 60px;
        text-align: center;
        background: #fff;
      }
      </style>
      
    • 路由文件

      ruoter/index.js

      // 1-导入路由模块
      import Vue from 'vue'
      import VueRouter from 'vue-router';
      
      // 2-注册插件
      Vue.use(VueRouter);
      
      
      // 3-创建路由规则
      // 导入页面组件
      import Main from '../pages/Main';
      import Goods from '../pages/Goods';
      import Order from '../pages/Order';
      import User from '../pages/User';
      
      const routes=[
          {
              // 模糊匹配: 访问地址中包含路由规则对象中的path, 那么认为匹配成功
              path:'/',
              component:Main,
              meta:{
                  title:'管理中心'
              }
          },
          {
              path:'/goods',
              component:Goods,
              meta:{
                  title:'商品管理'
              }
          },
          {
              path:'/user',
              component:User,
              meta:{
                  title:'会员管理'
              }
          },
          {
              path:'/order',
              component:Order,
              meta:{
                  title:'订单中心'
              }
          }
      ];
      
      // 4-创建路由对象
      const router=new  VueRouter({
          routes,
          mode:'hash',
          linkActiveClass:'active'
      });
      
      // 5-导出路由实例对象
      export default router;
      
    • 项目入口文件

      /main.js

      // The Vue build version to load with the `import` command
      // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
      import Vue from 'vue'
      // 导入了根组件
      import App from './App'
      // 导入路由实例对象
      import router from './router'
      /* eslint-disable no-new */
      new Vue({
        // 模板编译之后挂载的容器
        el: '#app',
        // 挂载路由模块
        router,
        components: { App },
        // vue实例的视图模板: 使用根组件App充当默认视图
        template:'<App/>'
      })
      
      

    4-在线参考文档

  • 相关阅读:
    linux中按行读取指定行
    linux常用配置文件
    linux虚拟机设置网络
    jenkins新建一个robot脚本的job
    jenkins中配置邮件发送
    jenkins中robot framework插件安装
    Jenkins subversion svn插件安装失败
    jenkins节点启动
    {"non_field_errors":["Unable to log in with provided credentials."]}% 无法使用提供的凭据登录
    路径模板
  • 原文地址:https://www.cnblogs.com/bnzw/p/14026617.html
Copyright © 2020-2023  润新知