当前位置: 首页 > news >正文

vue-router(vue 路由)基本使用指南(二)

文章目录

  • 深入使用
    • 导航守卫
    • 重定向与别名
    • history 配置:指定历史模式
    • 路由元信息(meta)
  • 拓展
    • 状态管理(Pinia / Vuex)
      • Pinia / Vuex 介绍
      • Vuex vs Pinia
      • Pinia 基本使用
      • Pinia 使用 Cookies 存储

深入使用

导航守卫

导航守卫用于在路由跳转前、跳转后或解析过程中,添加自定义的逻辑处理,例如权限验证。

  • 全局前置守卫

    router.beforeEach((to, from, next) => {// 例如,验证用户是否已登录if (to.path === '/protected' && !isLoggedIn()) {next('/login'); // 跳转到指定路径} else {next(); // 继续执行路由}
    });
    
    • tofrom 是即将进入的目标路由和当前导航正要离开的路由
    • next 是一个函数,该函数用于控制路由的跳转。
    • next():继续执行路由。
    • next(false):中断当前路由,如果浏览器的 URL 改变了,那么 URL 会回到 from 路由。
    • next(‘/path’):跳转到指定路径。
    • next(error):将控制权交给 router.onError()
  • 全局解析守卫

    全局解析守卫通过 router.beforeResolve 方法设置,它在所有组件内守卫和异步路由组件被解析之后调用。

    router.beforeResolve((to, from, next) => {// 类似于 beforeEach,但是在这个守卫中,所有组件内守卫和异步路由组件被解析之后调用。
    });
    
  • 全局后置钩子

    全局后置钩子通过 router.afterEach 方法设置,它不会接收 next 函数也不会改变导航本身:

    router.afterEach((to, from) => {// 在这里你可以访问路由守卫结束后的状态,但不能改变状态。console.log('路由已切换'); // 例如,记录日志或者统计页面访问等。
    });
    
  • 路由独享守卫

    const routes = [{path: '/admin',component: Admin,beforeEnter: (to, from, next) => {// 仅管理员可访问if (isAdmin()) {next();} else {next('/login');}},},
    ];
    
  • 组件内守卫

    export default {beforeRouteEnter(to, from, next) {// 在路由进入前调用next();},beforeRouteUpdate(to, from, next) {// 在当前路由改变,但组件被复用时调用next();},beforeRouteLeave(to, from, next) {// 在路由离开前调用next();},
    };
    

## 嵌套路由

嵌套路由用于构建具有层级关系的页面结构,即在一个组件内部再嵌套另一个路由视图。

详见:传送门

  • 定义嵌套路由

    const routes = [{path: '/user',component: User,children: [{// 当/user/profile匹配成功,UserProfile将被渲染到User的<router-view>内部path: 'profile',component: UserProfile,},{path: 'posts',component: UserPosts,},],},
    ];
    

    注意,以 / 开头的嵌套路径将被视为根路径。这允许你利用组件嵌套,而不必使用嵌套的 URL

  • 在父组件模板中

    <template><div><h2>用户页面</h2><router-view></router-view> <!-- 渲染子路由组件 --></div>
    </template>
    

重定向与别名

重定向:也是通过 routes 配置来完成

  • 示例:

    const routes = [{ path: '/home', redirect: '/' }]
    const routes = [{ path: '/home', redirect: { name: 'homepage' } }]
    const routes = [{// /search/screens -> /search?q=screenspath: '/search/:searchText',redirect: to => {// 方法接收目标路由作为参数// return 重定向的字符串路径/路径对象return { path: '/search', query: { q: to.params.searchText } }},},{path: '/search',// ...},
    ]
    

    注意

    • 导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上。在上面的例子中,在 /home 路由中添加 beforeEnter 守卫不会有任何效果。

    • 在写 redirect 的时候,可以省略 component 配置,因为它从来没有被直接访问过,所以没有组件要渲染。

      唯一的例外是嵌套路由:如果一个路由记录有 childrenredirect 属性,它也应该有 component 属性。

  • 相对重定向:重定向到相对位置

    const routes = [{// 将总是把/users/123/posts重定向到/users/123/profile。path: '/users/:id/posts',redirect: to => {// 该函数接收目标路由作为参数return to.path.replace(/posts$/, 'profile')},},
    ]
    

别名

  • / 别名为 /home,意味着当用户访问 /home 时,URL 仍然是 /home,但会被匹配为用户正在访问 /

    重定向是指当用户访问 /home 时,URL 会被 / 替换,然后匹配成 /

    const routes = [{ path: '/', component: Homepage, alias: '/home' }]
    
  • 通过别名,可以自由地将 UI 结构映射到一个任意的 URL,而不受配置的嵌套结构的限制。

    使别名以 / 开头,以使嵌套路径中的路径成为绝对路径。

    甚至可以将两者结合起来,用一个数组提供多个别名:

    const routes = [{path: '/users',component: UsersLayout,children: [// 为这3个URL(/users、/users/list、/people)呈现 UserList{ path: '', component: UserList, alias: ['/people', 'list'] },],},
    ]
    
  • 如果路由有参数,需确保在任何绝对别名中包含它们:

    const routes = [{path: '/users/:id',component: UsersByIdLayout,children: [// 为这3个URL(/users/24、/users/24/profile、/24)呈现 UserDetails{ path: 'profile', component: UserDetails, alias: ['/:id', ''] },],},
    ]
    

history 配置:指定历史模式

  • createWebHashHistory():Hash 模式(默认模式)

    • 内部传递的实际 URL 之前会加一个井号(#)(如 http://example.com/#/home
    • 无需服务器配置(所有URL,包括是不存在的,都不会被发送到服务器),适合纯前端单页应用(SPA)
    • 不过,它在 SEO 中确实有不好的影响。如果担心这个问题,可以使用 HTML5 模式。
    import { createRouter, createWebHashHistory } from 'vue-router'
    const router = createRouter({history: createWebHashHistory(),routes: [...],
    })
    
  • createWebHistory():history 模式 / HTML5 模式

    • url 更简洁(如 http://example.com/home),无 #
    • 需要服务器支持(避免 404 错误,需配置回退到 index.html
    • 适合需要 seo 或对 url 美观有要求的项目:
  • createMemoryHistory():Memory 模式

    • Memory 模式不会假定自己处于浏览器环境,因此不会与 URL 交互也不会自动触发初始导航

    • 需要在调用 app.use(router) 之后手动 push 到初始导航

    • 虽然不推荐,但仍可以在浏览器应用程序中使用此模式

      注意:它不会有历史记录,这意味着无法后退或前进

    • 非常适合 Node 环境和 SSR


路由元信息(meta)

路由配置中可以添加元信息(meta),例如权限控制、页面标题等。

  • 路由配置:

    const routes = [{ path: '/dashboard', name: 'Dashboard', component: Dashboard, meta: { requiresAuth: true, title: '控制面板' }}
    ];
    
  • 获取元信息:

    <script setup>
    import { useRoute } from 'vue-router';
    const route = useRoute();
    console.log(route.meta.title); // "控制面板"
    </script>
    
  • 全局导航守卫中使用:

    router.beforeEach((to, from) => {if (to.meta.requiresAuth && !isAuthenticated()) {return { name: 'Login' };}
    });
    

拓展

状态管理(Pinia / Vuex)

Pinia / Vuex 介绍

对于复杂或跨页面的数据传递,推荐使用状态管理库(Pinia/Vuex)。

  • Vuex:Vuex 是 Vue.js 官方的状态管理库。采用了 Flux 的思想,提供了一个集中式存储,允许组件以不同的方式共享状态。

    核心概念:

    • State: 应用的状态存储。
    • Getters: 类似于计算属性,用于计算基于状态的派生状态。
    • Mutations: 处理状态的唯一方式,直接修改状态。
    • Actions: 进行异步操作,并提交 Mutations。
  • Pinia:Pinia 是一个新兴的状态管理库,也是 Vue.js 的官方推荐替代方案。

    它为 Vue 3 提供了一种更简单、更具灵活性的状态管理方式

    与 Vuex 相比,Pinia 在设计上更现代化,支持 Composition API,使得开发者在使用时更加方便。

    核心概念:

    • Store: 状态存储的基本单位,通过建立一个或多个 Store 来管理状态。
    • State: 用于保存应用的响应式状态。
    • Getters: 计算属性的延伸,基于状态计算派生值。
    • Actions: 包含了执行异步操作的行为和直接修改状态的方法。

Vuex vs Pinia

  • API 和易用性
    • Vuex:采用认证的 Flux 风格,有一定的学习曲线,需要掌握多个概念(状态、getter、mutation、action)。对于小型应用来说,可能会显得过于复杂。
    • Pinia:设计更为简单,结合了 Composition API,让开发者能够更直观地管理状态。尤其是 Vue 3 的 Setup 语法糖,使用更加直观。
  • 响应式
    • Vuex:响应式总是要依赖于 Vue 的响应式系统,并且有多种约定(例如 Mutation),使用中需要更小心。
    • Pinia:完全基于 Vue 3 的响应式系统,状态变化后组件自动更新,无需额外的处理。
  • DevTools 支持
    • Vuex:在 Vue DevTools 中支持非常好,可以很方便地进行状态的查看和时间旅行调试。
    • Pinia:同样也支持 Vue DevTools,且整体使用体验更友好。
  • 社区支持和生态
    • Vuex:由于是官方库,资料和插件相对丰富,很多现有的项目都是基于 Vuex 的。
    • Pinia:作为新兴库,其社区支持还在不断扩大,函数式编程风格吸引了一部分开发者,但整体生态仍需时间发展。

总结

Vuex 和 Pinia 各有优缺点,选择哪个库取决于你的项目需求和个人偏好。如果你正在开发一个较大型的应用,且已有 Vuex 的使用经验,那么继续使用 Vuex 可能是一个不错的选择。而如果你想要尝试一种更简单、现代化的方式,那么 Pinia 无疑是个值得尝试的选项。


Pinia 基本使用

  • 安装 Pinia

    npm install pinia pinia-plugin-persistedstate
    
    • pinia-plugin-persistedstate 为 pinia 的数据持久化插件
  • main.tsmain.js 中初始化

    import { createApp } from 'vue';  
    import { createPinia } from 'pinia';  
    import { createPersistedState } from 'pinia-plugin-persistedstate';
    const app = createApp(App);  
    // 将状态管理器 pinia装入app
    const pinia = createPinia();
    pinia.use(createPersistedState()); // 开启状态持久化
    app.use(pinia);
    app.mount('#app');  
    
  • 创建一个 Store

    // store.js
    import { defineStore } from 'pinia';export const useCounterStore = defineStore('counter', {state: () => ({count: 0,}),getters: {doubleCount(state) {return state.count * 2;},},actions: {increment() {this.count++;},async incrementAsync() {await new Promise((resolve) => setTimeout(resolve, 1000));this.count++;},},persist: {enabled: true, // 启用持久化storage: window.localStorage, // 存储到 localStorage(默认)/sessionStorage},
    });
    
  • 使用 Pinia

    <template><div><p>Count: {{ count }}</p><p>Double Count: {{ doubleCount }}</p><button @click="increment">Increment</button><button @click="incrementAsync">Increment Async</button></div>
    </template><script setup lang="ts">
    import {computed} from "vue";
    import {useUserStore} from '@/utils/store.js';const counterStore = useUserStore()
    const count = computed(() => counterStore.count)
    const doubleCount = computed(() => counterStore.doubleCount)
    const increment = () => {counterStore.increment()
    }
    const incrementAsync = async () => {await counterStore.incrementAsync()
    }
    </script>
    

Pinia 使用 Cookies 存储

虽然Cookies主要用于存储少量数据,并且有大小限制(通常为4KB),但在某些情况下,也可以用于简单的持久化。

使用 Cookies 进行持久化时,需要手动处理数据的读写:

export const useUserStore = defineStore('user', {state: () => ({name: null,age: null,}),actions: {setName(name) {this.name = name;document.cookie = `name=${name}; path=/; max-age=3600`;},getName() {const name = document.cookie.split('; ').find(row => row.startsWith('name='));if (name) {this.name = name.split('=')[1];}},},
});
http://www.dtcms.com/a/460955.html

相关文章:

  • 深入理解 Java中的 异常和泛型(指南十二)
  • 草莓植物(plant)【高精度-->array高级!!!】
  • 3D 图表、堆叠饼图为什么是灾难?
  • Nacos 全解析:从注册中心到配置管理的实战指南
  • 微信小程序开发从零基础到项目发布的全流程实战教程(四)
  • wordpress 全站静态二次开发小程序
  • linux命令--后端项目部署
  • 网页版云手机 梦幻西游手游
  • HTML5 与 HTTPS,页面能力、必要性、常见问题与实战排查
  • 网站检索功能怎么做建设宣传网站的必要性
  • 做网站维护需要懂什么网站建设洽谈问题
  • 17、Linux 文件压缩与解压
  • IDEA编译时报错OOM的解决方案
  • .NET驾驭Word之力:基于规则自动生成及排版Word文档
  • 本地web测试服务器快速域名映射工具
  • 自己搭建远程桌面服务器——私有化部署RustDesk
  • 机器人强化学习原理讲解二:关于机器人重置
  • 目标检测YOLO实战应用案例100讲-相机 ISP(三)
  • 网站无障碍建设标准we建站
  • Linux系统为普通用户设置sudo权限
  • 网络流量分析工具
  • 网站基站的建设网站建设学习哪家专业
  • 【渗透测试】ARP是什么?有什么作用?
  • JavaEE 初阶第二十八期:HTTP协议深度揭秘(二)
  • 【Linux命令从入门到精通系列指南】source 命令详解:在当前 Shell 中执行脚本的终极指南
  • 深入理解 OKHttp:设计模式、核心机制与架构优势
  • 电压互感器在电网中接线方式决定了一次消谐器如何安装
  • HAMi 2.7.0 发布:全面拓展异构芯片支持,优化GPU资源调度与智能管理
  • Linux中延迟相关函数的实现
  • 企业制作网站一般多少钱如何选择网站关键词