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

一、路由传参

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)
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容