vuejs中如何实现路由切换及路由的缓存

本文详细介绍了在Vue.js中如何实现路由切换,包括安装和使用vue-router,设置路由激活样式,配置默认路由,处理404页面,以及使用ElementUI组件进行导航。此外,还讲解了如何实现路由组件的缓存,以保持用户表单数据不丢失,提升用户体验。

虽互不曾谋面,但希望能和您成为笔尖下的朋友

以读书,技术,生活为主,偶尔撒点鸡汤

不作,不敷衍,意在真诚吐露,用心分享

点击左上方,可关注本刊

标星公众号(ID:itclanCoder)

如果不知道如何操作

点击这里,标星不迷路

前言

我们知道在vue项目里,实现路由的跳转是使用router-link标签,由于导航链接不止一个,在模板里写死导航的话,不是很灵活

我们往往是结合现成的UI框架,一些现成的组件,快速的去实现我们的导航,路由的跳转等

而当切换导航时,若有表单数据,想要保留表单的数据,那应该怎么实现呢,一起来学习下

01

使用vue-router

1. 安装vue-router

npm install -D vue-router@3   // 注意:如果没有加后面的3,默认安装的是vue-router@4.0的版本

2. 引入vue-router

导入VueVueRouter,还要调用Vue.use(VueRouter)

import Vue from 'vue';   // 引入vue
import VueRouter from 'vue-router';   // 引入vueRouter,引入VueRouter函数

3. 调用Vue.use(VueRouter)

// 省略...
// 使用插件的方式注入
Vue.use(VueRouter);

4. 引入路由组件

通过import关键字引入在pages文件夹下定义好的路由组件

import XXX from 'xxxx.vue'

5. 定义路由

每个路由应该映射一个组件。其中component 可以是静态组件,也可以是懒加载组件

const routes = [
   {
     name:'组件名称1',
     path: '路径1',
     component: xxx1,  // 组件名
   },
    {
     name:'组件名称2',
     path: '路径2',
     component: xxx2,  // 组件名
   },
]

6. 构造VueRouter实例化对象

使用new VueRouter创建 router 实例,接收一配置对象,然后传 routes 配置

const router = new VueRouter({
  routes // (缩写) 相当于 routes: routes
})

7. 创建和挂载根实例

导出路由router对象,然后在根实例中注入

要通过 router 配置参数注入路由

const app = new Vue({
  router
}).$mount('#app')

8. 模板中使用router-link

在模板中使用router-link结合to进行路由的设置和跳转

<router-link to='路径'></router-link>


02

实现路由的切换

在模板中我们使用router-link实现路由的跳转,并且要展示的内容视图,使用router-view代码如下所示

<template>
  <div id="app">
      
      <router-link :to="item.path" v-for="item in routers" :key="item.path" >{{item.name}}</router-link>
    
      <router-view></router-view>
  </div>
</template>

<script>
// import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    // HelloWorld
  },
  data() {
    return {
      routers: [
        {
          path: '/recent',
          name: '最新文章'
        },
        {
          path: '/fontend',
          name: '前端'
        }
      ]
    }
  }
}
</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>

那在路由文件中如何进行配置呢,如下代码所示

import Vue from 'vue';
import VueRouter from "vue-router";

Vue.use(VueRouter);
// 实例化router对象
const router = new VueRouter({
    routes: [
        {
            path: '/recent',
            name: 'recent',
            component: () => import('../pages/RecentArticle/RecentArticle.vue')   // 路由的懒加载
        },
        {
            path: '/fontend',
            name: 'fontend',
            component: () => import('../pages/FontEnd/FontEnd.vue')
        },
    ],
    
})



export default router;

此时经过这样操作之后,可以实现路由的切换和展示,但是问题来了,我想要给当前激活路由添加样式,用于区别未激活的路由,那该怎么办?

03

如何设置当前路由激活样式

vue-router路由的实例化对象配置中,可以设置一个linkActiveClass的属性,全局配置激活class的样式

const router = new VueRouter({
    linkActiveClass: 'active',   // 后面是自己自定义的激活类名
    // 其他不变
})

在对应的组件中添加激活样式的类名

.active {
    color: red;
}

当然,你也可以在router-link上局部添加

<router-link active-class="active" to="路径"></router-link>


04

如何设置默认路由

当我们启动一个项目时,希望它自动的跳转到我们指定的路由上,也就当用户访问https://域名/端口/时,默认的跳转到一个路由上,这个该怎么实现呢

通过路由的重定向(redirect)实现的,同样是在routes中进行配置,如下代码所示

import Vue from 'vue';
import VueRouter from "vue-router";

Vue.use(VueRouter);
// 实例化router对象
const router = new VueRouter({
    linkActiveClass: 'active',
    routes: [
        {
            path: '/',              // 访问根路径时
            // redirect: '/recent'  // 重定向到某个路由
            redirect: {             // 与上面等价
                name: 'recent'
            }
        },
        {
            path: '/recent',
            name: 'recent',
            component: () => import('../pages/RecentArticle/RecentArticle.vue')   // 路由的懒加载
        },
        {
            path: '/fontend',
            name: 'fontend',
            component: () => import('../pages/FontEnd/FontEnd.vue')
        },
    ],
    
})



export default router;

当我们访问网站时,由于设置了重定向,默认的会跳转到指定的路由组件上,可以直接使用redirect: '路径',或者使用redirect: { name: '路由命名'}


05

当访问路由不存时,显示404

当用户访问的页面不存在时,手动输入的路由不存在,可以直接重定向到首页,也可以直接展示一个404页面

使用的是*符号,会进行全局匹配,如果没有匹配到相对应的路由,那么就重定向到这个notFound路由页面

{
    path: '/404',
    name: 'notFound',
    component: notFound
 },
{
    path: "*",
    redirect: {
        name:'notFound'
    },
    component: notFound
},


06

使用ElementUI中的组件实现导航切换

上面我们是使用vue-router中提供的router-link实现的路由跳转,但我们在实际项目开发里,都是使用现成的一些UI框架

进行快速的开发,毕竟用现成的UI框架,开发快

对于要求不是很严格的项目,使用成熟的UI框架,就是要快,能快速实现业务即可,具体还是要看实际的项目

哪有那么多时间和精力,让你造轮子,写css样式呢

这里我以elementUI框架为例,如果你是vue3的项目,可以使用elementplus

1. 安装elementUI

npm install -D element-ui

2. 引入ElementUI

这里以全局引入,在main.js中引入如下内容(当然也是可以按需引入的)

import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';


Vue.use(ElementUI);

然后我们将原先的代码替换成elementUI组件当中的按钮样式的单选组合组件,如下代码所示

<template>
  <div id="app">
      <el-radio-group v-model="radio" v-for="item in routers" :key="item.name" @change="handleRadioRoute">
          <el-radio-button :label="item.path">{{item.name}}</el-radio-button>
      </el-radio-group>
      <!-- 内容展示 -->
      <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App',
  components: {
    // HelloWorld
  },
  data() {
    return {
      radio: '/recent',
      routers: [
        {
          path: '/recent',
          name: '最新文章'
        },
        {
          path: '/fontend',
          name: '前端'
        }
      ]
    }
  },
  methods: {
    // 绑定事件
    handleRadioRoute(val){
       console.log(val);
       this.$router.push({
          path:val
       })
    }
  }
}
</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>

对比之前的实现,如下代码所示,是使用router-link实现

<template>
  <div id="app">
      
      <router-link active-class="active" :to="item.path" v-for="item in routers" :key="item.path" >{{item.name}}</router-link>
    
      <router-view></router-view>
  </div>
</template>

<script>
// import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    // HelloWorld
  },
  data() {
    return {
      routers: [
        {
          path: '/recent',
          name: '最新文章'
        },
        {
          path: '/fontend',
          name: '前端'
        }
      ]
    }
  }
}
</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>

你会发现,如果你使用的是btton组件进行路由的跳转,那么就需要使用vue-router中的编程式导航,也就是this.$router.push({})这种方式

我们发现,上面的编程式导航实现的路由跳转不是很优雅.对于激活的按钮到底是用路径还是名字,保持对应一致就可以了的

radio默认初始值也可以设置为空,去监听路由,从路由中拿到的,并赋值的,如下代码所示

<template>
  <div id="app">
      <el-radio-group v-model="radio" 
                      v-for="item in routers" 
                      :key="item.name" 
                      @change="handleRadioRoute" >
        <el-radio-button :label="item.path" >{{item.name}}</el-radio-button>
      </el-radio-group>
    
      <router-view></router-view>
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {
   
  },
  data() {
    return {
      radio: '',
      routers: [
        {
          path: '/recent',
          name: '最新文章'
        },
        {
          path: '/fontend',
          name: '前端'
        }
      ]
    }
  },
  methods: {
    handleRadioRoute(val){
       console.log(val);
       this.$router.push({
          path:val
       })
    }
  },

  watch: {
    // 监听路由,当前菜单
    $route: {
       handler(val) {
         console.log(val);
         this.radio = val.path;
       },
       immediate: true,   // 初始化时,就调用一次handler函数
    }
  }
}
</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>


07

如何缓存路由组件

让不展示的路由组件保持挂载,不被销毁

在路由的切换当中,只要切换到另一个路由组件上,前一个组件就会随之销毁,应证这个的话,可以借用destoryed生命周期进行测试的

在用户填写表单的时候,如果切换到另一个路由上,在回来,之前填写的数据都会丢失,如何保证用户之前填写的数据不丢失呢,就可以使用缓存路由组件

<keep-alive include='要缓存的组件名字,组件命名的那个name,而非路由那个name'>
   <router-view></router-view>
</keep-alive>

router-view外面包裹keep-alive组件包裹,不要包裹错了的

如果要缓存多个路由组件,直接:include='[路由组件名称1,路由组件名称2]'

缓存路由组件就是为了提升用户体验的,增加组件的性能

总结

vuejs中如何实现动态路由切换及路由的缓存,是一个非常重要的知识点,可以这么说,如果对路由不熟悉,那基本上是没法干活,它的知识点虽然不多

但是比较零散,使用路由必须要使用vue-router这个插件,然后进行一些配置,才可以使用

以及如何设置路由的激活样式,与传统的开发模式,是不一样的,有些东西,并不需要原生的去实现,根据vue-router提供的规则就可以实现

以及如何实现默认路由,以及使用elementUI中提供的组件实现路由的切换,还有如何缓存路由组件

VueJs中的编程式导航VS声明式导航

2022-07-20

7f6b53c68fc67a98ceb537d32d5cbfa0.jpeg

vuejs中路由的传参以及路由props配置

2022-07-17

4058a397d293ddf2ba47743f79f2f189.jpeg

暖暖聊天恋爱对话(套餐卡)

2022-07-13

a2529f9c63e67a1299c6d0c85cdde729.jpeg

第6节-服务器,ip,域名三者的一个关系

2022-07-09

13cec72120c6fabc44c7bbcec7820c5a.jpeg

第5节-如何选择一个有意义价值的域名

2022-07-09

c75c364292f54889815b6e97096a581b.jpeg

第4节-建设一个什么样的网站

2022-07-09

0a3d4d66cb09e72f8112fc4028661f7c.jpeg

第3节-怎么去做网站-选择最合适的技术

2022-07-09

259b648d44d6e9f43ddf1702d7e17fd3.jpeg

第2节-为什么有必要去建站开发应用

2022-07-09

74bc37e3663aee4d3b474c8de2f71d1b.jpeg

点个在看你最好看

4d80281d8a40ab678a76936fbd2c4b49.png

c138187b2c700e8b1f9c73c3bde23521.png

ca5eed9ff7b5bc6888c41c2eeeeb013f.png

点击下方阅读原文可了解更多

<think>首先,用户的问题是关于 Vue2 的:路由跳转正常(URL 变化了),但页面组件没有更新。我需要参考提供的引用,并给出解决方案。 关键引用: - 引用[1]:提到在 Vue 中,如果菜单使用 element-ui 的 menu 组件,index 值不能重复。还建议检查路由文件中的 path 和 component 名字是否正确。如果 index 没有重复,但页面不变,可以尝试在 router-view 标签加上 key。 - 引用[3]:在 Vue3 中,三级路由跳转成功但页面未刷新,解决方案是确保路由配置正确,并提到了 key 属性。 - 引用[5]:Vue 使用 vue-router 路由跳转页面数据未更新,原因是使用了 keep-alive 组件缓存。解决方案包括使用 activated 生命周期钩子或 watch $route。 用户的问题是针对 Vue2 的,所以我需要调整这些方案到 Vue2。 常见原因: 1. **路由配置错误**:path 或 component 定义不正确。 2. **组件重用**:由于相同组件被重用,生命周期钩子如 created 或 mounted 不会被调用。 3. **keep-alive 缓存**:如果使用了 keep-alive,组件会被缓存。 4. **key 属性缺失**:在 router-view 上添加 key 可以强制重新渲染。 5. **菜单或导航组件问题**:如 element-ui menu 的 index 值重复。 解决方案: - 检查路由配置:确保 path 和 component 正确。 - 添加 key 到 router-view:例如,<router-view :key="$route.fullPath">,这样每次路由变化时组件会重新渲染。 - 处理缓存:如果使用了 keep-alive,使用 activated 钩子或 watch $route 来更新数据。 - 确保菜单 index 唯一:如果使用 element-ui,确保每个菜单项的 index 值不同。 回答结构: 1. **问题原因**:解释为什么页面组件没有更新。 2. **解决方案**:列出步骤或方法。 3. **代码示例**:提供 Vue2 的代码片段。 4. **相关问题**:生成相关问题。 生成相关问题: - 基于用户问题,生成关于 Vue2 路由页面更新、优化等的问题。 使用中文回答。</think>### Vue2 路由跳转正常但页面组件未更新的原因和解决方案 在 Vue2 中使用 vue-router 时,路由跳转成功(URL 变化),但页面组件未更新,这是一个常见问题。这通常是由于组件重用、缓存机制或配置错误导致的。下面我将一步步分析原因并提供解决方案,确保回答真实可靠(基于 Vue2 官方文档和社区最佳实践)。 #### 问题原因 1. **组件重用**:vue-router 默认会复用相同组件(例如,从 `/user/1` 跳转到 `/user/2`),导致生命周期钩子(如 `created` 或 `mounted`)不被触发[^5]。 2. **keep-alive 缓存**:如果父组件使用了 `<keep-alive>`,子组件会被缓存数据不会自动更新[^5]。 3. **路由配置错误**:path 或 component 定义不正确(如路径重复或组件名错误),导致 vue-router 无法匹配到新组件[^1][^3]。 4. **菜单或导航组件问题**:在使用 element-ui 等 UI 库时,菜单项的 `index` 值重复,会阻止路由切换[^1]。 5. **缺少 key 属性**:`<router-view>` 未设置 key,无法强制组件重新渲染[^1][^3]。 #### 解决方案 以下是针对 Vue2 的实用解决方案,按优先级排序: 1. **添加 key 到 `<router-view>`** 在模板中添加 `:key="$route.fullPath"`,强制每次路由变化时重新渲染组件。 ```vue <template> <router-view :key="$route.fullPath"></router-view> </template> ``` - **原理**:key 的变化会触发组件销毁和重建,确保生命周期钩子执行[^1][^3]。 - **适用场景**:简单通用,适用于大多数情况。 2. **处理组件重用或缓存** 如果使用了 `<keep-alive>` 或组件复用,使用以下方法更新数据: - **在 `watch` 中监听路由变化**: ```javascript export default { watch: { '$route'(to, from) { // 路由变化时执行数据更新 this.fetchData(); // 替换为你的数据加载方法 } }, methods: { fetchData() { // 根据 this.$route.query 或 this.$route.params 获取参数 const id = this.$route.query.id; // 调用 API 或更新状态 } } } ``` - **使用 `activated` 生命周期钩子**(仅当组件被 `<keep-alive>` 缓存时有效): ```javascript export default { activated() { this.fetchData(); // 组件激活时更新数据 } } ``` - **原理**:`watch` 或 `activated` 可以绕过缓存机制,响应路由变化[^5]。 3. **检查路由配置** 确保路由文件(通常是 `router/index.js`)中 path 和 component 正确无误: ```javascript // router/index.js import Vue from 'vue'; import Router from 'vue-router'; import UserList from '@/views/UserList.vue'; import UserDetail from '@/views/UserDetail.vue'; Vue.use(Router); export default new Router({ routes: [ { path: '/users', // 路径必须唯一 component: UserList, children: [ { path: 'detail/:id', // 使用动态参数 component: UserDetail, // 组件名正确导入 name: 'userDetail' } ] } ] }); ``` - **检查点**: - 所有 path 必须唯一(避免重复)。 - component 导入路径正确(区分大小写)。 - 嵌套路由的 children 配置正确[^3]。 4. **确保菜单 index 唯一(如使用 element-ui)** 如果导航菜单基于 element-ui 的 `<el-menu>`,确保每个菜单项的 `index` 值唯一: ```vue <template> <el-menu :router="true"> <el-menu-item index="/users" @click="$router.push('/users')">用户列表</el-menu-item> <el-menu-item index="/users/detail" @click="$router.push('/users/detail')">用户详情</el-menu-item> <!-- index 必须不同 --> </el-menu> </template> ``` - **原理**:index 值重复会导致菜单状态不更新,影响路由跳转[^1]。 5. **验证路由跳转方法** 使用 `router.push` 或 `router.replace` 时,确保参数传递正确: ```javascript // 正确示例:使用 path 或 name 跳转 this.$router.push({ path: '/users/detail', query: { id: 123 } }); // 推荐 // 或 this.$router.push({ name: 'userDetail', params: { id: 123 } }); ``` - **避免错误**:不要混用 `query` 和 `params`,确保目标路由已定义[^4]。 #### 调试建议 - **使用 Vue Devtools**:检查路由状态和组件树,确认组件是否被激活。 - **控制台日志**:在 `mounted` 或 `watch` 中添加 `console.log` 跟踪路由变化。 - **最小化测试**:创建一个简单路由示例(如两个基本组件),排除其他代码干扰。 如果以上步骤无效,可能是 vue-router 版本问题(确保使用 Vue2 兼容版本,如 vue-router@3.x)或外部库冲突。建议参考 [Vue Router 官方文档](https://router.vuejs.org/zh/guide/)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值