前端Vue日常工作中--Vue路由相关

前端Vue日常工作中--Vue路由相关

1.路由模式

Vue 路由模式主要有两种:哈希模式(Hash Mode)和历史模式(History Mode)。

  1. 哈希模式(Hash Mode): 在哈希模式下,URL 中的路径会以 # 符号开头,在这种模式下,实际的路径是在 # 符号之后,而不会触发浏览器向服务器发送请求。这样可以避免浏览器刷新页面时发送请求,适用于单页应用。

    在 Vue 中,默认就是哈希模式,你不需要额外的配置,只需创建一个路由实例即可:

    javascript 复制代码
    import Vue from 'vue';
    import VueRouter from 'vue-router';
    
    Vue.use(VueRouter);
    
    const router = new VueRouter({
      mode: 'hash', // 默认就是 'hash' 模式
      routes: [
        // 路由配置
      ]
    });
  2. 历史模式(History Mode): 在历史模式下,URL 中的路径更具传统的形式,不再带有 # 符号,在这种模式下,需要服务器的支持,以确保在直接访问或刷新页面时能够正确处理路由。

    若要使用历史模式,需要配置 mode'history',并在服务器端进行相关设置。以下是一个基本的配置示例:

    javascript 复制代码
    import Vue from 'vue';
    import VueRouter from 'vue-router';
    
    Vue.use(VueRouter);
    
    const router = new VueRouter({
      mode: 'history', // 使用 'history' 模式
      routes: [
        // 路由配置
      ]
    });

在 Element UI,可以在项目中使用 Element UI 的导航组件如 <el-menu><el-menu-item>,并根据不同的路由模式进行相应的配置。例如,可以在菜单项中使用 <router-link> 组件来实现导航:

html 复制代码
<template>
  <el-menu :default-active="activeMenu" mode="horizontal" @select="handleMenuSelect">
    <el-menu-item index="/home">
      <router-link to="/home">Home</router-link>
    </el-menu-item>
    <el-menu-item index="/about">
      <router-link to="/about">About</router-link>
    </el-menu-item>
  </el-menu>
</template>

<script>
export default {
  data() {
    return {
      activeMenu: '' // 用于记录当前激活的菜单项
    };
  },
  methods: {
    handleMenuSelect(index) {
      this.activeMenu = index;
    }
  }
}
</script>

<router-link> 组件被用于创建带有正确路由的链接,这样用户点击菜单项时就会触发路由切换。在实际项目中,可以根据具体需求配置路由模式,并使用 Element UI 或其他 UI 库提供的组件来构建用户界面。

2. <math xmlns="http://www.w3.org/1998/Math/MathML"> r o u t e r 和 router和 </math>router和route

$router$route 是与路由相关的两个对象,它们分别代表了路由器和当前路由的信息。主要区别如下:

  1. $router:

    • $router 是 Vue 路由器的实例,提供了一系列导航方法,如 pushreplacego,用于在应用程序中进行路由导航。
    • $router 允许你通过编程的方式进行路由跳转,而不依赖于声明式的组件内部导航(例如 <router-link>)。
    • 可以在任何组件中通过 this.$router 访问。
  2. $route:

    • $route 是当前活动的路由对象,包含了当前路由的信息,如路径、参数、查询参数、哈希等。
    • $route 可以用于访问当前路由的各种信息,例如在组件内获取当前路径 this.$route.path,或者获取查询参数 this.$route.query
    • $route 是一个响应式对象,当路由发生变化时,相关组件会自动更新。
html 复制代码
<template>
  <div>
    <p>当前: {{ $route.path }}</p>
    <p>查询参数: {{ $route.query }}</p>

    <el-button @click="goToAbout">Go to About</el-button>
  </div>
</template>

<script>
export default {
  methods: {
    goToAbout() {
      // 使用 $router 进行编程式导航
      this.$router.push('/about');
    }
  }
}
</script>

$route.path 用于获取当前路由的路径,$route.query 用于获取查询参数。$router.push('/about') 使用 $router 对象进行编程式导航,将用户导航到 "/about" 路由。

3.路由跳转

在 Vue 中,常见的路由跳转方式包括:

  1. 声明式导航(Declarative Routing): 使用 <router-link> 组件进行声明式的导航,该组件会自动渲染为合适的 <a> 标签,通过 to 属性指定目标路由。

    html 复制代码
    <template>
      <router-link to="/home">Go to Home</router-link>
    </template>
  2. 编程式导航(Programmatic Routing): 使用 $router 对象进行编程式导航,通常在组件内部的方法中执行。在这里,可以使用 this.$router.push() 来导航到目标路由。

    html 复制代码
    <script>
    export default {
      methods: {
        goToHome() {
          this.$router.push('/home');
        }
      }
    }
    </script>
html 复制代码
<template>
  <div>
    <!-- 声明式导航 -->
    <router-link to="/home">
      <el-button type="primary">Go to Home</el-button>
    </router-link>

    <!-- 编程式导航 -->
    <el-button type="success" @click="goToAbout">Go to About</el-button>
  </div>
</template>

<script>
export default {
  methods: {
    goToAbout() {
      // 使用编程式导航
      this.$router.push('/about');
    }
  }
}
</script>

我们使用了 Element UI 的按钮组件来触发路由的跳转。<router-link> 用于声明式导航,而 this.$router.push() 用于编程式导航。

4.路由守卫

Vue 路由守卫用于在导航过程中对路由进行控制,可以在路由跳转前、跳转后、组件渲染前等不同阶段执行一些代码逻辑。Vue 提供了全局守卫、路由独享守卫、组件内守卫等多种类型的守卫。

  1. 全局前置守卫 (beforeEach): 在路由跳转前执行,常用于进行权限验证或全局设置。

    javascript 复制代码
    import router from './router';
    
    router.beforeEach((to, from, next) => {
      // 在此处进行权限验证或其他逻辑
      if (to.meta.requiresAuth && !isAuthenticated) {
        // 未登录,重定向到登录页
        next('/login');
      } else {
        // 继续路由跳转
        next();
      }
    });
  2. 全局解析守卫 (beforeResolve): 在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后调用。

    javascript 复制代码
    router.beforeResolve((to, from, next) => {
      // 在此处执行解析逻辑
      next();
    });
  3. 全局后置守卫 (afterEach): 在路由跳转后执行,常用于记录日志或进行页面埋点等操作。

    javascript 复制代码
    router.afterEach((to, from) => {
      // 在此处执行后置逻辑
    });
  4. 路由独享守卫 (beforeEnter): 在单个路由配置中定义,对特定路由生效。

    javascript 复制代码
    const router = new VueRouter({
      routes: [
        {
          path: '/admin',
          component: Admin,
          beforeEnter: (to, from, next) => {
            // 在此处执行路由独享守卫逻辑
            if (isAdmin) {
              next();
            } else {
              next('/login');
            }
          }
        }
      ]
    });
  5. 组件内守卫: 在组件内部定义 beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave 方法。

    javascript 复制代码
    export default {
      beforeRouteEnter(to, from, next) {
        // 在组件渲染前执行
        next(vm => {
          // 可以访问实例 `vm`
        });
      },
      beforeRouteUpdate(to, from, next) {
        // 在组件复用时调用
        // 可以访问组件实例 `this`
        next();
      },
      beforeRouteLeave(to, from, next) {
        // 在组件离开时调用
        // 可以访问组件实例 `this`
        next();
      }
    };
javascript 复制代码
router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !isAuthenticated) {
    // 使用 Element UI 的消息框提示用户
    this.$message.error('请先登录');
    // 未登录,重定向到登录页
    next('/login');
  } else {
    // 继续路由跳转
    next();
  }
});

5.路由传参

  1. 路由参数

    通过在路由路径中添加参数,可以使用$route.params来访问这些参数。

    javascript 复制代码
    // 路由配置
    const routes = [
      { path: '/user/:id', component: User }
    ];
    
    // 组件中获取参数
    this.$route.params.id

    Element UI:

    html 复制代码
    <!-- 使用el-link传递参数 -->
    <el-link :to="{ path: '/user/' + userId }">Go to User</el-link>
  2. 查询参数

    使用查询参数,可以通过$route.query来获取。

    javascript 复制代码
    // 路由配置
    const routes = [
      { path: '/user', component: User }
    ];
    
    // 组件中获取参数
    this.$route.query.id

    Element UI:

    html 复制代码
    <!-- 使用el-link传递查询参数 -->
    <el-link :to="{ path: '/user', query: { id: userId }}">Go to User</el-link>
  3. 命名路由

    使用命名路由,可以在$route.params中直接获取。

    javascript 复制代码
    // 路由配置
    const routes = [
      { path: '/user/:id', name: 'user', component: User }
    ];
    
    // 组件中获取参数
    this.$route.params.id

    Element UI:

    html 复制代码
    <!-- 使用el-link传递参数 -->
    <el-link :to="{ name: 'user', params: { id: userId }}">Go to User</el-link>
  4. props传参

    可以通过在路由配置中使用props来直接将参数传递给组件。

    javascript 复制代码
    // 路由配置
    const routes = [
      { path: '/user/:id', component: User, props: true }
    ];
    
    // 组件中通过props接收参数
    props: ['id']

    Element UI:

    html 复制代码
    <!-- 使用el-link传递参数 -->
    <el-link :to="{ path: '/user/' + userId, props: true }">Go to User</el-link>

6.问题:Vue路由解决页面刷新参数丢失的问题

当在Vue应用中刷新页面时,页面的状态和参数通常会丢失,这是因为刷新页面会重新加载整个应用,导致 Vue 实例重新创建。

  1. 使用路由参数

    将页面状态信息放在路由的路径中,以便在刷新页面时能够重新获取。这样,即使刷新页面,路由参数仍然会被保留。

    javascript 复制代码
    // 路由配置
    const routes = [
      { path: '/user/:id', component: User }
    ];
    
    // 在组件中获取参数
    this.$route.params.id

    Element UI 的 el-link

    html 复制代码
    <!-- 使用el-link传递参数 -->
    <el-link :to="{ path: '/user/' + userId }">Go to User</el-link>
  2. 使用localStorage或sessionStorage

    将页面状态信息存储在 localStoragesessionStorage 中,以便在页面刷新时检索。

    javascript 复制代码
    // 存储数据
    localStorage.setItem('userId', userId);
    
    // 获取数据
    const userId = localStorage.getItem('userId');

    在 Vue 组件的生命周期钩子中使用:

    javascript 复制代码
    mounted() {
      const userId = localStorage.getItem('userId');
      // 使用 userId 进行其他操作
    }

    使用 localStoragesessionStorage 存储的数据在页面关闭后仍然存在,需要手动清除或者通过其他方式进行管理。

  3. 使用Vuex

    如果应用状态较为复杂,可以使用 Vuex 来管理全局状态。即使页面刷新,Vuex 中的状态仍然可以被保留。

    javascript 复制代码
    // 在 Vuex store 中定义状态
    state: {
      userId: null
    }
    
    // 在组件中获取状态
    this.$store.state.userId

    在页面刷新后,你需要通过触发某个事件或在应用初始化时从其他地方恢复这些状态。

相关推荐
low神9 分钟前
前端在网络安全攻击问题上能做什么?
前端·安全·web安全
码力码力我爱你1 小时前
QT + WebAssembly + Vue环境搭建
vue.js·vue·wasm·webassembly·emscripten
qbbmnnnnnn1 小时前
【CSS Tricks】如何做一个粒子效果的logo
前端·css
唐家小妹1 小时前
【flex-grow】计算 flex弹性盒子的子元素的宽度大小
前端·javascript·css·html
涔溪1 小时前
uni-app环境搭建
前端·uni-app
安冬的码畜日常1 小时前
【CSS in Depth 2 精译_032】5.4 Grid 网格布局的显示网格与隐式网格(上)
前端·css·css3·html5·网格布局·grid布局·css网格布局
洛千陨1 小时前
element-plus弹窗内分页表格保留勾选项
前端·javascript·vue.js
小小19921 小时前
elementui 单元格添加样式的两种方法
前端·javascript·elementui
完球了1 小时前
【Day02-JS+Vue+Ajax】
javascript·vue.js·笔记·学习·ajax
前端没钱1 小时前
若依Nodejs后台、实现90%以上接口,附体验地址、源码、拓展特色功能
前端·javascript·vue.js·node.js