vue3+TypeScript+vue-router的使用方法
簡(jiǎn)單使用
創(chuàng)建項(xiàng)目
vue-cli創(chuàng)建
$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
,特別注意點(diǎn)空格是選擇,點(diǎn)回車是下一步 - Choose a version of Vue.js 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?
直接回車
文件結(jié)構(gòu):
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創(chuàng)建
執(zhí)行以下命令創(chuàng)建項(xiàng)目
$npm init vite-app <project-name> $cd <project-name> $npm install $npm run dev
文件結(jié)構(gòu):
project-name +--- index.html +--- package-lock.json +--- package.json +--- public | +--- favicon.ico +--- src | +--- App.vue | +--- assets | | +--- logo.png | +--- components | | +--- HelloWorld.vue | +--- index.css | +--- main.js +--- node_modules | +--- ...
入口文件為
src/main.ts
注意: 由于使用vite方法創(chuàng)建的項(xiàng)目沒(méi)有vue的聲明文件, 所以需要我們自定義, 否則會(huì)報(bào)錯(cuò).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" } }
創(chuàng)建/修改組件
創(chuàng)建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參數(shù)詳細(xì)看下文 { path: "/home", name: "home", component: Home }, { path: "/about", name: "about", component: About }, { path: "/user/:uid", // 動(dòng)態(tài)參數(shù) name: "user", component: User } ] export const router = createRouter({ history: createWebHashHistory(), routes: routes })
創(chuàng)建組件: 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 { // 返回的數(shù)據(jù) }; }, }); </script>
src/components/About.vue
<template> <div>About組件</div> </template> <script lang="ts"> import { defineComponent } from "vue"; export default defineComponent({ name: "About", setup() { return { // 返回的數(shù)據(jù) }; }, }); </script>
src/components/User.vue
<template> <div>User組件</div> </template> <script lang="ts"> import { defineComponent } from "vue"; export default defineComponent({ name: "User", setup() { return { // 返回的數(shù)據(jù) }; }, }); </script>
修改App.vue
<template> <div>{{ appMessage }}</div> <!-- router-link會(huì)被渲染成a標(biāo)簽 --> <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 { // 返回的數(shù)據(jù) 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' // 創(chuàng)建應(yīng)用 返回對(duì)應(yīng)的實(shí)例對(duì)象 const app = createApp(App) // 安裝 vue-router 插件 app.use(router) // 調(diào)用mount方法 app.mount('#app')
啟動(dòng)vue
$npm run serve > my-project@0.1.0 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.
在瀏覽器中訪問(wèn)
根據(jù)提示, 訪問(wèn)http://localhost:8080/
, 如下圖
文件結(jié)構(gòu)圖片
綜合使用
動(dòng)態(tài)參數(shù)
假如我們需要的路由是: /user/lczmx
和/user/jack
, 但是我們明顯不可能為這兩個(gè)路由定義兩個(gè)不同的組件, 最好的方法就是使用動(dòng)態(tài)參數(shù):
const routes = [ // 動(dòng)態(tài)段以冒號(hào)開(kāi)始 { path: '/users/:id', component: User }, // 使用正則表達(dá)式 `()` 里面的東西會(huì)傳給前面的pathMatch // 值在route.params.pathMatch下 { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound }, ]
匹配時(shí), 會(huì)將參數(shù)映射到router
實(shí)例的currentRoute.value.params
上
注意vue2中: 由于在
setup
無(wú)法使用this.$route
和this.$router
至于如何獲取, 看我的另一篇博客: vue3獲取當(dāng)前路由 和 官網(wǎng): Vue Router 和 組合式 API
匹配列表
匹配模式 | 匹配路徑 | 當(dāng)前路由的參數(shù) |
---|---|---|
/users/:username | /users/eduardo | { username: 'eduardo' } |
/users/:username/posts/:postId | /users/eduardo/posts/123 | { username: 'eduardo', postId: '123' } |
在使用帶有參數(shù)的路由時(shí)需要注意: 由于相同的組件實(shí)例將被重復(fù)使用,所以組件的生命周期鉤子不會(huì)被調(diào)用
但是我們可以對(duì)路由進(jìn)行監(jiān)聽(tīng)
使用watch監(jiān)聽(tīng)動(dòng)態(tài)參數(shù)
修改src/components/User.vue
:
<template> <div>User組件</div> <p>當(dāng)前用戶: {{ 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( // 監(jiān)聽(tīng)非響應(yīng)式數(shù)據(jù) () => router.currentRoute.value, (val) => { // 修改uid uid.value = val.params.uid; } ); return { // 返回的數(shù)據(jù) uid, }; }, }); </script>
使用組合API監(jiān)聽(tīng)動(dòng)態(tài)參數(shù)
https://next.router.vuejs.org/zh/guide/advanced/composition-api.html
重定向
下面使用router
的全部參數(shù):
const routes = [ { path: "/", // 寫(xiě)法1 寫(xiě)死url // redirect: "/home", // 訪問(wèn) "/" 時(shí) 跳轉(zhuǎn)到 "/home" // 寫(xiě)法2 跳轉(zhuǎn)到對(duì)應(yīng)的命名路由 redirect: { name: "home" }, // 寫(xiě)法3 定義一個(gè)方法 // 該方法亦可以 返回一個(gè)相對(duì)路徑 /* redirect: to => { // 方法接收目標(biāo)路由作為參數(shù) "to" // return 重定向的字符串路徑/路徑對(duì)象 // query指定參數(shù) return { path: '/home', query: { q: to.params.searchText } } }, */ }, { path: "/home", name: "home", component: Home } ]
注意, 重定向不會(huì)觸發(fā) 導(dǎo)航守衛(wèi)
另附官網(wǎng)的例子: Named Views - Vue Router 4 examples
命名與別名
命名路由
給路由一個(gè)名稱, 可以在其他路由中使用, 如:
redirect
和router-link
const routes = [ { path: '/user/:username', name: 'user', component: User } ]
在redirect
的使用如上文, 而router-link
如下:
<template> <div>User組件</div> <p>當(dāng)前用戶: {{ 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
對(duì)象)中使用:
router.push({ name: 'user', params: { uid: 'lczmx' } })
命名視圖
即, 我們可以
router-view
定義一個(gè)名字, 已達(dá)到實(shí)現(xiàn)可復(fù)用的效果
我們可以使用這個(gè)功能實(shí)現(xiàn) 一個(gè)側(cè)邊欄等
舉個(gè)例子
定義路由:
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, // 默認(rèn)用Home組件 a: About, // a用About組件 b: User, // b用User組件 }, }, { path: "/home", components: { default: About, // 默認(rèn)用About組件 a: Home, // a用Home組件 b: User, // b用User組件 }, }, ] export const router = createRouter({ history: createWebHashHistory(), routes: routes })
修改App.vue
<template> <div>{{ appMessage }}</div> <!-- router-link會(huì)被渲染成a標(biāo)簽 --> <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 name="user"></router-view> </template> <script lang="ts"> import { defineComponent } from "vue"; export default defineComponent({ name: "App", setup() { const appMessage = "App組件"; return { // 返回的數(shù)據(jù) appMessage, }; }, }); </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>
啟動(dòng)服務(wù)并訪問(wèn)vue
如圖:
假如不指定視圖名, 那么為
default
別名
可以實(shí)現(xiàn) 不同url 訪問(wèn)同一路由的效果
const routes = [ // 可以訪問(wèn) "/home" 也可以訪問(wèn) "/" // 且訪問(wèn)的路徑不會(huì)改變 { path: "/home", name: "home", component: Home, alias: "/" }
嵌套路由
之前我們?cè)?code>App.vue中定義router-view
, 讓其他組件在哪里渲染
但假如我們需要在其他組件中渲染的話, 就需要嵌套路由了
使用
children
嵌套路由, 它的值是路由數(shù)據(jù), 就好像外部的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 = [ // 可以訪問(wèn) "/home" 也可以訪問(wèn) "/" // 且訪問(wèn)的路徑不會(huì)改變 { path: "/home", name: "home", component: Home, alias: "/" }, { path: "/about", name: "about", component: About }, { path: "/user/:uid", // 動(dòng)態(tài)參數(shù) name: "user", component: User, // 內(nèi)部有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
中沒(méi)有path: ""
的話, 那么訪問(wèn)/user/lczmx
, 只能得到一個(gè)頁(yè)面空白
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>用戶主頁(yè)</div> </template>
UserProfile.vue
<template> <div>用戶詳細(xì)信息頁(yè)面</div> </template>
UserSettings.vue
<template> <div>用戶設(shè)置頁(yè)面</div> </template>
啟動(dòng)并訪問(wèn)
在瀏覽器中測(cè)試:
編程式路由
即不通過(guò)a標(biāo)簽, 而是通過(guò)js/ts
改變路由, 原理是向history
棧添加一個(gè)新的記錄
在vue3中, 有以下寫(xiě)法
<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對(duì)象 const router = useRouter(); const changeRouter = () => { /* 修改路由的例子 */ // 1 字符串路徑 router.push("/users/lczmx"); // 2 帶有路徑的對(duì)象 router.push({ path: "/users/lczmx" }); // 3 命名的路由,并加上參數(shù),讓路由建立 url router.push({ name: "user", params: { username: "lczmx" } }); // 4 帶查詢參數(shù),結(jié)果是 /register?plan=private router.push({ path: "/register", query: { plan: "private" } }); // 5 帶 hash,結(jié)果是 /about#team router.push({ path: "/about", hash: "#team" }); // 6 我們可以手動(dòng)建立 url,但我們必須自己處理編碼 const username = "lczmx"; router.push(`/user/${username}`); // -> /user/lczmx // 同樣 router.push({ path: `/user/${username}` }); // -> /user/lczmx // 如果可能的話,使用 `name` 和 `params` 從自動(dòng) URL 編碼中獲益 router.push({ name: "user", params: { username } }); // -> /user/lczmx // 7 `params` 不能與 `path` 一起使用, 否則 `params` 將會(huì)被忽略 router.push({ path: "/user", params: { username } }); // -> /user // 8 replace為true 不向history 中添加 router.push({ path: "/home", replace: true }); // 等同于 router.replace({ path: "/home" }); // 9 橫跨歷史 // 向前移動(dòng)一條記錄,與 router.forward() 相同 router.go(1); // 返回一條記錄,與router.back() 相同 router.go(-1); // 前進(jìn) 3 條記錄 router.go(3); // 如果沒(méi)有那么多記錄,靜默失敗 router.go(-100); router.go(100); }; return { // 返回的數(shù)據(jù) changeRouter, }; }, }); </script> <style> button { margin: 30px; } </style>
更多見(jiàn)vue-router4官網(wǎng): Vue Router
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue仿網(wǎng)易云音樂(lè)播放器界面的簡(jiǎn)單實(shí)現(xiàn)過(guò)程
興趣乃學(xué)習(xí)的動(dòng)力,想自己動(dòng)手寫(xiě)個(gè)音樂(lè)播放器,查了網(wǎng)上一些博客寫(xiě)了一個(gè),這篇文章主要給大家介紹了關(guān)于vue仿網(wǎng)易云音樂(lè)播放器界面的簡(jiǎn)單實(shí)現(xiàn)過(guò)程,需要的朋友可以參考下2021-11-11vue?@scroll監(jiān)聽(tīng)滾動(dòng)條事件方式
這篇文章主要介紹了vue?@scroll監(jiān)聽(tīng)滾動(dòng)條事件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11VSCode中寫(xiě)Vue沒(méi)有代碼提示的解決步驟(附圖文)
這篇文章主要給大家介紹了關(guān)于VSCode中寫(xiě)Vue沒(méi)有代碼提示的解決步驟,代碼提示功能能夠大大的提高開(kāi)發(fā)效率,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09利用Vue實(shí)現(xiàn)一個(gè)累加向上漂浮動(dòng)畫(huà)
在不久之前,看到一個(gè)比較有意思的小程序,就是靜神木魚(yú),可以實(shí)現(xiàn)在線敲木魚(yú),自動(dòng)敲木魚(yú),手盤(pán)佛珠,靜心頌缽的,下面就來(lái)揭秘如何實(shí)現(xiàn)這個(gè)小程序中敲木魚(yú)的累加向上漂浮動(dòng)畫(huà),需要的可以參考一下2022-11-11vue在響應(yīng)頭response中獲取自定義headers操作
這篇文章主要介紹了vue在響應(yīng)頭response中獲取自定義headers操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07Vue中mixins的使用方法以及實(shí)際項(xiàng)目應(yīng)用指南
vue中提供了一種混合機(jī)制--mixins,用來(lái)更高效的實(shí)現(xiàn)組件內(nèi)容的復(fù)用,下面這篇文章主要給大家介紹了關(guān)于Vue中mixins的使用方法以及實(shí)際項(xiàng)目應(yīng)用指南,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03