Vue_前端路由详细说明

作者: coderhzc | 来源:发表于2022-01-14 15:01 被阅读0次

    0. 前端路的概念和原理

    image.png
    1. router-view他的作用很单纯:占位符
    <router-view></router-view>:  只要在项目中安装和配置了vue-router,
    就可以使用router-view这个组件了,他的作用很单纯:占位符
    2. 路由跳转
    <router-link to="/about" > about</router-link>
    2.1 他有两个属性:
          -- to属性: 
          是一个字符串或者是一个对象
          -- replace属性:
          设置replace属性的话,当点击时,会调用router.replace(),也就是没有前进后退功能了
    
    3. active-class属性:
          设置激活a元素后应用的class,默认是router-link-active,这个有什么用呢?
          -- 看以下截图:
    
    

    看以下截图:

    image.png

    0.1 HTML5的History

       history接口是HTML5 新增的,他有六种 模式改变URL而不刷新页面:
                  -- replaceState:替换原来的路径;
                  -- pushState: 使用新的路径
                  -- popState: 路径的回退;
                  -- go: 向前或向后改变路径
                  -- forward: 向前改变路径;
                  -- back: 向后改变路径;
    

    一.用window的onhashchange事件监听路由的跳转

    需求:点击 首页 电影 关于,相对应的出现对应的页面,实现页面的路由跳转

    定义三个组件在App.vue中引入定义的三个组件

    <template>
      <div id="app">
        <div class="app-com">
          <h1 class="title">App 根组件</h1>
    
          <div class="comp-box">
            <a href="#/home">首页</a>
            <a href="#/move">电影</a>
            <a href="#/about">关于</a>
          </div>
        </div>
    
        <div>
          <component :is="comName"></component>
        </div>
      </div>
    </template>
    
    <script>
    import Home from "@/components/Home.vue";
    import Move from "@/components/Move.vue";
    import About from "@/components/About.vue";
    export default {
      name: "App",
      data() {
        return {
          comName: "Home", // 在动态组件的位置,要展示的组件的名字,值必须是字符串
        };
      },
      components: {
        Home,
        Move,
        About,
      },
      created() {
        // 只要当前的App 组件一被创建, 就立即监听window对象的onhashchange事件
        window.onhashchange = () => {
          console.log("监听onhashchange的变化", location.hash);
          switch (location.hash) {
            case "#/home":
              this.comName = "Home";
              break;
            case "#/move":
              this.comName = "Move";
              break;
            case "#/about":
              this.comName = "About";
              break;
    
            default:
              break;
          }
        };
      },
    };
    </script>
    
    <style lang="less" scoped>
    #app {
      .app-com {
        background-color: #ccc;
        margin-bottom: 10px;
        padding-bottom: 10px;
        .title {
          height: 60px;
          line-height: 60px;
          background-color: #ccc;
          text-align: center;
          padding: 20px 0;
          margin-bottom: 10px;
        }
        .comp-box {
          display: flex;
          a {
            padding: 0 10px;
          }
        }
      }
    }
    </style>
    
    

    实际截图

    image.png

    一.一.history实现

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    
    <body>
      <div id="app">
        <a href="/home">home</a>
        <a href="/about">about</a>
    
        <div class="content">default</div>
      </div>
    
      <script>
        const contentEl = document.querySelector(".content")
        const aEls = document.getElementsByTagName('a');
        for (let aEl of aEls) {
          aEl.addEventListener('click', e => {
            e.preventDefault();
            const href = aEl.getAttribute('href');
            console.log(href);
            window.history.pushState({}, "", href) // 三个参数
    
            switch (location.pathname) {
              case "/home":
                contentEl.innerHTML = "Home";
                break;
              case "/move":
                contentEl.innerHTML = "Move";
                break;
              case "/about":
                contentEl.innerHTML = "About";
                break;
    
              default:
                break;
            }
          })
    
        }
    
      </script>
    </body>
    
    </html>
    

    /*******************************************************/

    二.Vue的router的基本使用

    2.1 安装命令:

     在vue2的项目中,安装vue-router的命令如下: 
         -- npm i vue-router@3.5.2 -S
    

    2.2. 创建路由模块:

    在src源代码目录下,新建router/index.js路由模块文件,并初始化如下代码:
    // 1. 导入Vue 和VueRouter的包
    import Vue from "vue";
    import VueRouter from "vue-router"
    import Home from "../components/Home.vue"
    import Move from "../components/Move.vue"
    import About from "../components/About.vue"
    
    // 2. 调用Vue.use()函数,把VueRouter 安装为Vue的插件
    Vue.use(VueRouter) 
    
    // 3. 创建路由的实例对象
    const router = new VueRouter({
      // routes是一个数组,作用: 定义"hash地址" 与 "组件"之间的对应关系
      routes:[
        // {path:'展示的路由地址', component: "要展示的组件"}
        {path:'/home', component: Home},
        {path:'/about', component: About},
        {path:'/move', component: Move}
      ]
    })
    
    // 4. 向外共享路由的实例对象
    export default router;
    

    2.3 在main.js 中引入router.js

    import Vue from "vue";
    import App from "./App.vue";
    import router from "./router"
    Vue.config.productionTip = false;
    
    new Vue({
      router,
      render: (h) => h(App),
    }).$mount("#app");
    
    

    2.4 在页面中如何去使用Vue 的router(路由)

    <template>
      <div id="app">
        <div class="app-com">
          <h1 class="title">App2 根组件</h1>
        </div>
        <hr />
        
        <!-- 
          当安装和配置了 vue-router后,就可以使用router-link来替代普通的a链接了 
          1. to属性: 添加要跳转的路径和router/index.js 中的path:"/home"对应的路径就可以了,类似a链接的href属性
        -->
        <!-- <a href="/home"></a> -->
        <router-link to="/home">首页</router-link>
        <router-link to="/move">电影</router-link>
        <router-link to="/about">关于</router-link>
    
        <!-- 
              只要在项目中安装和配置了vue-router,就可以使用router-view这个组件了,
              他的作用很单纯:占位符,如果没有这个玩意的话你的所有的组件都不会渲染出来
         -->
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    export default {
      name: "App",
      created() {},
      data() {
        return {};
      },
    };
    </script>
    
    <style lang="less" scoped>
    #app {
      .app-com {
        background-color: #ccc;
        margin-bottom: 10px;
        padding-bottom: 10px;
        .title {
          height: 60px;
          line-height: 60px;
          background-color: #ccc;
          text-align: center;
          padding: 20px 0;
          margin-bottom: 10px;
        }
        .comp-box {
          display: flex;
          a {
            padding: 0 10px;
          }
        }
      }
    }
    </style>
    
    

    实际截图

    image.png

    /*************************************************/

    三.路由重定向redirect

    当你刚进来的时候 或者当你切换地址栏路径到斜杠的时候,你会发现啥都不会显示的时候,这种就要用到重定向了

    image.png
    import Vue from "vue";
    import VueRouter from "vue-router"
    import Home from "../components/Home.vue"
    import Move from "../components/Move.vue"
    import About from "../components/About.vue"
    
    Vue.use(VueRouter) 
    
    const router = new VueRouter({
      // routes是一个数组,作用: 定义"hash地址" 与 "组件"之间的对应关系
      routes:[
        // {path:'展示的路由地址', component: "要展示的组件"}
        // 当用户访问 / 时候,通过 redirect 属性跳转到 /home 对应的路由规则
        {path:"/",redirect:'/home'},
        {path:'/home', component: Home},
        {path:'/about', component: About},
        {path:'/move', component: Move}
      ]
    })
    
    export default router;
    

    使用了redirect指定了默认组件以后 当你切换到 / 的时候就不会出现空白页面了

    /********************************************/

    四.嵌套路由(子路由,在子路由中的path:"tab1",在tab1前面千万不要加 / , 不然组件是出不来的):

    1.首先分析: 当你在父组件中点击跳转到某一个子组件中,然后子组件下面还有子路由,这种就叫嵌套路由

    2.如下是嵌套路由的一个展示图:

    image.png

    3.声明嵌套路由的规则:

    image.png

    4. 嵌套路由的整个代码实现过程如下:

    image.png

    5.子路由重定向redirect

    const router = new VueRouter({
      // routes是一个数组,作用: 定义"hash地址" 与 "组件"之间的对应关系
      routes: [
        // {path:'展示的路由地址', component: "要展示的组件"}
        // 当用户访问 / 时候,通过 redirect 属性跳转到 /home 对应的路由规则
        { path: "/", redirect: "/home" },
        { path: "/home", component: Home },
        { path: "/move", component: Move },
        {
          path: "/about",
          component: About,
          redirect: "/about/tab1", // 这个重定向可以
          children: [
            // { path: "", redirect: "tab1" }, // 这个重定向也可以
            {
              path: "tab1", // tab1 前面千万不要加 /
              component: Tab1,
            },
            {
              path: "tab2", // tab2 前面千万不要加 /
              component: Tab2,
            },
          ],
        },
      ],
    });
    

    /********************************************/

    五.动态路由

    1.什么是动态路由呢?

    例如: 当你进入到自己喜欢的鞋子界面的时候,你想看具体的鞋子的时候,你点击你选中的那个鞋子查看当前写的详情,那么此时就要是用到动态路由

    2. 动态路由的基本是用图:

    image.png

    3.动态路由的基本用法:

    image.png

    4.动态路由的具体代码实现:

    image.png

    5. 为路由开启props传参,是用$route.params.XXXX 的传参方式太麻烦了

    image.png

    6. 扩展和 query 和fullPath

    截图展示:


    image.png
    1. <router-link to="/move/1">洛基</router-link>
        --- 注意: 在hash地址中, / 后面的都叫"路径参数"
        --- 在路由"参数对象"中,需要使用$route.params来访问路径参数
    
    2. <router-link to="/move/2?name=zs&age=20">洛基</router-link>
       --- 注意在hash 地址中? 后面的参数项,叫做''查询参数''
       --- 在路由"参数对象"中,需要使用this.$route.query 来访问参数
    
    3. 注意: 在this.$route 中,path只是路径部分;fullPath是完整的地址
    /move/2?name=zs&age=20 是fullPath的值
    /move/2 是path的值
    

    7. 动态拼接data中的数据

    image.png

    8. 路由懒加载的几种书写方式:

    image.png

    9. 路由的meta属性:

    image.png

    /************************************************************/

    六.路由导航守卫

    image.png

    6.1 导航守卫

    image.png

    6.2 全局前置守卫 beforeEach

    image.png

    6.3 next()的3种调用方式

    image.png

    七.控制访问权限

    router.beforeEach(function (to, from, next) {
    
      const token = localStorage.getItem('token'); // 拿到登录时后端返回的登录token
      
      if(to.path === "/main") { // 判断将要去的,是否 是/main页面
    
        if(token) { // 如果有token的话
    
          next() // 如果访问的是/main,也有token的话 那么就放行
    
        }else {
    
          next('/login'); // 如果访问的是/main,没有有token的话 那么就强行跳转到/login登录页
    
        }
    
      }else {
    
        next(); // 访问的不是后台主页,那么就直接放行
    
      }
      
    });
    

    八.需求: 当我们随便输入一个路径的时候,没有这个路由 让我们显示一个对应的Page Not Found 该咋怎么做了?

    image.png

    九.如果你想拿到用户输入的乱七八糟的东西的话:

    image.png

    相关文章

      网友评论

        本文标题:Vue_前端路由详细说明

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