5.4 开发首页页面
首页是本项目的主要操作页面,该页面包含文件夹列表、备忘录列表和备忘录编辑等功能。
因为首页的内容比较多,所以将文件夹列表和备忘录列表单独提取为组件,页面中只保留编辑器的部分。
5.4.1 编写首页组件
首页组件就是根组件 Home.vue,接下来我们编写这个组件。
(1)编辑模版代码,结构如下:
<!-- Home.vue -->
<template>
<main class="home-point">
<cus-header></cus-header>
<router-view></router-view>
</main>
</template>
<script setup lang="ts">
import CusHeader from "@/components/CusHeader.vue";
</script>
上面代码的模板中只用了两个组件:公共头部组件和路由视图组件。
公共头部组件
:只会加载一次,对除登录页外的所有页面生效。路由视图组件
:用于匹配定义在首页组件下动态切换的所有子路由组件。
(2)新建 views/index/index.vue 文件表示首页组件,并为该组件配置路由:
// router/index.ts
routes: [
{
path: "/",
component: HomeView,
redirect: "/index",
children: [
{
path: "index",
component: () => import("@/views/index/index.vue"),
},
],
},
];
在上面的代码中,首页被配置为首页根组件 Home.vue 的二级路由,同时添加了“redirect: '/index'”配置来保证打开网址时自动重定向到首页。
(3)按照左、中、右三栏布局结构编写模板代码:
<template>
<div class="index-page">
<div class="catalogs">
<!--文件夹区域-->
<Cataloge></Cataloge>
</div>
<div class="memos">
<!--备忘录列表区域-->
<Menos></Menos>
</div>
<div class="detail">
<!--编辑器区域-->
</div>
</div>
</template>
上述代码使用了 Cataloge 组件和 Menos 组件,即单独提取的文件夹列表组件和备忘录列表组件。编辑器区域的内容会在下一节展开介绍。
(4)编写 JavaScript 代码引入 Cataloge 组件和 Menos 组件,并初始化首页 Store:
<script setup lang="ts">
import { indexStore } from "@/stores";
import Cataloge from "./catalogs.vue";
import Menos from "./menos.vue";
const store = indexStore();
</script>
上述代码在同级目录下导入两个子组件,5.3.5 节和 5.3.6 节会详细介绍这两个组件。
(5)使用 Flex 布局实现页面结构的排版:
<style lang="less">
.index-page {
display: flex;
align-items: stretch;
height: calc(100vh - 55px);
.catalogs {
width: 20%;
background: #f9f9f9;
}
.memos {
width: 25%;
}
.detail {
flex: 1;
}
}
</style>
至此,完成首页的基本结构。
5.4.2 编写首页 Store
在首页中引入首页 Store,该 Store 会存储很多状态用于在首页和其子组件中使用。下面编写首页 Store 的代码。
(1)新建 stores/index 文件夹,并添加 index.ts 文件和 type.ts 文件。在 index.ts 文件中创建首页 Store:
import { defineStore } from "pinia";
const indexStore = defineStore("index", {
state: () => ({}),
});
export default indexStore;
(2)在 type.ts 文件中定义文件夹和备忘录的类型:
export interface CatalogType {
cata_id: number; // 文件夹 ID
user_id: number; // 用户 ID
cata_name: string; // 文件夹名称
}
export interface MemoType {
memo_id: number; // 备忘录 ID
cata_id: number; // 文件夹 ID
title: string; // 备忘录标题
content: string; // 备忘录内容
update_at: number; // 更新时间
}
在上述代码中,CatalogType 表示文件夹类型,MemoType 表示备忘录类型。文件夹数据和备忘录数据的字段必须严格匹配类型文件中的定义。
(3)在首页 Store 中添加 4 个状态,分别是文件夹列表、备忘录列表、当前文件夹 ID 和当前备忘录 ID。各状态的定义如下:
state: () => ({
catalogs: [] as CatalogType[], // 文件夹列表
memos: [] as MemoType[], // 备忘录列表
active_cataid: null as number | null, // 当前文件夹 ID
active_memoid: null as number | null, // 当前备忘录 ID
}),
在首页和子组件中读取这些状态,可以渲染出文件夹和备忘录的数据。
(4)添加设置状态的方法。从 localStorage 中获取数据并为 catalogs 状态和 memos 状态赋值,同时添加设置 active_cataid 和 active_memoid 的方法,编写 Action:
actions: {
// 获取目录列表
getCatalogs() {
let data = localGetItem("catalogs");
if (data) {
this.catalogs = data;
}
},
// 获取备忘录列表
getMemos() {
let data = localGetItem("memos");
if (data) {
this.memos = data;
}
},
// 设置备忘录 ID
setMemoId(id: number | null) {
this.active_memoid = id;
localSetItem("active_memoid", id);
},
setCateId(id: number | null) {
this.active_cataid = id;
localSetItem("active_cataid", id);
}
}
(5)在 stores/index.ts 文件中将首页 Store 全局导出:
export { default as indexStore } from "./index/index";
至此,可以在首页组件中导入并使用这些在首页 Store 中定义的状态和方法。