vue3+TypeScript+vue-router的使用方法
目錄
- 簡單使用
- 建立專案
- -cli建立
- vite建立
- 安裝vue-router
- 建立/修改元件
- 修改入口ts
- 啟動vue
- 在瀏覽器中訪問
- 檔案結構圖片
- 綜合使用
- 動態引數
- 使用watch監聽動態引數
- 使用組合API監聽動態引數
- 重定向
- 命名與別名
- 命名路由
- 命名檢視
- 別名
- 巢狀路由
- 式路由
簡單使用
建立專案
vue-cli建立
$npm install -g @vue/cli $vue --version @vue/cli 4.5.15 $vue create my-project
然後的步驟:
- Please pick a preset
選擇 Manually select features - Check the features needed for your project
TypeScript
,特別注意點空格是選擇,點回車是下一步 - Choose a version of Vue. that you want to start the project with
選擇 3.x (Preview) - Use class-style component syntax
直接回車 - Use Babel alongside TypeScript
直接回車 - Pick a linter / formatter config
直接回車 - Use history mode for router?
直接回車 - Pick a linter / formatter config
直接回車 - Pick additional lint features
- Where do you prefer placing config for Babel,ESLint,etc.?
直接回車 - Save this as a preset for future projects?
直接回車
檔案結構:
my-project +--- babel.config.js +--- package-lock.json +--- package.json +--- public | +--- favicon.ico | +--- index.html +--- README.md +--- src | +--- App.vue | +--- assets | | +--- logo.png | +--- components | | +--- HelloWorld.vue | +--- main.ts | +--- shims-vue.d.ts +--- tsconfig.json +--- node_modules | +--- ...
入口檔案為
src/main.ts
vite建立
執行以下命令建立專案
$npm init vite-app <project-name> $cd <project-name> $npm install $npm run dev
檔案結構:
project-name +--- index.html +--- package-lock.json +--- package.json +--- public | +--- favicon.ico +--- src | +--- App.vue | +--- assets | | +--- logo.png | +--- components | | +--- HelloWorld.vue | +--- index. | +--- main.js +--- node_modules | +--- ...
入口檔案為
src/main.ts
注意: 由於使用vite方法建立的專案沒有vue的宣告檔案,所以需要我們自定義,否則會報錯.src/shims-vue.d.ts
/* eslint-disable */ declare module '*.vue' { import type { DefineComponent } from 'vue' const component: DefineComponent<{},{},any> export default component }
安裝vue-router
$npm install vue-router@4
至此,package.json
如下:
{ "name": "my-project","version": "0.1.0","private": true,"scripts": { "serve": "vue-cli-service serve","build": "vue-cli-service build","lint": "vue-cli-service lint" },"dependencies": { "core-js": "^3.6.5","vue": "^3.0.0","vue-router": "^4.0.12" },"devDependencies": { "@typescript-eslint/eslint-plugin": "^4.18.0","@typescript-eslint/parser": "^4.18.0","@vue/cli-plugin-babel": "~4.5.0","@vue/cli-plugin-eslint": "~4.5.0","@vue/cli-plugin-typescript": "~4.5.0","@vue/cli-service": "~4.5.0","@vue/compiler-sfc": "^3.0.0","@vue/eslint-config-typescript": "^7.0.0","eslint": "^6.7.2","eslint-plugin-vue": "^7.0.0","typescript": "~4.1.5" } }
建立/修改元件
建立src/router/index.ts
import { createRouter,createWebHashHistory } from "vue-router" import Home from '../components/Home.vue' import About from '../components/About.vue' import User from '../components/User.vue' const routes = [ // router引數詳細看下文 { path: "/home",name: "home",component: Home },{ path: "/about",name: "about",component: About },{ path: "/user/:uid",// 動態引數 name: "user",component: User } ] export const router = createRouter({ history: createWebHashHistory(),routes: routes })
建立元件: Home.vue
About.vue
User.vue
src/components/Home.vue
<template> <div>home元件</div> </template> <script lang="ts"> import { defineComponent } from "vue"; export default defineComponent({ name: "Home",setup() { return { // 返回的資料 }; },}); </script>
src/components/About.vue
<template> <div>About元件</div> </template> <script lang="ts"> import { defineComponent } from "vue"; export default defineComponent({ name: "About",}); </script>
src/components/User.vue
<template> <div>User元件</div> </template> <script lang="ts"> import { defineComponent } from "vue"; export default defineComponent({ name: "User",}); </script>
修改App.vue
<template> <div>{{ appMessage }}</div> <!-- router-link會被渲染成a標籤 --> <router-link to="/home">home</router-link> <router-link to="/about">about</router-link> <router-link to="/user/lczmx">user</router-link> <!-- 路由出口 --> <!-- 路由匹配到的元件將渲染在這裡 --> <router-view></router-view> </template> <script lang="ts"> import { defineComponent } from "vue"; export default defineComponent({ name: "App",setup() { const appMessage = "App元件"; return { // 返回的資料 appMessage,}; },}); </script> <style> /* 新增樣式 */ #app { text-align: center; margin-top: 50px; } a { margin: 30px; display: inline-block; } </style>
修改入口ts
修改src/main.ts
:
import { createApp } from 'vue' import App from './App.vue' import './index.css' import { router } from './router' // 建立應用 返回對應的例項物件 const app = createApp(App) // 安裝 vue-router 外掛 app.use(router) // 呼叫mount方法 app.mount('#app')
啟動vue
$npm run serve > [email protected] serve > vue-cli-service serve INFO Starting development server... 98% after emitting CopyPlugin DONE Compiled successfully in 6387ms 下午4:14:30 App running at: - Local: http://localhost:8080/ - Network: http://192.168.43.12:8080/ Note that the development build is not optimized. To create a production build,run npm run build. No issues found.
在瀏覽器中訪問
根據提示,訪問http://localhost:8080/
,如下圖
檔案結構圖片
綜合使用
動態引數
假如我們需要的路由是: /user/lczmx
和/user/jack
,但是我們明顯不可能為這兩個路由定義兩個不同的元件,最好的方法就是使用動態引數:
const routes = [ // 動態段以冒號開始 { path: '/users/:id',component: User },// 使用正則表示式 `()` 裡面的東西會傳給前面的pathMatch // 值在route.params.pathMatch下 { path: '/:pathMatch(.*)*',name: 'NotFound',component: NotFound },]
匹配時,會將引數對映到router
例項的currentRoute.value.params
上
注意vue2中: 由於在
setup
無法使用this.$route
和this.$router
至於如何獲取,看我的另一篇部落格: vue3獲取當前路由 和 官網: Vue Router 和 組合式 API
匹配列表
匹配模式 | 匹配路徑 | 當前路由的引數 |
---|---|---|
/users/:username | /users/eduardo | { username: 'eduardo' } |
/users/:username/posts/:postId | /users/eduardo/posts/123 | { username: 'eduardo',postId: '123' } |
在使用帶有引數的路由時需要注意: 由於相同的元件例項將被重複使用,所以元件的生命週期鉤子不會被呼叫
但是我們可以對路由進行監聽
使用watch監聽動態引數
修改src/components/User.vue
:
<template> <div>User元件</div> <p>當前使用者: {{ uid }}</p> <router-link to="/user/lczmx">lczmx</router-link> <router-link to="/user/jack">jack</router-link> </template> <script lang="ts"> import { defineComponent,watch,ref } from "vue"; import { useRouter } from "vue-router"; export default defineComponent({ name: "User",setup() { const router = useRouter(); const uid = ref(router.currentRoute.value.params.uid); watch( // 監聽非響應式資料 () => router.currentRoute.value,(val) => { // 修改uid uid.value = val.params.uid; } ); return { // 返回的資料 uid,}); </script>
使用組合API監聽動態引數
https://next.router.vuejs.org/zh/guide/advanced/composition-api.html
重定向
下面使用router
的全部引數:
const routes = [ { path: "/",// 寫法1 寫死url // redirect: "/home",// 訪問 "/" 時 跳轉到 "/home" // 寫法2 跳轉到對應的命名路由 redirect: { name: "home" },// 寫法3 定義一個方法 // 該方法亦可以 返回一個相對路徑 /* redirect: to => { // 方法接收目標路由作為引數 "to" // return 重定向的字串路徑/路徑物件 // query指定引數 return { path: '/home',query: { q: to.params.searchText } } },*/ },{ path: "/home",component: Home } ]
注意,重定向不會觸發 導航守衛
另附官網的例子: Named Views - Vue Router 4 examples
命名與別名
命名路由
給路由一個名稱,可以在其他路由中使用,如:
redirect
和router-link
const routes = [ { path: '/user/:username',name: 'user',component: User } ]
在redirect
的使用如上文,而router-link
如下:
<template> <div>User元件</div> <p>當前使用者: {{ uid }}</p> <router-link :to="{ name: 'user',params: { uid: 'lczmx' } }" >lczmx</router-link > <router-link :to="{ name: 'user',params: { uid: 'jack' } }" >jack</router-link > </template>
在router.push
(router
是router
物件)中使用:
router.push({ name: 'user',params: { uid: 'lczmx' } })
命名檢視
即,我們可以
router-view
定義一個名字,已達到實現可複用的效果
我們可以使用這個功能實現 一個側邊欄等
舉個例子
定義路由:
import { createRouter,createWebHashHistory } from "vue-router" import Home from '../components/Home.vue' import About from '../components/About.vue' import User from '../components/User.vue' const routes = [ { path: "/",components: { default: Home,// 預設用Home元件 a: About,// a用About元件 b: User,// b用User元件 },},{ path: "/home",components: { default: About,// 預設用About元件 a: Home,// a用Home元件 b: User,] export const router = createRouter({ history: createWebHashHistory(),routes: routes })
修改App.vue
<template> <div>{{ appMessage }}</div> <!-- router-link會被渲染成a標籤 --> <router-link to="/">/</router-link> <router-link to="/home">/home</router-link> <!-- 路由出口 --> <!-- 路由匹配到的元件將渲染在這裡 --> <!-- default --> <router-view></router-view> <router-view name="about"></router-view> <router-view http://www.cppcns.comname="user"></router-view> </template> <script lang="ts"> import { defineComponent } from "vue"; export default defineComponent({ name: "App",}); </script> <style> /* 新增樣式 */ #app { text-align: center; margin-top: 50px; } a { margin: 30px; display: inline-block; } </style>
其他元件About.vue
:
<template> <div>about元件</div> </template>
Home.vue
:
<template> <div>home元件</div> </template>
User.vue
<template> <div>user元件</div> </template>
啟動服務並訪問vue
如圖:
假如不指定檢視名,那麼為
default
別名
可以實現 不同url 訪問同一路由的效果
const routes = [ // 可以訪問 "/home" 也可以訪問 "/" // 且訪問的路徑不會改變 { path: "/home",component: Home,alias: "/" }
巢狀路由
之前我們在App.vue
中定義router-view
,讓其他元件在哪裡渲染
但假如我們需要在其他元件中渲染的話,就需要巢狀路由了
使用
children
巢狀路由,它的值是路由資料,就好像外部的router
那樣定義
例子:
router.index.ts
import { createRouter,createWebHashHistory } from "vue-router" import Home from '../components/Home.vue' import About from '../components/About.vue' import User from '../components/User.vue' import UserHome from '../components/UserHome.vue' import UserSettings from '../components/UserSettings.vue' import UserProfile from '../components/UserProfile.vue' const routes = [ // 可以訪問 "/home" 也可以訪問 "/" // 且訪問的路徑不會改變 { path: "/home",name: "home",alias: "/" },component: User,// 內部有router-view渲染要巢狀的路由 children: [ // 匹配形如 /user/lczmx 的url { path: "",component: UserHome },// 匹配形如 /user/lczmx/settings 的url { path: "settings",component: UserSettings,name: "user-settings" },// 匹配形如 /user/lczmx/profile 的url { path: "profile",component: UserProfile,name: "user-profile" } ] } ] export const router = createRouter({ history: createWebHashHistory(),routes: routes })
注意: 假如
children
中沒有path: ""
的話,那麼訪問/user/lczmx
,只能得到一個頁面空白
User.vue
<template> <div> <router-link :to="{ name: 'user-settings' }">settings</router-link> <router-link :to="{ name: 'user-profile' }">profile</router-link> </div> <router-view></router-view> </template>
UserHome.vue
<template> <div>使用者主頁</div> </template>
UserProfile.vue
<template> <div>使用者詳細資訊頁面</div> </template>
UserSettings.vue
<template> <div>使用者設定頁面</div> </template>
啟動並訪問
在瀏覽器中測試:
程式設計式路由
即不通過a標籤,而是通過js/ts
改變路由,原理是向history
棧新增一個新的記錄
在vue3中,有以下寫法
<template> <div>about元件</div> <button @click="changeRouter">修改路由</button> </template> <script lang="ts"> import { defineComponent } from "vue"; import { useRouter } from "vue-router"; export default defineComponent({ name: "About",setup() { // 獲得router物件 const router = useRouter(); const changeRouter = () => { /* 修改路由的例子 */ // 1 字串路徑 router.push("/users/lczmx"); // 2 帶有路徑的物件 router.push({ path: "/users/lczmx" }); // 3 命名的路由,並加上引數,讓路由建立 url router.push({ name: "user",params: { username: "lczmx" } }); // 4 帶查詢引數,結果是 /register?plan=private router.push({ path: "/register",query: { plan: "private" } }); // 5 帶 hash,結果是 /about#team router.push({ path: "/about",hash: "#team" }); // 6 我們可以手動建立 url,但我們必須自己處理編碼 const username = "lczmx"; router.push(`/user/${username}`); // -> /user/lczmx // 同樣 router.push({ path: `/user/${username}` }); // -> /user/lczmx // 如果可能的話,使用 `name` 和 `params` 從自動 URL 編碼中獲益 router.push({ name: "user",params: { username } }); // -> /user/lczmx // 7 `params` 不能與 `path` 一起使用,否則 `params` 將會被忽略 router.push({ path: "/user",params: { username } }); // -> /user // 8 replace為true 不向history 中新增 router.push({ path: "/home",replace: true }); // 等同於 router.replace({ path: "/home" }); // 9 橫跨歷史 // 向前移動一條記錄,與 router.forward() 相同 router.go(1); // 返回一條記錄,與router.back() 相同 router.go(-1); // 前進 3 條記錄 router.go(3); // 如果沒有那麼多記錄,靜默失敗 router.go(-100); router.go(100); }; return { // 返回的資料 changeRouter,}); </script> <style> button { margin: 30px; } </style>
更多見vue-router4官網: Vue Router
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。