美文网首页vue
Vue CLI——路由传参 & 路由进阶 & 路由缓存

Vue CLI——路由传参 & 路由进阶 & 路由缓存

作者: 叽里咕呱 | 来源:发表于2021-12-15 19:09 被阅读0次

    一、路由传参

    1. params 参数

    (1)params 参数

    路由配置

    {
        // 注意:这里的路由需要传一个参数,路由可以传多个参数
        // 如果是多个参数,可以写 /type/:id/:name
        path:'/type/:id',
        // 设置该选项为true,组件可以通过props选项接收路由参数
        props:true,
        component:Type
    }
    

    页面

    <router-link to="/type/1001">南京</router-link>
    <router-link to="/type/1002">无锡</router-link>
    
    <h2>{{ city.name }}</h2>
    <p>{{ city.content }}</p>
    
    // 使用props选项接收路由参数
    props:["id"],
      data() {
        return {
          city: {
            id: 0,
            name: "",
            content: "",
          },
          list: [
            {
              id: 1001,
              name: "南京",
              content: "南京的盐水鸭真好吃"
            },
            {
              id: 1002,
              name: "镇江",
              content: "镇江的锅盖面真好吃"
            }
          ],
        };
      },
      methods: {
        getData() {
          this.city = this.list.find((r) => r.id == this.id);
        },
      },
      created() {
        // $route返回的是当前路由信息,它身上有一个params属性,该属性里面保存的是当前路由信息的参数。
        // 这种方法无法更新路由页面 
        // let {params: { id }} = this.$route;
        // this.city = this.list.find((r) => r.id == id);
      },
      watch: {
        // 监视id的变化
        id: {
          immediate: true,
          handler() {
            this.getData();
          },
        },
      },
    

    (2)v-html指令

    v-html指令,可以渲染富文本内容(包含html信息的内容)。
    v-text指令,渲染文本内容。
    当需要渲染的数据是html内容时,使用v-html指定。

    <!-- 所有由ref修饰的组件或标签,都会保存到$refs中 -->
    <!-- <div ref="content"></div> -->
    <!-- v-html指令,用于渲染html内容 -->
    <div v-html="city.content"></div>
    <!-- v-text指令,用于渲染文本内容 -->
    <!-- <div v-text="city.content"></div> -->
    
      data() {
        return {
          city: {
            id: 0,
            name: "",
            content: "",
          },
          list: [
            {
              id: 1001,
              name: "南京",
              content: `
                 <ul>
                    <li>南京的盐水鸭真好吃</li>
                    <li>南京的老门东真好玩</li>
                 </ul>
              `,
            },
            {
              id: 1002,
              name: "镇江",
              content: `
                 <div>
                    <button>镇江</button>
                    <img src="https://img0.baidu.com/it/u=4141467167,4004418012&fm=26&fmt=auto">
                 </div>
              `,
            }
          ],
        };
      },
    mounted() {
        this.$refs.content.innerHTML = this.city.content
    },
    

    效果:点击城市名切换对应信息

    2、query参数

    路由地址,采用query传参方式:?参数1=XXX&参数2=XXX

    <router-link to="/news?id=1001">一坡一岭,护好美丽中国鲜明底色</router-link>
    <router-link to="/news?id=1002">刘诗诗陈妍希一起练瑜伽</router-link>
    
    <div class="news">
      <h2>{{ news.name }}</h2>
      <div v-html="news.content"></div>
    </div>
    
      data() {
        return {
          news: {
            id: 0,
            name: "",
            content: "",
          },
          list: [
            {
              id: 1001,
              name: "一坡一岭,护好美丽中国鲜明底色",
              content: `
                 <div>
                    梯田层层绕山腰,五谷瓜果栽满沟,陕西省米脂县银州街道高西沟村,昔日荒山换新颜。
                 </div>
              `,
            },
            {
              id: 1002,
              name: "刘诗诗陈妍希一起练瑜伽",
              content: `
                 <div>
                    <p>与众好友一起拍照的刘诗诗,扎着丸子头蜷着腿率性地坐在瑜伽垫上,只见她一手撑地一手比耶,心情看上去十分不错。</p>
                    <img src="https://inews.gtimg.com/newsapp_bt/0/14290991287/1000">
                 </div>
              `,
            }
          ],
        };
      },
      methods: {
        getData(){
          let { query: { id } } = this.$route;
          this.news = this.list.find((r) => r.id == id);
        }
      },
      watch: {
        $route: {
           immediate:true,
           handler(){
             this.getData()
           }
        }
      },
    

    效果:点击新闻标题切换对应信息

    3、$router和$route

    $router返回的是当前项目中的路由器对象。
    $route返回的是当前路由信息。

    4、vue.config.js

    vue.config.js 是一个可选的配置文件,如果项目的 (和 package.json 同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service 自动加载。

    // 引入nodejs内置模块path
    let path = require('path')
    // 注意:该配置文件中,只能使用commonjs模块化语法
    module.exports = {
        // 关闭 eslint-loader 语法检查
        lintOnSave:false,
        // 配置devServer开发服务器
        devServer:{
            // 端口号
            port: 5566,
            // 自动打开
            open:true,
            // 静态资源路径
            // 注意:__dirname是nodejs的内置变量,返回的是的当前项目的绝对路径
            // contentBase: path.join(__dirname, "static")
        },
        // 用于配置原生的Webpack配置
        configureWebpack:{
            // 解析
            resolve:{
                // 定义路径别名
                alias:{
                    "@c":path.resolve(__dirname,'src/components'),
                    "@p":path.resolve(__dirname,'src/pages'),
                    "@a":path.resolve(__dirname,'src/apis'),
                    "@u":path.resolve(__dirname,'src/utils'),
                }
            }
        }
    }
    

    二、添加路由

    1、路由规则redirect属性重定向

    redirect属性:进行重定向URL地址。

    {
        path:'/index',
        // 重定向到指定的路由/home
        redirect:'/home'
    },
    

    2、添加404路由

    // *号,表示匹配不上的所有路由(未配置的所有路由地址)
    {
        path:'*',
        component:Error404
    }
    

    3、命名路由

    命名路由:在routes配置中给某个路由设置名称。
    在跳转路由时,可以根据路由的名称(name)去跳转。

    (1)params参数

    {
        name:'type',
        path:'/type/:id',
        props:true,
        component:Type
    }
    

    页面

    <router-link :to="{name:'type',params:{id:1001}}">南京</router-link>
    <router-link to="/type/1002">无锡</router-link>
    

    (2)query参数

    {
        name:'news',
        path:'/news',
        component:News
    }
    

    页面

    <router-link :to="{name:'news',query:{id:1001}}">一坡一岭,护好美丽中国鲜明底色</router-link>
    <router-link to="/news?id=1002">刘诗诗陈妍希一起练瑜伽</router-link>
    

    三、路由进阶

    1、路由模式

    路由模式有两种:hash模式(默认) 和 history模式。
    hash模式:使用的是锚链接的原理实现路由的跳转,这种方式兼容性非常好;缺点是路径带有#号,不够美观。
    history模式:使用的是浏览器中内置的history对象实现路由的跳转,这种方式不兼容老版本的浏览器,刷新后会丢失路由信息。

    mode:'hash'
    

    2、路由元信息

    meta选项:用于配置路由的元信息,里面的内容是自定义的,用于配置路由的数据。

    {
        path:'/',
        name:'home',
        meta:{
            title:'首页',
            //  可以在路由元信息里面配置路由的访问权限
            roles:['admin','vip','user']
        },
        // 路由组件懒加载
        component:()=>import('../pages/Home.vue'),
    }
    

    3、导航守卫

    vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。其实,导航守卫就是路由跳转过程中的一些钩子函数。

    (1)前置守卫--路由跳转之前

    使用 router.beforeEach 注册一个全局前置守卫。每次跳转路由之前,都会拦截,next方法表示下一步。通常在这里会做一些权限验证操作。
    to:返回去哪里的路由信息
    from:返回从哪来的路由信息
    next方法:用于跳转

    // 定义路由前置守卫
    // 每次跳转路由之前,都会拦截,next方法表示下一步
    router.beforeEach((to,from,next)=>{
      // 获取浏览器的缓存中,保存的当前登录用户的权限
      let role = sessionStorage.getItem('role')
      // 验证用户访问权限
      if(to.meta.roles && to.meta.roles.includes(role)){
        // next()方法,表示继续向下执行
        next()
      }
    })
    

    (2)后置守卫--路由跳转完成

    使用 router.afterEach 注册一个后置守卫。通常在这里会做一些页面的修改操作

    router.afterEach((to,from)=>{
      // 配置当前页的标题
      document.title = to.meta.title
    })
    

    4、nprogress加载进度条

    nprogress是页面跳转时出现在浏览器顶部的进度条。

    (1)安装

    npm install nprogress
    

    (2)导入

    // 导入nprogress
    import NProgress from "nprogress";
    // 导入nprogress的样式
    import "nprogress/nprogress.css";
    

    (3)在导航守卫中使用

    // 导航守卫
    // 1.路由前置守卫--路由跳转之前
    router.beforeEach((to, from, next) => {
      // 开启loading
      NProgress.start();
      // 通常:在这里会做一些权限验证操作
      next();
    });
    
    // 2.路由后置守卫--路由跳转完成
    router.afterEach((to, from) => {
      // 通常:在这里会做一些页面的修改操作
      document.title = to.meta.title;
      // 结束loading
      NProgress.done();
    });
    

    5、二级路由

    需要先定义一级路由组件,确定好在哪个组件中配置二级路由,就去那个组件的配置规则中添加children关键字,按照一级路由的配置方法配置规则。

      {
        path: '/one',
        name: 'One',
        component: ()=>import('@v/One.vue'),
        meta:{
          title:'One',
          roles:['admin']
        },
        //定义one的二级路由信息
        children:[
          {
            path:'nj',
            name:'nj',
            // 采用路由懒加载的方式,导入组件
            component:()=>import('../views/city/Nj.vue'),
            meta:{
              title:'南京'
            }
          },
          {
            path:'sz',
            name:'sz',
            component:()=>import('../views/city/Sz.vue'),
            meta:{
              title:'深圳'
            }
          }
        ]
      },
    

    App.vue

    <router-link to="/">Home</router-link> |
    <router-link to="/one">One</router-link> |
    <router-link to="/two">Two</router-link> |
    <!-- 该路由视图,匹配一级路由 -->
    <router-view></router-view>
    

    One.vue

    <router-link to="/one/nj">南京</router-link> | 
    <router-link to="/one/sz">深圳</router-link> |
    <!-- 这里的路由视图,匹配one的二级路由 -->
    <router-view></router-view>
    

    6、路由懒加载

    使用路由懒加载,是为了给客户更好的体验,首页组件加载速度更快一些,提高首屏性能。
    懒加载简单来说就是延迟加载或按需加载,即在需要的时候的时候进行加载。

    // 路由组件懒加载
    component:()=>import('../pages/Home.vue')
    

    7、路由分组懒加载

    有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用命名 chunk,一个特殊的注释语法来提供 chunk name。

    component: ()=>import(/* webpackChunkName: "a" */'../views/Home.vue')
    component: () => import(/* webpackChunkName: "a" */'../views/About.vue')
    component: () => import(/* webpackChunkName: "b" */'../views/One.vue')
    component: () => import(/* webpackChunkName: "b" */'../views/Two.vue')
    

    8、scoped

    scoped属性,用于设置局部样式,当前组件中的样式只对当前组件生效。
    注意:App组件中的样式是全局样式,通常不加scoped。

    <style scoped>
        ....
    </style>
    

    9、sass

    Sass 是一个 CSS 预处理器。使用sass可以定义嵌套定义样式,大大节省css代码;使用sass可以使用定义变量,可以统一定义风格。

    (1)安装

    npm install sass sass-loader@8 -D
    

    (2)使用

    &符号表示当前元素。常见的两种用法:伪类选择器和伪元素。

    <div class="one">
        <h2>One</h2>
        <div class="province">
          江苏省
          <div class="city">
            南京省
            <div class="district">
              雨花台区
              <div class="street">赛虹桥街道</div>
            </div>
          </div>
        </div>
        <h3>南京的鸭血粉丝真好吃</h3>
        <p>南京的盐水鸭真好吃</p>
    </div>
    
    <style scoped lang="scss">
    $red:darkred;
    .about{
      border: 1px solid black;
      padding: 5px;
      h2{
        color:black;
      }
      h3{
        color: $red;
      }
      p{
        color: $red;
      }
      .province{
        color: $red;
        font-size: 30px;
        .city{
          color: green;
          font-size: 25px;
          .district{
            color: blue;
            font-size: 20px;
            .street{
              color: orange;
              font-size: 15px;
            }
          }
        }
      }
    }
    </style>
    

    效果:

    10、less

    less 也是一个 CSS 预处理器。
    注意:在less里面定义变量的符号是@。

    (1)安装

    npm i less@3 -D
    npm i less-loader@7 -D
    

    (2)使用

    <style scoped lang="less">
    @red:darkred;
    .one {
      border: 1px solid black;
      padding: 5px;
      h2{
        color:black;
      }
      h3{
        color: @red;
      }
      p{
        color: @red;
      }
      .province{
        color: @red;
        font-size: 30px;
        .city{
          color: green;
          font-size: 25px;
          .district{
            color: blue;
            font-size: 20px;
            .street{
              color: orange;
              font-size: 15px;
            }
          }
        }
      }
    }
    </style>
    

    效果:

    四、路由缓存

    1、keep-alive组件

    keep-alive:用于缓存路由组件,默认情况下会缓存打开的所有组件。如果需要指定缓存哪些组件,通过include属性指定,该属性可以传一个数组,数组中定义组件的名称。
    作用:通过路由缓存,组件之间的切换就能保存上个组件的状态,而不是切换之后又得重新操作。

    <keep-alive :include="['Two','Three']">
      <router-view/>
    </keep-alive>
    

    2、路由组件特有的两个生命周期

    当路由组件采用缓存后,created和mounted这两个生命周期函数,只会在第一次执行;并且destroyed这个生命周期函数不会执行。
    这时候,通常都会配合activated(路由组件激活状态生命周期函数)和deactivated(路由组件失活状态生命周期函数)这两个生命周期钩子。
    注意:只有当组件在 <keep-alive> 内被切换,才会有activated 和 deactivated 这两个钩子函数。

        // 路由组件激活状态生命周期函数
        activated() {
            console.log('路由组件激活');
            // 开启定时器
            this.timer = setInterval(()=>{
                this.count++
            },1000)
        },
        // 路由组件失活状态生命周期函数
        deactivated() {
            console.log('路由组件失活');
            clearInterval(this.timer)
        }
    

    相关文章

      网友评论

        本文标题:Vue CLI——路由传参 & 路由进阶 & 路由缓存

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