簡單使用
建立項目
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.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 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.css
| +--- 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
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", setup() { return { // 傳回的資料 }; }, }); </script>
src/components/User.vue
<template> <div>User元件</div> </template> <script lang="ts"> import { defineComponent } from "vue"; export default defineComponent({ name: "User", setup() { return { // 傳回的資料 }; }, }); </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
至于如何擷取, 看我的另一篇部落格: vue3擷取目前路由 和 官網: Vue Router 和 組合式 API
this.$router
比對清單
比對模式 | 比對路徑 | 目前路由的參數 |
---|---|---|
| | |
| | |
在使用帶有參數的路由時需要注意: 由于相同的元件執行個體将被重複使用,是以元件的生命周期鈎子不會被調用
但是我們可以對路由進行監聽
使用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",
name: "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, // 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 name="user"></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>
- 其他元件
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",
name: "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", component: Home, alias: "/" }, { path: "/about", name: "about", component: About }, { path: "/user/:uid", // 動态參數 name: "user", 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
本文來自部落格園,作者:403·Forbidden,轉載請注明原文連結:https://www.cnblogs.com/lczmx/p/15763999.html