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

Vue 前端开发中的路由知识:从入门到精通

文章目录

    • 引言
    • 1. Vue Router 简介
      • 1.1 安装 Vue Router
      • 1.2 配置 Vue Router
      • 1.3 在 Vue 实例中使用 Vue Router
    • 2. 路由的基本用法
      • 2.1 路由映射
      • 2.2 路由视图
      • 2.3 路由链接
    • 3. 动态路由
      • 3.1 动态路径参数
      • 3.2 访问动态参数
      • 3.3 响应路由参数的变化
    • 4. 嵌套路由
      • 4.1 定义嵌套路由
      • 4.2 渲染嵌套路由
    • 5. 路由守卫
      • 5.1 全局守卫
      • 5.2 路由独享守卫
      • 5.3 组件内守卫
    • 6. 路由懒加载
      • 6.1 使用动态导入实现懒加载
      • 6.2 使用 Webpack 的魔法注释
    • 7. 路由元信息
      • 7.1 定义路由元信息
      • 7.2 使用路由元信息
    • 8. 路由过渡效果
      • 8.1 使用 `<transition>` 组件
      • 8.2 自定义过渡效果
    • 9. 路由滚动行为
      • 9.1 定义路由滚动行为
      • 9.2 滚动到指定元素
    • 10. 路由模式
      • 10.1 Hash 模式
      • 10.2 History 模式
      • 10.3 服务器配置
    • 11. 路由错误处理
      • 11.1 捕获路由错误
      • 11.2 定义 404 路由
    • 12. 路由与状态管理
      • 12.1 在路由守卫中更新状态
      • 12.2 在组件中访问路由和状态
    • 13. 路由与权限控制
      • 13.1 权限验证
      • 13.2 动态路由
    • 14. 路由与 SEO
      • 14.1 服务器端渲染
      • 14.2 预渲染
    • 15. 路由与性能优化
      • 15.1 路由懒加载
      • 15.2 路由预取
      • 15.3 路由缓存
    • 16. 路由与国际化
      • 16.1 定义国际化路由
      • 16.2 动态切换语言
    • 17. 路由与动画
      • 17.1 使用 `<transition>` 组件
      • 17.2 自定义路由动画
    • 18. 路由与测试
      • 18.1 单元测试
      • 18.2 端到端测试
    • 19. 路由与调试
      • 19.1 使用 Vue Devtools
      • 19.2 使用 `router.beforeEach` 调试
    • 20. 路由与插件
      • 20.1 使用 `VueRouter.prototype`
      • 20.2 使用插件
    • 21. 路由与 TypeScript
      • 21.1 定义路由类型
      • 21.2 使用路由类型
    • 22. 路由与性能监控
      • 22.1 使用 `router.onReady`
      • 22.2 使用 `router.afterEach`
    • 23. 路由与错误监控
      • 23.1 使用 `router.onError`
      • 23.2 使用 `router.beforeEach`
    • 24. 路由与日志
      • 24.1 使用 `router.beforeEach`
      • 24.2 使用 `router.afterEach`
    • 25. 路由与安全
      • 25.1 使用路由守卫
      • 25.2 使用 HTTPS
    • 26. 路由与缓存
      • 26.1 使用 `<keep-alive>`
      • 26.2 动态缓存
    • 27. 路由与懒加载
      • 27.1 使用动态导入
      • 27.2 使用 Webpack 的魔法注释
    • 28. 路由与预加载
      • 28.1 使用 `router.beforeEach`
      • 28.2 使用 `router.onReady`

引言

在现代前端开发中,单页面应用(SPA)已经成为主流。SPA 通过动态地重写当前页面来与用户交互,而不是从服务器加载整个新页面。这种方式不仅提高了用户体验,还减少了服务器的负担。Vue.js 作为一个流行的前端框架,提供了强大的路由功能,使得开发者能够轻松地构建复杂的单页面应用。

本文将深入探讨 Vue 前端开发中的路由知识,涵盖从基础概念到高级用法的各个方面。我们将从 Vue Router 的安装和配置开始,逐步介绍路由的基本用法、动态路由、嵌套路由、路由守卫、懒加载等高级特性,并通过丰富的代码示例和实际案例帮助读者更好地理解和掌握这些知识。

1. Vue Router 简介

Vue Router 是 Vue.js 官方的路由管理器,它与 Vue.js 核心深度集成,使得构建单页面应用变得轻而易举。Vue Router 允许我们定义路由映射关系,并在用户访问不同 URL 时渲染不同的组件。

1.1 安装 Vue Router

在使用 Vue Router 之前,我们需要先安装它。可以通过 npm 或 yarn 来安装 Vue Router:

npm install vue-router

或者:

yarn add vue-router

1.2 配置 Vue Router

安装完成后,我们需要在 Vue 项目中配置 Vue Router。通常,我们会创建一个 router 目录,并在其中创建一个 index.js 文件来配置路由。

// src/router/index.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';Vue.use(VueRouter);const routes = [{path: '/',name: 'Home',component: Home},{path: '/about',name: 'About',component: About}
];const router = new VueRouter({mode: 'history',routes
});export default router;

在上面的代码中,我们首先引入了 Vue 和 VueRouter,然后通过 Vue.use(VueRouter) 来安装 Vue Router。接着,我们定义了一个路由数组 routes,其中每个路由对象都包含 pathnamecomponent 属性。最后,我们创建了一个 VueRouter 实例,并将其导出。

1.3 在 Vue 实例中使用 Vue Router

配置好路由后,我们需要在 Vue 实例中使用它。通常,我们会在 main.js 文件中引入并使用路由。

// src/main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router';Vue.config.productionTip = false;new Vue({router,render: h => h(App)
}).$mount('#app');

在上面的代码中,我们将 router 实例注入到 Vue 实例中,这样整个应用就可以使用 Vue Router 了。

2. 路由的基本用法

2.1 路由映射

在 Vue Router 中,路由映射是通过 routes 数组来定义的。每个路由对象都包含 pathnamecomponent 属性。

  • path:表示路由的路径,可以是静态路径或动态路径。
  • name:表示路由的名称,可以通过名称来引用路由。
  • component:表示路由对应的组件。
const routes = [{path: '/',name: 'Home',component: Home},{path: '/about',name: 'About',component: About}
];

2.2 路由视图

在 Vue Router 中,路由视图是通过 <router-view> 组件来渲染的。<router-view> 是一个占位符,用于显示与当前路由匹配的组件。

<!-- src/App.vue -->
<template><div id="app"><router-view></router-view></div>
</template>

在上面的代码中,<router-view> 会根据当前路由动态渲染对应的组件。

2.3 路由链接

在 Vue Router 中,路由链接是通过 <router-link> 组件来创建的。<router-link> 是一个导航链接,用于在不同的路由之间切换。

<!-- src/App.vue -->
<template><div id="app"><nav><router-link to="/">Home</router-link><router-link to="/about">About</router-link></nav><router-view></router-view></div>
</template>

在上面的代码中,<router-link> 会根据 to 属性生成相应的链接,并在用户点击时导航到对应的路由。

3. 动态路由

在实际开发中,我们经常需要根据不同的参数来动态渲染组件。Vue Router 提供了动态路由的功能,允许我们在路由路径中使用动态参数。

3.1 动态路径参数

在路由路径中,我们可以使用 : 来定义动态参数。例如,我们可以定义一个包含用户 ID 的动态路由:

const routes = [{path: '/user/:id',name: 'User',component: User}
];

在上面的代码中,:id 是一个动态参数,它可以匹配任何值。例如,/user/1/user/2 都会匹配到这个路由。

3.2 访问动态参数

在组件中,我们可以通过 this.$route.params 来访问动态参数。例如,在 User 组件中,我们可以通过 this.$route.params.id 来获取用户 ID。

// src/views/User.vue
<template><div><h1>User ID: {{ userId }}</h1></div>
</template><script>
export default {computed: {userId() {return this.$route.params.id;}}
};
</script>

在上面的代码中,我们通过 this.$route.params.id 获取了用户 ID,并在模板中显示出来。

3.3 响应路由参数的变化

当路由参数发生变化时,Vue Router 会复用同一个组件实例,而不是销毁并重新创建。这意味着,组件的生命周期钩子(如 mounted)不会再次触发。为了响应路由参数的变化,我们可以使用 watch 来监听 $route 对象的变化。

// src/views/User.vue
<template><div><h1>User ID: {{ userId }}</h1></div>
</template><script>
export default {computed: {userId() {return this.$route.params.id;}},watch: {'$route.params.id'(newId, oldId) {console.log('User ID changed from', oldId, 'to', newId);}}
};
</script>

在上面的代码中,我们通过 watch 监听 $route.params.id 的变化,并在控制台中输出变化信息。

4. 嵌套路由

在实际开发中,我们经常需要在一个组件中嵌套其他组件。Vue Router 提供了嵌套路由的功能,允许我们在一个路由中定义子路由。

4.1 定义嵌套路由

在路由配置中,我们可以通过 children 属性来定义嵌套路由。例如,我们可以在 User 组件中定义两个子路由:ProfilePosts

const routes = [{path: '/user/:id',component: User,children: [{path: 'profile',component: Profile},{path: 'posts',component: Posts}]}
];

在上面的代码中,User 组件是父路由,ProfilePosts 是子路由。当用户访问 /user/1/profile 时,User 组件会渲染 Profile 组件;当用户访问 /user/1/posts 时,User 组件会渲染 Posts 组件。

4.2 渲染嵌套路由

在父组件中,我们可以通过 <router-view> 来渲染子路由。例如,在 User 组件中,我们可以使用 <router-view> 来渲染 ProfilePosts 组件。

<!-- src/views/User.vue -->
<template><div><h1>User ID: {{ userId }}</h1><router-view></router-view></div>
</template><script>
export default {computed: {userId() {return this.$route.params.id;}}
};
</script>

在上面的代码中,<router-view> 会根据当前子路由动态渲染 ProfilePosts 组件。

5. 路由守卫

路由守卫是 Vue Router 提供的一种机制,允许我们在路由导航过程中执行一些操作,例如权限验证、数据预取等。Vue Router 提供了三种路由守卫:全局守卫、路由独享守卫和组件内守卫。

5.1 全局守卫

全局守卫是在路由导航过程中全局生效的守卫。Vue Router 提供了三种全局守卫:beforeEachbeforeResolveafterEach

  • beforeEach:在路由导航之前执行,常用于权限验证。
  • beforeResolve:在路由导航确认之前执行,常用于数据预取。
  • afterEach:在路由导航完成之后执行,常用于日志记录。
// src/router/index.js
const router = new VueRouter({mode: 'history',routes
});router.beforeEach((to, from, next) => {console.log('Global beforeEach guard');next();
});router.beforeResolve((to, from, next) => {console.log('Global beforeResolve guard');next();
});router.afterEach((to, from) => {console.log('Global afterEach guard');
});export default router;

在上面的代码中,我们定义了三个全局守卫,并在控制台中输出相应的日志信息。

5.2 路由独享守卫

路由独享守卫是在某个特定路由上生效的守卫。我们可以在路由配置中通过 beforeEnter 属性来定义路由独享守卫。

const routes = [{path: '/user/:id',component: User,beforeEnter: (to, from, next) => {console.log('Route-specific beforeEnter guard');next();}}
];

在上面的代码中,我们为 /user/:id 路由定义了一个 beforeEnter 守卫,并在控制台中输出日志信息。

5.3 组件内守卫

组件内守卫是在组件内部定义的守卫。Vue Router 提供了三种组件内守卫:beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave

  • beforeRouteEnter:在路由进入组件之前执行,常用于权限验证。
  • beforeRouteUpdate:在路由更新时执行,常用于响应路由参数的变化。
  • beforeRouteLeave:在路由离开组件之前执行,常用于提示用户保存未保存的数据。
// src/views/User.vue
<template><div><h1>User ID: {{ userId }}</h1></div>
</template><script>
export default {computed: {userId() {return this.$route.params.id;}},beforeRouteEnter(to, from, next) {console.log('Component beforeRouteEnter guard');next();},beforeRouteUpdate(to, from, next) {console.log('Component beforeRouteUpdate guard');next();},beforeRouteLeave(to, from, next) {console.log('Component beforeRouteLeave guard');next();}
};
</script>

在上面的代码中,我们定义了三个组件内守卫,并在控制台中输出相应的日志信息。

6. 路由懒加载

随着应用的规模增大,打包后的 JavaScript 文件也会变得越来越大,这会导致应用的初始加载时间变长。为了优化应用的性能,Vue Router 提供了路由懒加载的功能,允许我们将路由对应的组件按需加载。

6.1 使用动态导入实现懒加载

在 Vue Router 中,我们可以使用动态导入(import())来实现路由懒加载。动态导入会返回一个 Promise,Vue Router 会在需要时加载对应的组件。

const routes = [{path: '/',name: 'Home',component: () => import('../views/Home.vue')},{path: '/about',name: 'About',component: () => import('../views/About.vue')}
];

在上面的代码中,我们使用动态导入来懒加载 HomeAbout 组件。这样,只有在用户访问 //about 时,才会加载对应的组件。

6.2 使用 Webpack 的魔法注释

在使用动态导入时,我们可以使用 Webpack 的魔法注释来为生成的 chunk 命名。这样,我们可以更好地管理和调试生成的代码。

const routes = [{path: '/',name: 'Home',component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue')},{path: '/about',name: 'About',component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')}
];

在上面的代码中,我们使用 webpackChunkName 魔法注释为 HomeAbout 组件生成的 chunk 命名。这样,生成的 chunk 文件会被命名为 home.jsabout.js

7. 路由元信息

在实际开发中,我们经常需要为路由添加一些额外的信息,例如权限、标题等。Vue Router 提供了路由元信息的功能,允许我们在路由配置中添加自定义的元信息。

7.1 定义路由元信息

在路由配置中,我们可以通过 meta 属性来定义路由元信息。例如,我们可以为每个路由添加一个 requiresAuth 元信息,表示该路由是否需要登录才能访问。

const routes = [{path: '/',name: 'Home',component: Home,meta: {requiresAuth: false}},{path: '/dashboard',name: 'Dashboard',component: Dashboard,meta: {requiresAuth: true}}
];

在上面的代码中,我们为 //dashboard 路由分别定义了 requiresAuth 元信息。

7.2 使用路由元信息

在路由守卫中,我们可以通过 to.meta 来访问路由元信息。例如,我们可以在全局守卫中检查路由是否需要登录。

router.beforeEach((to, from, next) => {if (to.meta.requiresAuth && !isAuthenticated()) {next('/login');} else {next();}
});

在上面的代码中,我们检查 to.meta.requiresAuth 是否为 true,并且用户是否已经登录。如果路由需要登录但用户未登录,则重定向到 /login 路由。

8. 路由过渡效果

在 Vue Router 中,我们可以通过 <transition> 组件为路由切换添加过渡效果。Vue 提供了多种过渡效果,例如淡入淡出、滑动等。

8.1 使用 <transition> 组件

App.vue 中,我们可以使用 <transition> 组件包裹 <router-view>,并为路由切换添加过渡效果。

<!-- src/App.vue -->
<template><div id="app"><transition name="fade" mode="out-in"><router-view></router-view></transition></div>
</template><style>
.fade-enter-active, .fade-leave-active {transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {opacity: 0;
}
</style>

在上面的代码中,我们使用 <transition> 组件为 <router-view> 添加了淡入淡出的过渡效果。name="fade" 表示使用 fade 过渡效果,mode="out-in" 表示在切换路由时,先离开当前路由,再进入新路由。

8.2 自定义过渡效果

除了使用 Vue 提供的过渡效果外,我们还可以自定义过渡效果。例如,我们可以为不同的路由定义不同的过渡效果。

<!-- src/App.vue -->
<template><div id="app"><transition :name="transitionName" mode="out-in"><router-view></router-view></transition></div>
</template><script>
export default {data() {return {transitionName: 'fade'};},watch: {'$route'(to, from) {if (to.meta.transitionName) {this.transitionName = to.meta.transitionName;} else {this.transitionName = 'fade';}}}
};
</script><style>
.fade-enter-active, .fade-leave-active {transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {opacity: 0;
}.slide-enter-active, .slide-leave-active {transition: transform 0.5s;
}
.slide-enter, .slide-leave-to {transform: translateX(100%);
}
</style>

在上面的代码中,我们通过 watch 监听 $route 的变化,并根据路由的 meta.transitionName 属性动态设置过渡效果。例如,如果路由的 meta.transitionNameslide,则使用滑动过渡效果。

9. 路由滚动行为

在单页面应用中,当用户切换路由时,页面的滚动位置通常会保持不变。为了提升用户体验,Vue Router 提供了路由滚动行为的功能,允许我们在路由切换时控制页面的滚动位置。

9.1 定义路由滚动行为

在 Vue Router 配置中,我们可以通过 scrollBehavior 函数来定义路由滚动行为。scrollBehavior 函数接收 tofromsavedPosition 三个参数,并返回一个滚动位置对象。

const router = new VueRouter({mode: 'history',routes,scrollBehavior(to, from, savedPosition) {if (savedPosition) {return savedPosition;} else {return { x: 0, y: 0 };}}
});

在上面的代码中,我们定义了一个 scrollBehavior 函数。如果 savedPosition 存在(即用户通过浏览器的前进/后退按钮导航),则返回 savedPosition;否则,返回 { x: 0, y: 0 },即滚动到页面顶部。

9.2 滚动到指定元素

除了滚动到页面顶部外,我们还可以滚动到页面中的指定元素。例如,我们可以滚动到某个锚点。

const router = new VueRouter({mode: 'history',routes,scrollBehavior(to, from, savedPosition) {if (to.hash) {return { selector: to.hash };} else if (savedPosition) {return savedPosition;} else {return { x: 0, y: 0 };}}
});

在上面的代码中,如果 to.hash 存在(即 URL 中包含锚点),则滚动到对应的元素;否则,按照默认行为滚动。

10. 路由模式

Vue Router 支持两种路由模式:hash 模式和 history 模式。

10.1 Hash 模式

Hash 模式是 Vue Router 的默认模式。在 Hash 模式下,URL 中的路径会以 # 开头。例如,http://example.com/#/user/1

Hash 模式的优点是兼容性好,可以在不支持 HTML5 History API 的浏览器中使用。缺点是 URL 不够美观,且 # 后面的部分不会被发送到服务器。

const router = new VueRouter({mode: 'hash',routes
});

10.2 History 模式

History 模式使用 HTML5 History API 来实现路由。在 History 模式下,URL 中的路径是正常的路径,例如 http://example.com/user/1

History 模式的优点是 URL 美观,且路径会被发送到服务器。缺点是需要服务器配置支持,否则在刷新页面时会出现 404 错误。

const router = new VueRouter({mode: 'history',routes
});

10.3 服务器配置

在使用 History 模式时,我们需要确保服务器能够正确处理所有的路由请求。通常,我们需要在服务器配置中添加一个回退路由,将所有未匹配的请求重定向到 index.html

例如,在 Nginx 中,我们可以添加以下配置:

location / {try_files $uri $uri/ /index.html;
}

在 Apache 中,我们可以添加以下配置:

<IfModule mod_rewrite.c>RewriteEngine OnRewriteBase /RewriteRule ^index\.html$ - [L]RewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-dRewriteRule . /index.html [L]
</IfModule>

11. 路由错误处理

在实际开发中,我们可能会遇到一些路由错误,例如用户访问了不存在的路由。为了提升用户体验,Vue Router 提供了路由错误处理的功能。

11.1 捕获路由错误

在 Vue Router 中,我们可以通过 router.onError 方法来捕获路由错误。例如,我们可以捕获路由加载失败的错误。

router.onError((error) => {console.error('Route error:', error);
});

在上面的代码中,我们通过 router.onError 方法捕获路由错误,并在控制台中输出错误信息。

11.2 定义 404 路由

为了处理用户访问不存在的路由的情况,我们可以定义一个 404 路由。通常,我们会将 404 路由放在路由配置的最后。

const routes = [{path: '/',name: 'Home',component: Home},{path: '/about',name: 'About',component: About},{path: '*',component: NotFound}
];

在上面的代码中,我们定义了一个 * 路由,用于匹配所有未定义的路由。当用户访问不存在的路由时,会渲染 NotFound 组件。

12. 路由与状态管理

在实际开发中,我们经常需要将路由与状态管理结合起来使用。例如,我们可能需要在路由切换时更新 Vuex 中的状态。

12.1 在路由守卫中更新状态

在路由守卫中,我们可以通过 store.commitstore.dispatch 来更新 Vuex 中的状态。例如,我们可以在全局守卫中更新用户的登录状态。

router.beforeEach((to, from, next) => {if (to.meta.requiresAuth && !store.state.isAuthenticated) {next('/login');} else {next();}
});

在上面的代码中,我们检查 to.meta.requiresAuth 是否为 true,并且用户是否已经登录。如果路由需要登录但用户未登录,则重定向到 /login 路由。

12.2 在组件中访问路由和状态

在组件中,我们可以通过 this.$routethis.$store 来访问路由和状态。例如,我们可以在组件中根据当前路由和状态来渲染不同的内容。

<template><div><h1>{{ pageTitle }}</h1></div>
</template><script>
export default {computed: {pageTitle() {return this.$route.meta.title || 'Default Title';},isAuthenticated() {return this.$store.state.isAuthenticated;}}
};
</script>

在上面的代码中,我们通过 this.$route.meta.title 获取当前路由的标题,并通过 this.$store.state.isAuthenticated 获取用户的登录状态。

13. 路由与权限控制

在实际开发中,我们经常需要根据用户的权限来控制路由的访问。Vue Router 提供了路由守卫的功能,允许我们在路由导航过程中进行权限验证。

13.1 权限验证

在路由守卫中,我们可以根据用户的权限来决定是否允许访问某个路由。例如,我们可以在全局守卫中检查用户是否具有访问某个路由的权限。

router.beforeEach((to, from, next) => {if (to.meta.requiresAdmin && !store.state.isAdmin) {next('/forbidden');} else {next();}
});

在上面的代码中,我们检查 to.meta.requiresAdmin 是否为 true,并且用户是否具有管理员权限。如果路由需要管理员权限但用户没有权限,则重定向到 /forbidden 路由。

13.2 动态路由

在某些情况下,我们可能需要根据用户的权限动态生成路由。例如,我们可以在用户登录后根据用户的权限动态添加路由。

const adminRoutes = [{path: '/admin',component: Admin,meta: {requiresAdmin: true}}
];router.addRoutes(adminRoutes);

在上面的代码中,我们定义了一个 adminRoutes 数组,并在用户登录后通过 router.addRoutes 方法动态添加这些路由。

14. 路由与 SEO

在单页面应用中,由于页面的内容是通过 JavaScript 动态生成的,搜索引擎可能无法正确抓取页面的内容。为了提升 SEO(搜索引擎优化),我们可以使用服务器端渲染(SSR)或预渲染(Prerendering)技术。

14.1 服务器端渲染

服务器端渲染(SSR)是指在服务器端生成 HTML 内容,并将其发送到客户端。Vue 提供了官方的 SSR 解决方案,即 Vue Server Renderer。

使用 SSR 可以确保搜索引擎能够正确抓取页面的内容,从而提升 SEO。然而,SSR 的实现比较复杂,需要对服务器和客户端代码进行特殊处理。

14.2 预渲染

预渲染(Prerendering)是指在构建时生成静态 HTML 文件,并将其作为静态资源提供给客户端。预渲染可以提升 SEO,并且实现相对简单。

在 Vue 项目中,我们可以使用 prerender-spa-plugin 插件来实现预渲染。

// vue.config.js
const PrerenderSPAPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
const path = require('path');module.exports = {configureWebpack: {plugins: [new PrerenderSPAPlugin({staticDir: path.join(__dirname, 'dist'),routes: ['/', '/about', '/user/1'],renderer: new Renderer({renderAfterDocumentEvent: 'render-event'})})]}
};

在上面的代码中,我们使用 prerender-spa-plugin 插件为 //about/user/1 路由生成静态 HTML 文件。

15. 路由与性能优化

在实际开发中,我们可能需要对路由进行性能优化,以提升应用的加载速度和运行效率。

15.1 路由懒加载

如前所述,路由懒加载可以有效地减少初始加载时间。我们可以将路由对应的组件按需加载,从而减少初始加载的 JavaScript 文件大小。

const routes = [{path: '/',name: 'Home',component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue')},{path: '/about',name: 'About',component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')}
];

15.2 路由预取

在某些情况下,我们可能希望在用户访问某个路由之前预取该路由对应的组件。Vue Router 提供了路由预取的功能,允许我们在用户导航到某个路由之前预取该路由的组件。

router.beforeEach((to, from, next) => {if (to.meta.prefetch) {to.matched[0].components.default().then(() => {next();});} else {next();}
});

在上面的代码中,我们检查 to.meta.prefetch 是否为 true,并在导航之前预取该路由的组件。

15.3 路由缓存

在某些情况下,我们可能希望缓存某些路由的组件,以避免重复渲染。Vue 提供了 <keep-alive> 组件,允许我们缓存路由组件。

<template><div id="app"><keep-alive><router-view></router-view></keep-alive></div>
</template>

在上面的代码中,我们使用 <keep-alive> 组件缓存 <router-view> 中的组件。这样,当用户再次访问该路由时,组件不会被重新渲染。

16. 路由与国际化

在实际开发中,我们可能需要为应用添加国际化支持。Vue Router 可以与 Vue I18n 结合使用,以实现路由的国际化。

16.1 定义国际化路由

在路由配置中,我们可以为每个路由定义多个语言版本。例如,我们可以为 /about 路由定义英文和中文版本。

const routes = [{path: '/about',component: About,meta: {title: {en: 'About',zh: '关于'}}}
];

在上面的代码中,我们为 /about 路由定义了英文和中文的标题。

16.2 动态切换语言

在应用中,我们可以通过 vue-i18n 插件动态切换语言。例如,我们可以在用户切换语言时更新路由的标题。

<template><div><h1>{{ $t($route.meta.title) }}</h1></div>
</template><script>
export default {watch: {'$i18n.locale'(newLocale) {document.title = this.$t(this.$route.meta.title);}}
};
</script>

在上面的代码中,我们通过 watch 监听 $i18n.locale 的变化,并在语言切换时更新页面的标题。

17. 路由与动画

在实际开发中,我们可能希望为路由切换添加动画效果。Vue Router 可以与 Vue 的过渡系统结合使用,以实现路由切换的动画效果。

17.1 使用 <transition> 组件

如前所述,我们可以使用 <transition> 组件为路由切换添加过渡效果。例如,我们可以为路由切换添加淡入淡出的效果。

<template><div id="app"><transition name="fade" mode="out-in"><router-view></router-view></transition></div>
</template><style>
.fade-enter-active, .fade-leave-active {transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {opacity: 0;
}
</style>

在上面的代码中,我们使用 <transition> 组件为 <router-view> 添加了淡入淡出的过渡效果。

17.2 自定义路由动画

除了使用 Vue 提供的过渡效果外,我们还可以自定义路由动画。例如,我们可以为不同的路由定义不同的动画效果。

<template><div id="app"><transition :name="transitionName" mode="out-in"><router-view></router-view></transition></div>
</template><script>
export default {data() {return {transitionName: 'fade'};},watch: {'$route'(to, from) {if (to.meta.transitionName) {this.transitionName = to.meta.transitionName;} else {this.transitionName = 'fade';}}}
};
</script><style>
.fade-enter-active, .fade-leave-active {transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {opacity: 0;
}.slide-enter-active, .slide-leave-active {transition: transform 0.5s;
}
.slide-enter, .slide-leave-to {transform: translateX(100%);
}
</style>

在上面的代码中,我们通过 watch 监听 $route 的变化,并根据路由的 meta.transitionName 属性动态设置过渡效果。例如,如果路由的 meta.transitionNameslide,则使用滑动过渡效果。

18. 路由与测试

在实际开发中,我们可能需要对路由进行单元测试和端到端测试。Vue Router 提供了测试工具,允许我们轻松地测试路由。

18.1 单元测试

在单元测试中,我们可以使用 vue-test-utils 来测试路由。例如,我们可以测试某个路由是否正确地渲染了对应的组件。

import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueRouter from 'vue-router';
import Home from '@/views/Home.vue';const localVue = createLocalVue();
localVue.use(VueRouter);const router = new VueRouter({routes: [{path: '/',component: Home}]
});describe('Home.vue', () => {it('renders the home component', () => {const wrapper = shallowMount(Home, {localVue,router});expect(wrapper.text()).toMatch('Home');});
});

在上面的代码中,我们使用 vue-test-utils 测试 Home 组件是否正确地渲染了 Home 文本。

18.2 端到端测试

在端到端测试中,我们可以使用 CypressNightwatch 来测试路由。例如,我们可以测试用户导航到某个路由时是否正确地渲染了对应的组件。

// Cypress test
describe('Navigation', () => {it('navigates to the about page', () => {cy.visit('/');cy.get('a[href="/about"]').click();cy.url().should('include', '/about');cy.contains('h1', 'About');});
});

在上面的代码中,我们使用 Cypress 测试用户导航到 /about 路由时是否正确地渲染了 About 组件。

19. 路由与调试

在实际开发中,我们可能需要对路由进行调试。Vue Router 提供了调试工具,允许我们轻松地调试路由。

19.1 使用 Vue Devtools

Vue Devtools 是一个浏览器扩展,允许我们调试 Vue 应用。我们可以使用 Vue Devtools 来查看当前的路由状态、路由历史等信息。

19.2 使用 router.beforeEach 调试

在路由守卫中,我们可以通过 console.log 来输出调试信息。例如,我们可以在全局守卫中输出当前的路由信息。

router.beforeEach((to, from, next) => {console.log('Navigating from', from.path, 'to', to.path);next();
});

在上面的代码中,我们在全局守卫中输出当前的路由信息,以便调试路由导航过程。

20. 路由与插件

在实际开发中,我们可能需要为 Vue Router 添加一些插件,以扩展其功能。Vue Router 提供了插件系统,允许我们轻松地添加插件。

20.1 使用 VueRouter.prototype

我们可以通过 VueRouter.prototype 来扩展 Vue Router 的功能。例如,我们可以为 Vue Router 添加一个 back 方法,用于返回上一个路由。

VueRouter.prototype.back = function() {this.go(-1);
};const router = new VueRouter({mode: 'history',routes
});export default router;

在上面的代码中,我们为 Vue Router 添加了一个 back 方法,用于返回上一个路由。

20.2 使用插件

我们可以将扩展功能封装成插件,并在 Vue Router 中使用。例如,我们可以创建一个 router-plugin.js 文件,并在其中定义插件。

// src/plugins/router-plugin.js
export default {install(Vue, router) {router.back = function() {this.go(-1);};}
};// src/main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import routerPlugin from './plugins/router-plugin';Vue.config.productionTip = false;Vue.use(routerPlugin, router);new Vue({router,render: h => h(App)
}).$mount('#app');

在上面的代码中,我们创建了一个 router-plugin.js 文件,并在其中定义了一个插件。然后,我们在 main.js 中使用该插件。

21. 路由与 TypeScript

在实际开发中,我们可能需要在 TypeScript 项目中使用 Vue Router。Vue Router 提供了 TypeScript 支持,允许我们轻松地在 TypeScript 项目中使用路由。

21.1 定义路由类型

在 TypeScript 项目中,我们可以为路由定义类型。例如,我们可以为路由配置定义类型。

import Vue from 'vue';
import VueRouter, { RouteConfig } from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';Vue.use(VueRouter);const routes: RouteConfig[] = [{path: '/',name: 'Home',component: Home},{path: '/about',name: 'About',component: About}
];const router = new VueRouter({mode: 'history',routes
});export default router;

在上面的代码中,我们为 routes 数组定义了 RouteConfig[] 类型。

21.2 使用路由类型

在组件中,我们可以使用 RouteRouteConfig 类型来定义路由相关的属性和方法。例如,我们可以在组件中定义 $route$router 的类型。

import { Component, Vue } from 'vue-property-decorator';
import { Route } from 'vue-router';@Component
export default class Home extends Vue {get route(): Route {return this.$route;}navigateToAbout() {this.$router.push('/about');}
}

在上面的代码中,我们使用 Route 类型定义了 route 属性,并在 navigateToAbout 方法中使用 $router 导航到 /about 路由。

22. 路由与性能监控

在实际开发中,我们可能需要对路由的性能进行监控。Vue Router 提供了性能监控的功能,允许我们轻松地监控路由的性能。

22.1 使用 router.onReady

我们可以使用 router.onReady 方法来监控路由的加载性能。例如,我们可以在路由加载完成后输出加载时间。

router.onReady(() => {console.log('Router ready');
});

在上面的代码中,我们在路由加载完成后输出 Router ready

22.2 使用 router.afterEach

我们可以使用 router.afterEach 方法来监控路由导航的性能。例如,我们可以在路由导航完成后输出导航时间。

router.afterEach((to, from) => {console.log('Navigated from', from.path, 'to', to.path);
});

在上面的代码中,我们在路由导航完成后输出导航信息。

23. 路由与错误监控

在实际开发中,我们可能需要对路由的错误进行监控。Vue Router 提供了错误监控的功能,允许我们轻松地监控路由的错误。

23.1 使用 router.onError

我们可以使用 router.onError 方法来监控路由的错误。例如,我们可以在路由加载失败时输出错误信息。

router.onError((error) => {console.error('Route error:', error);
});

在上面的代码中,我们在路由加载失败时输出错误信息。

23.2 使用 router.beforeEach

我们可以使用 router.beforeEach 方法来监控路由导航的错误。例如,我们可以在路由导航失败时输出错误信息。

router.beforeEach((to, from, next) => {try {next();} catch (error) {console.error('Navigation error:', error);next(false);}
});

在上面的代码中,我们在路由导航失败时输出错误信息,并阻止导航。

24. 路由与日志

在实际开发中,我们可能需要对路由的导航过程进行日志记录。Vue Router 提供了日志记录的功能,允许我们轻松地记录路由的导航过程。

24.1 使用 router.beforeEach

我们可以使用 router.beforeEach 方法来记录路由导航的日志。例如,我们可以在路由导航开始时输出日志信息。

router.beforeEach((to, from, next) => {console.log('Navigating from', from.path, 'to', to.path);next();
});

在上面的代码中,我们在路由导航开始时输出日志信息。

24.2 使用 router.afterEach

我们可以使用 router.afterEach 方法来记录路由导航的日志。例如,我们可以在路由导航完成后输出日志信息。

router.afterEach((to, from) => {console.log('Navigated from', from.path, 'to', to.path);
});

在上面的代码中,我们在路由导航完成后输出日志信息。

25. 路由与安全

在实际开发中,我们可能需要对路由的安全性进行考虑。Vue Router 提供了安全相关的功能,允许我们轻松地保护路由。

25.1 使用路由守卫

我们可以使用路由守卫来保护路由。例如,我们可以在全局守卫中检查用户是否具有访问某个路由的权限。

router.beforeEach((to, from, next) => {if (to.meta.requiresAuth && !store.state.isAuthenticated) {next('/login');} else {next();}
});

在上面的代码中,我们检查 to.meta.requiresAuth 是否为 true,并且用户是否已经登录。如果路由需要登录但用户未登录,则重定向到 /login 路由。

25.2 使用 HTTPS

我们可以使用 HTTPS 来保护路由的通信安全。例如,我们可以在服务器配置中启用 HTTPS。

server {listen 443 ssl;server_name example.com;ssl_certificate /path/to/certificate.crt;ssl_certificate_key /path/to/private.key;location / {proxy_pass http://localhost:8080;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}
}

在上面的代码中,我们在 Nginx 配置中启用了 HTTPS,并将请求代理到本地的 Vue 应用。

26. 路由与缓存

在实际开发中,我们可能需要对路由的组件进行缓存,以提升应用的性能。Vue 提供了 <keep-alive> 组件,允许我们缓存路由组件。

26.1 使用 <keep-alive>

我们可以使用 <keep-alive> 组件来缓存路由组件。例如,我们可以在 App.vue 中使用 <keep-alive> 组件缓存 <router-view> 中的组件。

<template><div id="app"><keep-alive><router-view></router-view></keep-alive></div>
</template>

在上面的代码中,我们使用 <keep-alive> 组件缓存 <router-view> 中的组件。这样,当用户再次访问该路由时,组件不会被重新渲染。

26.2 动态缓存

在某些情况下,我们可能希望动态地缓存某些路由的组件。例如,我们可以在路由配置中定义 meta.keepAlive 属性,并根据该属性动态缓存组件。

const routes = [{path: '/',name: 'Home',component: Home,meta: {keepAlive: true}},{path: '/about',name: 'About',component: About,meta: {keepAlive: false}}
];

在上面的代码中,我们为 / 路由定义了 meta.keepAlivetrue,表示该路由的组件需要缓存;为 /about 路由定义了 meta.keepAlivefalse,表示该路由的组件不需要缓存。

<template><div id="app"><keep-alive><router-view v-if="$route.meta.keepAlive"></router-view></keep-alive><router-view v-if="!$route.meta.keepAlive"></router-view></div>
</template>

在上面的代码中,我们根据 $route.meta.keepAlive 属性动态缓存组件。

27. 路由与懒加载

在实际开发中,我们可能需要对路由的组件进行懒加载,以提升应用的初始加载速度。Vue Router 提供了懒加载的功能,允许我们按需加载路由组件。

27.1 使用动态导入

我们可以使用动态导入(import())来实现路由组件的懒加载。例如,我们可以在路由配置中使用动态导入来懒加载组件。

const routes = [{path: '/',name: 'Home',component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue')},{path: '/about',name: 'About',component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')}
];

在上面的代码中,我们使用动态导入来懒加载 HomeAbout 组件。这样,只有在用户访问 //about 时,才会加载对应的组件。

27.2 使用 Webpack 的魔法注释

在使用动态导入时,我们可以使用 Webpack 的魔法注释来为生成的 chunk 命名。这样,我们可以更好地管理和调试生成的代码。

const routes = [{path: '/',name: 'Home',component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue')},{path: '/about',name: 'About',component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')}
];

在上面的代码中,我们使用 webpackChunkName 魔法注释为 HomeAbout 组件生成的 chunk 命名。这样,生成的 chunk 文件会被命名为 home.jsabout.js

28. 路由与预加载

在实际开发中,我们可能需要对路由的组件进行预加载,以提升应用的性能。Vue Router 提供了预加载的功能,允许我们在用户导航到某个路由之前预取该路由的组件。

28.1 使用 router.beforeEach

我们可以使用 router.beforeEach 方法来预取路由的组件。例如,我们可以在全局守卫中预取某个路由的组件。

router.beforeEach((to, from, next) => {if (to.meta.prefetch) {to.matched[0].components.default().then(() => {next();});} else {next();}
});

在上面的代码中,我们检查 to.meta.prefetch 是否为 true,并在导航之前预取该路由的组件。

28.2 使用 router.onReady

我们可以使用 router.onReady 方法来预取路由的组件。例如,我们可以在路由加载完成后预取某个路由的组件。

router.onReady(() => {router.getMatchedComponents().forEach(component => {if (component.preload) {component.preload();}});
});

在上面的代码中,我们在路由加载完成后预取所有匹配的组件。

相关文章:

Vue 前端开发中的路由知识:从入门到精通

文章目录 引言1. Vue Router 简介1.1 安装 Vue Router1.2 配置 Vue Router1.3 在 Vue 实例中使用 Vue Router 2. 路由的基本用法2.1 路由映射2.2 路由视图2.3 路由链接 3. 动态路由3.1 动态路径参数3.2 访问动态参数3.3 响应路由参数的变化 4. 嵌套路由4.1 定义嵌套路由4.2 渲染…...

前端VUE+后端uwsgi 环境搭建

1整体架构 请求流程the web clinet--the web server->the socket->uwsgi--django 第一级的nginx并不是必须的&#xff0c;uwsgi完全可以完成整个的和浏览器交互的流程&#xff1b;在nginx上加上安全性或其他的限制&#xff0c;可以达到保护程序的作用&#xff1b;uWSGI本…...

I2C实践开发 ---【STM32-I2C-HDC1080温湿度采集系统】

I2C实践开发 — STM32-I2C-HDC1080温湿度采集系统 目录 I2C实践开发 --- STM32-I2C-HDC1080温湿度采集系统1. 引言2. 系统架构2.1 硬件架构2.2 软件架构 3. 代码分析3.1 I2C驱动文件 (i2c.h 和 i2c.c)3.2 HDC1080传感器驱动文件 (hdc1080.h 和 hdc1080.c) 4. 功能总结【HDC1080…...

【个人开发】deepspeed+Llama-factory 本地数据多卡Lora微调【完整教程】

文章目录 1.背景2.微调方式2.1 关键环境版本信息2.2 步骤2.2.1 下载llama-factory2.2.2 准备数据集2.2.3 微调模式2.2.3.1 zero-1微调2.2.3.2 zero-2微调2.2.3.3 zero-3微调2.2.3.4 单卡Lora微调 2.2.4 实验2.2.4.1 实验1&#xff1a;多GPU微调-zero12.2.4.2 实验2&#xff1a;…...

浏览器报错:无法访问此网站 无法找到xxx.xxx.net的DNS地址。正在诊断该问题。尝试运行Windows网络诊断。DNS_PROBE_STARTED

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;希望我的文章能帮到您&#x1f7ea;如有兴趣可点关注了解更多内容 &#x1f4d8;博主信息 点击标题&#x1f446;有惊喜 &#x1f4c3;文章前言 &#x1f537;文章均为学习和工作中整理的笔记&#xff0c;分享记录…...

【设计模式】 代理模式(静态代理、动态代理{JDK动态代理、JDK动态代理与CGLIB动态代理的区别})

代理模式 代理模式是一种结构型设计模式&#xff0c;它提供了一种替代访问的方法&#xff0c;即通过代理对象来间接访问目标对象。代理模式可以在不改变原始类代码的情况下&#xff0c;增加额外的功能&#xff0c;如权限控制、日志记录等。 静态代理 静态代理是指创建的或特…...

网络安全-攻击流程-用户层

用户层攻击主要针对操作系统中的用户空间应用程序及用户权限&#xff0c;利用软件漏洞、配置错误或用户行为弱点进行攻击。以下是常见的用户层攻击类型及其流程&#xff0c;以及防御措施&#xff1a; 1. 缓冲区溢出攻击 攻击流程&#xff1a; 目标识别&#xff1a;确定存在漏…...

网络安全等级保护测评(等保测评):全面指南与准备要点

等保测评&#xff0c;全称为“网络安全等级保护测评”&#xff0c;是根据《网络安全法》及《网络安全等级保护条例》等法律法规&#xff0c;对信息系统进行安全等级划分&#xff0c;并依据不同等级的安全保护要求&#xff0c;采用科学方法和技术手段&#xff0c;全面评估信息系…...

具身导航赋能智能物流!OpenBench:智能物流最后一公里语义导航新基准

作者&#xff1a;Junhui Wang, Dongjie Huo, Zehui Xu, Yongliang Shi, Yimin Yan, Yuanxin Wang, Chao Gao, Yan Qiao, Guyue Zhou 单位&#xff1a;澳门科技大学系统工程与协作实验室、智能科学与系统联合实验室&#xff0c;清华大学人工智能产业研究院&#xff08;AIR&…...

详解 本机安装多个MySQL服务【为后续大数据量分库分表奠定基础,以mysql8.0为例,附有图文】

本机安装多个mysql 在电脑上新建mysql8文件夹&#xff0c;然后在mysql8文件下新建mysql3391文件夹。然后找到自己原本mysql的安装目录&#xff0c;我的是E:\software\mysql\one&#xff0c;如图所示&#xff1a; 将次目录下的所有文件全选复制粘贴在mysql3391文件夹下。 然后…...

2025年新趋势:如何利用AI技术优化你的在线帮助中心

在2025年的今天&#xff0c;人工智能&#xff08;AI&#xff09;技术正以惊人的速度改变着我们的世界。从自动驾驶汽车到智能家居&#xff0c;从医疗诊断到金融分析&#xff0c;AI的身影无处不在。而在客户服务领域&#xff0c;AI同样正在发挥着越来越重要的作用。特别是在线帮…...

同花顺Java开发面试题及参考答案 (上)

int 类型占用几个字节&#xff1f;float 类型的数字如何与 0 进行比较&#xff1f; 在 Java 中&#xff0c;int 类型是一种基本数据类型&#xff0c;它占用 4 个字节。一个字节有 8 位&#xff0c;所以 int 类型总共是 32 位。这 32 位可以用来表示不同的整数值&#xff0c;其取…...

CommonLang3-使用介绍

摘自&#xff1a;https://www.cnblogs.com/haicheng92/p/18721636 学习要带着目的&#xff0c;参照现实问题 本次目标&#xff1a; 了解 CommonsLang3 API 文档&#xff0c;找对路后以后开发直接查询 API 文档&#xff0c;摈弃盲目的百度掌握基础的字符串、日期、数值等工具…...

Java常用设计模式及其应用场景

1. 什么是设计模式&#xff1f; 设计模式是一个经过多次验证的、针对常见问题的可复用解决方案。设计模式并不是具体的代码实现&#xff0c;而是给出了如何解决问题的思路和结构。在实际开发过程中&#xff0c;设计模式有助于开发者快速找到合适的解决方案&#xff0c;从而减少…...

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_pnalloc函数

ngx_pnalloc 声明在 src\core\ngx_palloc.h void *ngx_pnalloc(ngx_pool_t *pool, size_t size); 定义在 src\core\ngx_palloc.c void * ngx_pnalloc(ngx_pool_t *pool, size_t size) { #if !(NGX_DEBUG_PALLOC)if (size < pool->max) {return ngx_palloc_small(pool, …...

【ISO 14229-1:2023 UDS诊断(会话控制0x10服务)测试用例CAPL代码全解析①】

ISO 14229-1:2023 UDS诊断【会话控制0x10服务】_TestCase01 作者&#xff1a;车端域控测试工程师 更新日期&#xff1a;2025年02月14日 关键词&#xff1a;UDS诊断、0x10服务、诊断会话控制、ECU测试、ISO 14229-1:2023 TC10-001测试用例 用例ID测试场景验证要点参考条款预期…...

A与B组件自动对齐与组装,无映射直接补偿。

网上针对组装的从视觉到控制动作,要不就是收费,要不就是简单介绍。这么详细的比较难找~ 手下留情,不喜勿喷! Show time~ 分步解决方案: 标定阶段(Calibration) 9点张氏标定(每个位置A1、A2、B1、B2): 使用机械手在相机视野内沿Z字形路径移动,覆盖9个点(XY方…...

QT 读写锁

一、概述 1、读写锁是一种线程同步机制&#xff0c;用于解决多线程环境下的读写竞争问题。 2、读写锁允许多个线程同时获取读锁&#xff08;共享访问&#xff09;&#xff0c;但只允许一个线程获取写锁&#xff08;独占访问&#xff09;。 3、这种机制可以提高并发性能&…...

C++ 的时间库之二:Ratio

从现在开始&#xff0c;我们开始介绍 C 风格的时间处理&#xff0c;在这之前&#xff0c;首先要介绍std::ratio。因为 C 的 chrono库中的时间段&#xff08;duration&#xff09;定义离不开std::ratio&#xff0c;不了解std::ratio&#xff0c;就很难理解duration的定义。 1 st…...

使用小雅xiaoya/Emby正确的观看电影电视剧的姿势

最近有很多小伙伴来咨询关于小雅Emby全家桶的使用问题&#xff0c;最常见的就是在Emby上搜索出来资源之后&#xff0c;点击播放会提示【播放错误】&#xff0c;当前没有兼容的流。 这可把很多小伙伴给急坏了……于是找到小白咨询。 嗯……怎么说呢&#xff1f;小白并不喜欢看电…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...