zoukankan      html  css  js  c++  java
  • 路由 之 初识

    一.认识路由

     1.路由:就是通过互联的网络吧信息从源地址输到目的地的活动  --维基百科

    2.后端路由阶段:

       一个页面有自己对应的网址,即url,url会发送到服务器 ,服务器通过正则对该url进行匹配,并最后交给一个controller进行处理,controller最终生成html或者数据,返回给前端,这就完成了一个I/0操作

      缺点:前端开发人员进行开发,需要懂后端语言才行

              html代码和对应的逻辑混在一起,编写和维护非常的糟糕.

    3.前后端分离路由阶段

      随着ajax,有了前后端分离的开发模式,前端通过ajax请求得到的数据,通过js将数据渲染.这样后端专注数据,前端专注交互和可视化,并且移动端出现后,后端不需要任何处理,还是之前使用的一套api即可

    4.单页面应用阶段

      其实SPA最主要的特点就是在前后端分离基础上添加了一层前端路由,也就是前端来维护一套路由规则.

    5.前端路由的核心

      改变url,但是页面不进行整体的刷新

     url发生改变是,页面不刷新,而是将 codewhy.com (html+css+js全部资源) 中属于该url部分的相关内容渲染出来

    二.vue-router基本使用

     (1)安装vue-router

    npm i vue-router --save

    (2)在模块化工程中使用它(因为是一个插件,所以可以通过Vue.use()来安装路由功能)

      第一步:导入路由对象,并且调用Vue.use(VueRouter)

      第二步:创建路由实例,并且传入路由映射配置

      第三步:在vue实例中挂载创建的路由实例

    具体操作代码和文件

    1>在vue项目中的src中添加router文件夹,在router添加index.js文件

    2>index.js文件写内容

    //配置路由信息
    import VueRouter from "vue-router";
    import Vue from "vue";
    
    //1.通过vue.use(插件),安装插件
    Vue.use(VueRouter);
    
    //2.创建VueRouter对象
    const routes = [];
    const router = new VueRouter({
      //配置路由和组件之间的应用关系
      routes,
    });
    
    //3.将router对象传入到vue实例中
    export default router;
    

    3>main.js写内容

    import Vue from "vue";
    import App from "./App.vue";
    import router from "./router/index"; // './router' 这样会自动找到index.js
    
    Vue.config.productionTip = false;
    
    new Vue({
      render: (h) => h(App),
      router: router,
    }).$mount("#app");
    

    (3)使用vue-router的步骤 映射配置和呈现

      第一步:创建路由组件

      第二步:配置路由映射,组件和路径映射关系

      第三步:使用路由:通过<router-link>和<router-view>  

    具体操作代码和文件

    1>在components文件夹中添加 Home.vue

    <template>
      <div>
        <h2>我是首页</h2>
        <p>我是首页内容</p>
      </div>
    </template>
    <script>
    export default {
      name: "Home",
      data() {
        return {
          message: "张三",
        };
      },
    };
    </script>
    <style></style>
    

    2>在components文件夹中添加 About.vue  

    <template>
      <div>
        <h2>我是导航栏</h2>
        <p>导航栏内容</p>
      </div>
    </template>
    <script>
    export default {
      name: "About",
      data() {
        return {
          message: "张三",
        };
      },
    };
    </script>
    <style></style>
    

    3>修改index.js

    import Vue from "vue";
    import VueRouter from "vue-router";
    import Home from "../components/Home.vue";
    import About from "../components/About.vue";
    
    //1.通过vue.use安装插件
    Vue.use(VueRouter);
    
    //2.创建vuerouter对象
    const routes = [
      {
        path: "/home",
        component: Home,
      },
      {
        path: "/about",
        component: About,
      },
    ];
    const router = new VueRouter({
      routes,
    });
    
    export default router;
    

    4>修改App.vue文件

    <template>
      <div id="app">
        <router-link to="/home">首页</router-link>
        <router-link to="/about">导航</router-link>
        <router-view></router-view>  //用于占位
      </div>
    </template>
    
    <script>
    // import HelloWorld from "./components/HelloWorld.vue";
    
    export default {
      name: "App",
    };
    </script>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    

    5>执行命令

    npm run serve
    

    6>路由的默认值(重定向) 修改index.js的内容

    const routes = [
      {
        path: "",
        redirect: "/home",  //重定向
     //path:''
    //component:Home  这样写的确可以加载,但是网页的路径并没有修改,所以采用重定向
      },
      {
        path: "/home",d
        component: Home,
      },
      {
        path: "/about",
        component: About,
      },
    ];
    

    7>修改为history模式

       路由默认的是hash模式,那么在 浏览器上默认是有 "#"的:例如     http://localhost:8080/#/home

       修改index.js文件

      

    import Vue from "vue";
    import VueRouter from "vue-router";
    import Home from "../components/Home.vue";
    import About from "../components/About.vue";
    
    //1.通过vue.use安装插件
    Vue.use(VueRouter);
    
    //2.创建vuerouter对象
    const routes = [
      {
        path: "",
        redirect: "/home",
      },
      {
        path: "/home",
        component: Home,
      },
      {
        path: "/about",
        component: About,
      },
    ];
    const router = new VueRouter({
      mode: "history",   //添加这部分内容
      routes,
    });
    
    export default router;
    

      

    (4)router-link的其他属性补充

      router-link在vue中默认渲染的是a标签

    <router-link to="/home" tag="button" replace  active-class="active"></router-link>
    
    to:指定跳转路径
    tag:将router-link渲染为button标签
          若没有该属性,默认是a标签
    replace:不会留下history记录,所以指定replace情况下,浏览器的前进后退键是不能返回到上一个页面中的
    active-class="active"
    
    //没有看到任何效果
    style{
           active:{
             color:red    
          }
    }
    

     那么 active-class="active"不需要了,可以通过在index.js配置一个信息

    const router = new VueRouter({
      mode: "history",
      routes,
      linkActiveClass: "active",//就这一句代码
    });
    

    (5)通过代码跳转路由 修改app.vue文件即可

    <template>
      <div id="app">
        <!-- <router-link to="/home" replace>首页</router-link>
        <router-link to="/about" replace>导航</router-link> -->
        <button @click="homeClick">首页</button>
        <button @click="aboutClick">关于</button>
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    // import HelloWorld from "./components/HelloWorld.vue";
    
    export default {
      name: "App",
      methods: {
        //通过代码的方式来修改路径
        homeClick() {
          //所有的组件都有一个属性:router  来自vue-router
          this.$router.push("/home");
    //this.$router.replace('/home') 这个操作就相当于上面 router-link 的replace的属性作用 }, aboutClick() { this.$router.push("/about"); }, }, }; </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } .active { color: "red"; } </style>

     重点:this.$router 相当于index.js中 new VueRouter实例

               this.$route 表示的是那个路由处于活跃状态:表示 index.js页面中 routes的 哪个path是活跃的

    (6)vue-router动态路由的使用 (也是传参的一种方式)

     分析:为什么要动态路由,原因是若进入的home,about页面都是开放的,可是登录user(用户界面时),那么路径就是 /user/zhangsan ,表示是张三登录的

    1/修改index.js页面

    import Vue from "vue";
    import VueRouter from "vue-router";
    import Home from "../components/Home.vue";
    import About from "../components/About.vue";
    import User from "../components/User.vue";
    
    //1.通过vue.use安装插件
    Vue.use(VueRouter);
    
    //2.创建vuerouter对象
    const routes = [
      {
        path: "",
        redirect: "/home",
      },
      {
        path: "/home",
        component: Home,
      },
      {
        path: "/about",
        component: About,
      },
      {
        path: "/user/:abc",  //表示是谁登录了用户界面
        component: User,
      },
    ];
    const router = new VueRouter({
      mode: "history",
      routes,
    });
    
    export default router;
    

      

    2> 添加User.vue页面

    <template>
      <div>
        <h2>用户</h2>
        <p>这是用户</p>
        <p>{{ $route.params.abc }}</p>
        <!-- <p>{{ userid }}</p> -->
      </div>
    </template>
    <script>
    export default {
      name: "User",
      data() {
        return {
          message: "用户信息",
        };
      },
      computed: {
        userid() {
          return this.$route.params.abc;
        },
      },
    };
    </script>
    <style></style>
    

    3>修改App.vue

    <template>
      <div id="app">
        <!-- <router-link to="/home" replace>首页</router-link>
        <router-link to="/about" replace>导航</router-link> -->
        <!-- <button @click="homeClick">首页</button>
        <button @click="aboutClick">关于</button>
        <button></button> -->
        <router-link to="/home" replace>首页</router-link>
        <router-link to="/about" replace>关于</router-link>
        <router-link :to="'/user/' + userid" replace>用户</router-link>
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    // import HelloWorld from "./components/HelloWorld.vue";
    
    export default {
      name: "App",
      data() {
        return {
          userid: "张三",
        };
      },
    };
    </script>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    .active {
      color: "red";
    }
    </style>

    重点:this.$route 表示的是那个路由处于活跃状态:表示 index.js页面中 routes的 哪个path是活跃的 

    (7)路由的懒加载

    官方给出的解释:

          当打包构建时,js包会非常大,影响页面加载,那么把不同路由对应的组件分割成不同的代码块,那么当路由被访问的时候才加载,这样就更高效

    分析官方的解释:

          路由通常定义很多页面

          一般情况下,很多页面放在一个js文件中,会造成index.html这个页面非常大

          一次性从服务器请求下来的页面,可能需要花费一定的时间,甚至会出现短暂的空白

    懒加载做了啥?

         路由懒加载主要作用是将路由对应的组件打包成一个个js代码块

         只有这个路由被访问时,才加载对应的组件

    懒加载的方式(如图)

    重构index.js文件

    import Vue from "vue";
    import VueRouter from "vue-router";
    // import Home from "../components/Home.vue";
    // import About from "../components/About.vue";
    // import User from "../components/User.vue";
    
    const Home = () => import("../components/Home.vue");
    const About = () => import("../components/About.vue");
    const User = () => import("../components/User.vue");
    //1.通过vue.use安装插件
    Vue.use(VueRouter);
    
    //2.创建vuerouter对象
    const routes = [
      {
        path: "",
        redirect: "/home",
      },
      {
        path: "/home",
        component: Home,
      },
      {
        path: "/about",
        component: About,
      },
      {
        path: "/user/:abc",
        component: User,
      },
    ];
    const router = new VueRouter({
      mode: "history",
      routes,
    });
    
    export default router;
    

      

    重点: npm run build  会多生成三个js文件,因为一个懒加载文件就会生成一个js文件

    三.vue-router嵌套路由

     (1)认识嵌套路由

     (2)通过home/news   和 home/message 路径访问

    1>在components添加HomeNews.vue文件

    <template>
      <div>
        <h2>我是新闻</h2>
        <p>我是新闻内容</p>
      </div>
    </template>
    <script>
    export default {
      name: "HomeNews",
      data() {
        return {
          message: "张三",
        };
      },
    };
    </script>
    <style></style>
    

    2>在components添加HomeMessage.vue文件 

    <template>
      <div>
        <h2>我是消息</h2>
        <p>我是消息内容</p>
      </div>
    </template>
    <script>
    export default {
      name: "HomeMessage",
      data() {
        return {
          message: "张三",
        };
      },
    };
    </script>
    <style></style>
    

    3>修改index.js文件

    import Vue from "vue";
    import VueRouter from "vue-router";
    // import Home from "../components/Home.vue";
    // import About from "../components/About.vue";
    // import User from "../components/User.vue";
    
    const Home = () => import("../components/Home.vue");
    const HomeNews = () => import("../components/HomeNews.vue"); //添加的内容
    const HomeMessage = () => import("../components/HomeMessage.vue"); //添加的内容
    const About = () => import("../components/About.vue");
    const User = () => import("../components/User.vue");
    //1.通过vue.use安装插件
    Vue.use(VueRouter);
    
    //2.创建vuerouter对象
    const routes = [
      {
        path: "",
        redirect: "/home",
      },
      {
        path: "/home",
        component: Home,
        children: [
          { path: "", redirect: "news" },
          {
            path: "news",
            component: HomeNews,
          },
          {
            path: "message",
            component: HomeMessage,
          },
        ],
      },
      {
        path: "/about",
        component: About,
      },
      {
        path: "/user/:abc",
        component: User,
      },
    ];
    const router = new VueRouter({
      mode: "history",
      routes,
    });
    
    export default router;
    

    4>修改home.vue文件

    <template>
      <div>
        <h2>我是首页</h2>
        <p>我是首页内容</p>
        <router-link to="/home/news" replace>新闻</router-link>
        <router-link to="/home/message" replace>消息</router-link>
        <router-view></router-view>
      </div>
    </template>
    <script>
    export default {
      name: "Home",
      data() {
        return {
          message: "张三",
        };
      },
    };
    </script>
    <style></style>
    

      

    四.vue-router参数传递

    (1)传递参数的方式

       第一种:params  

            配置路由格式:/router/:id

            传递的方式:在path后面跟上对应的值 <router-link :to=" '/home/' +变量名  ">

            传递后形成的路径:/router/123,router/abc

      第二种:query

             配置路由格式:/router,也就是普通的配置

             传递的方式:对象中使用query的key作为传递方式

            传递后形成的路径:/router?id=123,/router?id=abc

    演示传递参数,创建新的组件,以下步骤

     第一步:创建新的组件Profile.vue

    第二步:配置路由映射

    第三步:添加跳转的<router-link>

    1>components文件夹添加Profile.vue文件

    <template>
      <div>
        <h2>我是档案</h2>
        <p>我是档案内容</p>
      </div>
    </template>
    <script>
    export default {
      name: "Profile",
      data() {
        return {
          message: "张三",
        };
      },
    };
    </script>
    <style></style>
    

    2>配置路由映射 index.js

    import Vue from "vue";
    import VueRouter from "vue-router";
    // import Home from "../components/Home.vue";
    // import About from "../components/About.vue";
    // import User from "../components/User.vue";
    
    const Home = () => import("../components/Home.vue");
    const HomeNews = () => import("../components/HomeNews.vue");
    const HomeMessage = () => import("../components/HomeMessage.vue");
    const About = () => import("../components/About.vue");
    const User = () => import("../components/User.vue");
    const Profile = () => import("../components/Profile.vue");
    //1.通过vue.use安装插件
    Vue.use(VueRouter);
    
    //2.创建vuerouter对象
    const routes = [
      {
        path: "",
        redirect: "/home",
      },
      {
        path: "/home",
        component: Home,
        children: [
          { path: "", redirect: "news" },
          {
            path: "news",
            component: HomeNews,
          },
          {
            path: "message",
            component: HomeMessage,
          },
        ],
      },
      {
        path: "/about",
        component: About,
      },
      {
        path: "/user/:abc",
        component: User,
      },
      {
        path: "/profile",
        component: Profile,
      },
    ];
    const router = new VueRouter({
      mode: "history",
      routes,
    });
    
    export default router;
    

    3>App.vue文件

     

    <template>
      <div id="app">
        <!-- <router-link to="/home" replace>首页</router-link>
        <router-link to="/about" replace>导航</router-link> -->
        <!-- <button @click="homeClick">首页</button>
        <button @click="aboutClick">关于</button>
        <button></button> -->
        <router-link to="/home" replace>首页</router-link>
        <router-link to="/about" replace>关于</router-link>
        <router-link :to="'/user/' + userid" replace>用户</router-link>
        <!-- <router-link to="/profile">档案</router-link> -->
        <router-link :to="{ path: '/profile', query: { name: 'why', age: 18 } }"  //这里用的是query
          >档案</router-link
        >
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    // import HelloWorld from "./components/HelloWorld.vue";
    
    export default {
      name: "App",
      data() {
        return {
          userid: "张三",
        };
      },
      methods: {
        //通过代码的方式来修改路径
        homeClick() {
          //所有的组件都有一个属性:router  来自vue-router
          this.$router.push("/home");
        },
        aboutClick() {
          this.$router.push("/about");
        },
      },
    };
    </script>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    .active {
      color: "red";
    }
    </style>
    

      

    4>需改profile文件

    <template>
      <div>
        <h2>我是档案</h2>
        <p>我是档案内容</p>
        <p>{{ $route.query.name }}</p>
      </div>
    </template>
    <script>
    export default {
      name: "Profile",
      data() {
        return {
          message: "张三",
        };
      },
    };
    </script>
    <style></style>
    

    5>修改app.vue文件

    <template>
      <div id="app">
        <!-- <router-link to="/home" replace>首页</router-link>
        <router-link to="/about" replace>导航</router-link> -->
        <!-- <button @click="homeClick">首页</button>
        <button @click="aboutClick">关于</button>
        <button></button> -->
        <router-link to="/home" replace>首页</router-link>
        <router-link to="/about" replace>关于</router-link>
        <router-link :to="'/user/' + userid" replace>用户</router-link>
        <!-- <router-link to="/profile">档案</router-link> -->
        <router-link :to="{ path: '/profile', query: { name: 'why', age: 18 } }"
          >档案</router-link
        >
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    // import HelloWorld from "./components/HelloWorld.vue";
    
    export default {
      name: "App",
      data() {
        return {
          userid: "张三",
        };
      },
      methods: {
        //通过代码的方式来修改路径
        homeClick() {
          //所有的组件都有一个属性:router  来自vue-router
          this.$router.push("/home");
        },
        aboutClick() {
          this.$router.push("/about");
        },
        profileClick() {
          this.router.push({
            path: "/profile",
            query: {
              name: "profile",
              age: 18,
              height: 1.87,
            },
          });
        },
      },
    };
    </script>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    .active {
      color: "red";
    }
    </style>

    五.vue-router导航守卫

    为什么要使用导航守卫?

    网页标题是通过title来显示但是只有一个固定的HTML,切换不同的页面时,标题并不会改变

    但是可以通过js来修改title内容,window.document.title ='新的标题'

    第一种通过代码来实现

    (1)修改home.vue文件

    export default {
      name: "Home",
      data() {
        return {
          message: "张三",
        };
      },
      created() {
        document.title = "首页"; //这一部分
      },
    };
    

    (2)修改index.js文件

    import Vue from "vue";
    import VueRouter from "vue-router";
    // import Home from "../components/Home.vue";
    // import About from "../components/About.vue";
    // import User from "../components/User.vue";
    
    const Home = () => import("../components/Home.vue");
    const HomeNews = () => import("../components/HomeNews.vue");
    const HomeMessage = () => import("../components/HomeMessage.vue");
    const About = () => import("../components/About.vue");
    const User = () => import("../components/User.vue");
    const Profile = () => import("../components/Profile.vue");
    //1.通过vue.use安装插件
    Vue.use(VueRouter);
    
    //2.创建vuerouter对象
    const routes = [
      {
        path: "",
        redirect: "/home",
      },
      {
        path: "/home",
        component: Home,
        children: [
          { path: "", redirect: "news" },
          {
            path: "news",
            component: HomeNews,
          },
          {
            path: "message",
            component: HomeMessage,
          },
        ],
      },
      {
        path: "/about",
        component: About,
      },
      {
        path: "/user/:abc",
        component: User,
      },
      {
        path: "/profile",
        component: Profile,
      },
    ];
    const router = new VueRouter({
      mode: "history",
      routes,
    });
    
    router.beforeEach((to, from, next) => {
      document.title = to.matched[0].meta.title;
      console.log(to);
      next();
    });
    
    export default router;

    第二种:通过配置来实现 

    {
        path: "/about",
        component: About,
        meta: {
          title: "关于",
        },
      },

    index.js文件

    //前置钩子
    router.beforeEach((to, from, next) => { document.title = to.matched[0].meta.title; console.log(to); next(); }); 

     后置钩子:afterEach

       全局守卫(上面的代码就是全局守卫) 

              路由独享守卫

             组件内守卫

    六.keep-alive

  • 相关阅读:
    设计模式(一)工厂模式Factory(创建型)
    Caused by: org.springframework.beans.factory.BeanCreationException
    从Delphi 7升级到Delphi XE
    system strategies of Resources Deadlock
    Service Manager流程,派BC_REPLY,唤醒FregServer流程,返回BR_TRANSACTION_COMPLETE,睡眠等待proc-&gt;wait
    Sqlserver2000联系Oracle11G数据库进行实时数据的同步
    火柴移动面试题
    Eclipse4.4设备egit插件提交本地项目代码到远程仓库
    V离MWare至Openstack至FDIO
    【BZOJ1791】【IOI2008】【基环树】island(status第一速度)
  • 原文地址:https://www.cnblogs.com/zmztya/p/14438232.html
Copyright © 2011-2022 走看看