# 23. TodoList 路由模組
# 關於 todo list
統整前面學到的觀念,製作 todo list 。
# 功能
- 能新增事項
- 能刪除事項,並跳出 alert 提醒。
- 單擊事項能修改完成狀態。
- 雙擊事項能修改事項內容。
- 切換路由能陳列對應狀態的事項。
- 將資料保存到 localStorage。
# 作法
- 使用 component 建立區塊
- 使用 Vuex store 存放資料
# 起始架構
使用 Vue CLI,並安裝以下依賴:
- vue-router
- vuex
- vuex-router-syne (opens new window):
- 將 Vue Router 同步為 Vuex state 的一部分。
- 這個套件只是讓開發者能方便讀取
$route
的內容。修改仍需透過 Vue Router 而非 Vuex。
# 安裝 vuex-router-sync
# 安裝
可在終端機輸入 vue ui
,從 UI 介面的 「依賴」 搜尋 "vuex-router-sync" 下載並安裝。
# 使用
安裝好 "vuex-router-sync" 之後,到 "main.js" 進行以下修改:
//- main.js
import { createApp } from "vue";
import App from "./App.vue";
import { sync } from 'vuex-router-sync' // 引入 vuex-router-sync
import router from "./router";
import store from "./store";
sync(store, router) // 同步 router 和 store
createApp(App).use(store).use(router).mount("#app");
# 原理
- 這個套件會在 store 增加一個名為
route
的模組,用來表示目前路由的狀態。
store.state.route.path // current path (字串)
store.state.route.params // current params (物件)
store.state.route.query // current query (物件)
- 切換路由時,store 的狀態會被更新。
store.state.route
是不能修改的,因為該值取自 URL,無法修改該值去觸發瀏覽器的導航行為。- 可以透過以下方法去修改路由:
$router.push()
$router.go()
$router.push({query: {...}})
:更新目前路徑的 query 字串。
# 使用路徑篩選事項
在這個範例,我們會使用 router 去篩選出符合的事項。因此,我們將 router 中的 routes 改為:
//- router/index.js
import { createRouter, createWebHistory } from "vue-router";
const routes = [
{
path: "/all", // 全部事項
name: "all",
},
{
path: "/active", // 未完成事項
name: "active",
},
{
path: "/complete", // 已完成事項
name: "complete",
},
{
path: "*",
redirect: "/all" // 如果是其他參數,則重新導到 all
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;
相對地,我們也要在 "App.vue" 修改路徑及其名稱:
//- App.vue
<template>
<div id="nav">
<router-link to="/all">全部</router-link> |
<router-link to="/acitve">未完成</router-link> |
<router-link to="/complete">已完成</router-link>
</div>
<router-view />
</template>
沒用到的 .vue 檔案和 component 檔案就先刪掉,另外建立需要的模組。
WARNING
補充:
從 Vue 2.x 遷移到 Vue 3.x,Vue Router 移除了 *
,改用客製化的 regex 參數定義所有路由。
const routes = [
// pathMatch 是参数的名称,例如,跳转到 /not/found 会得到
// { params: { pathMatch: ['not', 'found'] } }
// 这要归功于最后一个 *,意思是重复的参数,如果你
// 打算直接使用未匹配的路径名称导航到该路径,这是必要的
{ path: '/:pathMatch(.*)*', name: 'not-found', component: NotFound },
// 如果你省略了最后的 `*`,在解析或跳转时,参数中的 `/` 字符将被编码
{ path: '/:pathMatch(.*)', name: 'bad-not-found', component: NotFound },
]
WARNING
補充:
如果 Vue router 沒有設定 component ,瀏覽器執行後報錯,可在路由中設定 component: {render: (e) => e("router-view")}
。例如:
const routes = [
{
path: "/all",
name: "all",
component: {render: (e) => e("router-view")}
},
{
path: "/active",
name: "active",
component: {render: (e) => e("router-view")}
},
{
path: "/complete",
name: "complete",
component: {render: (e) => e("router-view")}
},
{
path: "/:pathMatch(.*)*",
redirect: "/all"
},
];