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();}});
});

在上面的代碼中,我們在路由加載完成后預取所有匹配的組件。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/895783.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/895783.shtml
英文地址,請注明出處:http://en.pswp.cn/news/895783.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于Springboot+微信小程序調用文心一言大模型實現AI聊天

一、文章前言 此文主要實現基于Springboot微信小程序調用文心一言大模型實現AI聊天對話功能&#xff0c;使用Java作為后端語言進行支持&#xff0c;界面友好&#xff0c;開發簡單。 二、開發流程及工具準備 2.1、登錄百度智能云平臺&#xff0c;獲取 API Key 和 Secret Key兩個…

leaflet前端初始化項目

1、通過npm安裝leaflet包&#xff0c;或者直接在項目中引入leaflet.js庫文件。 npm 安裝&#xff1a;npm i leaflet 如果在index.html中引入leaflet.js,在項目中可以直接使用變量L. 注意:盡量要么使用npm包&#xff0c;要么使用leaflet.js庫&#xff0c;兩者一起使用容易發生…

Deepseek官網接口文檔

API 接口 生成完成 生成聊天完成 創建模型 列出本地模型 顯示模型信息 復制模型 刪除模型 拉取模型 推送模型 生成嵌入 列出運行中的模型 版本 約定 模型名稱 模型名稱遵循 model:tag 格式&#xff0c;其中 model 可以有一個可選的命名空間&#xff0c;例如 ex…

容器運行常見數據庫

一.涉及鏡像壓縮包 均為amd架構版本&#xff1a;mysql:5.7.42、postgres:13.16、dm8:20250206_rev257733_x86_rh6_64、oceanbase-ce:v4.0、opengauss:5.0.2 通過網盤分享的文件&#xff1a;db.tgz 鏈接: https://pan.baidu.com/s/1EBbFPZj1FxCA4_GxjVunWg?pwd563s 提取碼: 5…

python爬蟲系列課程2:如何下載Xpath Helper

python爬蟲系列課程2:如何下載Xpath Helper 一、訪問極簡插件官網二、點擊搜索按鈕三、輸入xpath并點擊搜索四、點擊推薦下載五、將下載下來的文件解壓縮六、打開擴展程序界面七、將xpath.crx文件拖入擴展程序界面一、訪問極簡插件官網 極簡插件官網地址:https://chrome.zzz…

PHP支付寶--轉賬到支付寶賬戶

官方參考文檔&#xff1a; ?https://opendocs.alipay.com/open/62987723_alipay.fund.trans.uni.transfer?sceneca56bca529e64125a2786703c6192d41&pathHash66064890? 可以使用默認應用&#xff0c;也可以自建新應用&#xff0c;此處以默認應用來講解【默認應用默認支持…

前端開發崗模擬面試題套卷A答案及解析(一)技術面部分

前端開發崗模擬面試題套卷A答案及解析(一)技術面部分 (一)技術面 一、JavaScript核心技術(ES6+) 1-1、實現防抖函數 function debounce(fn, delay) {let timer = null;return function(...args) {clearTimeout(timer); // 清除已有定時器timer = setTimeout(() =>…

對稱加密算法——IDEA加密算法

Java IDEA算法詳解 1. 理論背景 IDEA&#xff08;International Data Encryption Algorithm&#xff09;是一種對稱密鑰加密算法&#xff0c;由Xuejia Lai和James Massey于1991年提出。它被設計用于替代DES&#xff08;Data Encryption Standard&#xff09;算法&#xff0c;…

單例模式、構造函數、左值右值

拷貝構造函數 簡單的說就是——用一個對象構造另外一個對象 class Myclass {public:int d0;Myclass(int d_){d d_}; //常用的構造函數Myclass(Myclass c) //拷貝構造函數{d c.d;} }; //對比 class Myclass {public:int d0;Myclass(int d_){d d_}; //常用的構造函數Myclass…

rustdesk遠程桌面自建服務器

首先&#xff0c;我這里用到的是阿里云服務器 centos7版本&#xff0c;win版客戶端。 準備工作 centos7 服務器端文件&#xff1a; https://github.com/rustdesk/rustdesk-server/releases/download/1.1.11-1/rustdesk-server-linux-amd64.zip win版客戶端安裝包&#xff1…

【深度學習】Transformer入門:通俗易懂的介紹

【深度學習】Transformer入門&#xff1a;通俗易懂的介紹 一、引言二、從前的“讀句子”方式三、Transformer的“超級閱讀能力”四、Transformer是怎么做到的&#xff1f;五、Transformer的“多視角”能力六、Transformer的“位置記憶”七、Transformer的“翻譯流程”八、Trans…

用deepseek學大模型03-數學基礎 概率論 最大似然估計(MLE)最大后驗估計(MAP)

https://metaso.cn/s/r4kq4Ni 什么是最大似然估計&#xff08;MLE&#xff09;最大后驗估計&#xff08;MAP&#xff09;&#xff1f;深度學習中如何應用&#xff0c;舉例說明。 好的&#xff0c;我現在需要回答關于最大似然估計&#xff08;MLE&#xff09;和最大后驗估計&…

Socket通訊協議理解及客戶端服務器程序流程

Socket通訊我們可以從以下幾個方面簡單理解 1.Socket是網絡通信中的一項重要技術&#xff0c;它提供了在網絡上進行數據交換的接口。用C#、Java、C等開發語言&#xff0c;都可以開發Socket網絡通信程序。 2.Socket(套接字)是計算機網絡編程中的一種抽象&#xff0c;它允許不同…

《Stable Diffusion繪畫完全指南:從入門到精通的Prompt設計藝術》-配套代碼示例

第一章&#xff1a;模型加載與基礎生成 1.1 基礎模型加載 from diffusers import StableDiffusionPipeline import torch# 加載SD 1.5基礎模型&#xff08;FP32精度&#xff09; pipe StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5",…

【DL】淺談深度學習中的知識蒸餾 | 輸出層知識蒸餾

目錄 一 核心概念與背景 二 輸出層知識蒸餾 1 教師模型訓練 2 軟標簽生成&#xff08;Soft Targets&#xff09; 3 學生模型訓練 三 擴展 1 有效性分析 2 關鍵影響因素 3 變體 一 核心概念與背景 知識蒸餾&#xff08;Knowledge Distillation, KD&#xff09;是一種模…

嵌入式學習第十六天--stdio(二)

文件打開 open函數 #include <fcntl.h> int open(const char *pathname&#xff0c;int flags); int open(const char *pathname&#xff0c;int flags&#xff0c;mode_t mode); 功能: 打開或創建文件 參數: pathname //打開的文件名 flags //操作…

對話智面創始人陶然:一是初心和心態,二是堅持和心力

隨著經濟全球化的加深和市場競爭的日益激烈&#xff0c;企業迅速發展成為了每一個企業家的夢想。然而&#xff0c;要實現企業的快速發展并保持競爭力&#xff0c;企業戰略的人力資源管理起著至關重要的作用。 企業的核心競爭力是“人才”的競爭&#xff0c;無論是研發、銷售、…

mybatis使用typeHandler實現類型轉換

使用mybatis作為操作數據庫的orm框架&#xff0c;操作基本數據類型時可以通過內置的類型處理器完成java數據類型和數據庫類型的轉換&#xff0c;但是對于擴展的數據類型要實現與數據庫類型的轉換就需要自定義類型轉換器完成&#xff0c;比如某個實體類型存儲到數據庫&#xff0…

Qt開發①Qt的概念+發展+優點+應用+使用

目錄 1. Qt的概念和發展 1.1 Qt的概念 1.2 Qt 的發展史&#xff1a; 1.3 Qt 的版本 2. Qt 的優點和應用 2.1 Qt 的優點&#xff1a; 2.2 Qt 的應用場景 2.3 Qt 的應用案例 3. 搭建 Qt 開發環境 3.1 Qt 的開發工具 3.2 Qt SDK 的下載和安裝 3.3 Qt 環境變量配置和使…

mac安裝Pyspark并連接Mysql

安裝Scala, apache-spark, Hadoop brew install scala brew install apache-spark brew install hadoop pip install pyspark注意不要自己另外安裝jdk, 會造成版本對不上報錯。因為安裝apache-spark的過程中會自動安裝openjdk。 配置環境變量 JAVA_HOME/opt/homebrew/Cellar…