Skip to content

5.5 开发公共列表组件

上一节开发首页页面时,我们直接引用了 文件夹列表组件备忘录列表组件,本节我们就来开发这两个组件。

5.5.1 文件夹列表组件

文件夹列表组件可以将首页左侧的文件夹区域提取到单独的组件中,主要用来展示文件夹列表,对文件夹数据进行增、查、改、删。

(1)在 views/index 目录下创建 catalogs.vue 组件,并添加模板代码:

vue
<template>
  <div class="catalogs-comp">
    <div class="handel">
      <el-button round @click="toCreate">新建文件夹</el-button>
    </div>
    <div class="catas-list">
      <div
        v-for="item in store.catalogs"
        :key="item.cata_id"
        :class="
          store.active_cataid == item.cata_id ? 'cata-item active' : 'cata-item'
        "
        @click="store.setCateId(item.cata_id)"
      >
        <el-icon :size="17">
          <FolderOpened v-if="store.active_cataid == item.cata_id" />
          <FolderRemove v-else />
        </el-icon>
        <span class="text">{{ item.cata_name }}</span>
      </div>
    </div>
  </div>
</template>

上述代码遍历了仓库中的文件夹列表状态 catalogs,并通过 active_cataid 状态来判断当前文件夹是否被选中,从而展示不同的图标与样式。

(2)模板中有“新建文件夹”按钮,在首页 Store 中添加 createCata()方法实现新建文件夹的功能:

js
import { geneId, localSetItem, localGetItem } from "@/utils";
actions: {
  // 新建文件夹
  createCata(val: CatalogType) {
    let curcata = Object.assign({}, val, {
      cata_id: geneId();
    });
    this.catalogs.push(curcata);
    localSetItem("catalogs", this.catalogs);
  },
}

新建文件夹时会自动生成 ID 标识,这里便用的是工具函数 geneId()。文件夹有“增、查、改、删”的功能,这里只介绍新建文件夹的函数,其他的函数与其类似。

(3)编写 JavaScript 代码,导入首页 Store 并添加新建文件夹的函数:

vue
<script setup lang="ts">
import { indexStore } from "@/stores";
import { ElMessageBox } from "element-plus";
const store = indexStore();
// 新建文件夹
const toCreate = () => {
  ElMessageBox.prompt("输入文件夹名称", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
  }).then((res) => {
    if (res.value) {
      store.createCata({
        user_id: "xxx",
        cata_name: res.value,
      });
    }
  });
};
</script>

最终的文件夹的页面展示效果如图 5-5 所示。

5.5.2 备忘录列表组件

备忘录列表组件与文件夹列表组件的实现原理相同,都将页面单独提取为组件,并把状态定义在首页 Store 中。

(1)在 views/index 目录下创建 menos.vue 组件,并添加模板代码:

vue
<template>
  <div class="menos-comp">
    <div class="handel">
      <span>共{{ store.activeMemos.length }}条备忘录</span>
      <el-button :icon="Plus" circle @click="toCreate" />
    </div>
    <div class="menos-list">
      <div
        v-for="item in store.activeMemos"
        :key="item.memo_id"
        :class="
          store.active_memoid == item.memo_id ? 'meno-item active' : 'meno-item'
        "
        @click="store.setMemoId(item.memo_id)"
      >
        <div class="meno-item-inner">
          <h3>{{ item.title }}</h3>
          <span class="text">{{ FormatTime(item.update_at) }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

上述代码的头部用来展示备忘录数量和添加按钮,下部用来遍历 activeMemos 状态,以及展示当前的备忘录列表。备忘录的时间用工具函数 FormatTime()处理,并且通过 active 类名来表示选中状态。

(2)在首页 Store 中定义 createMemo()方法用于创建备忘录,定义 getMemos()方法用于获取备忘录列表,并定义 activeMemos 表示当前的备忘录列表:

js
actions: {
  getMemos() {
    let data = localGetItem("memos");
    if (data) this.memos = data;
  },
  createMemo(val: Pick<MemoType, "title" | "cata_id" | "content">) {
    let memo = Object.assign({}, val, {
      memo_id: geneId(),
      update_at: new Date().valueOf(),
    });
    this.memos.push(memo);
    localSetItem("memos", this.memos);
  }
}
getters: {
  activeMemos: (state) => {
    return state.memos.filter((r) => r.cata_id == state.active_cataid);
  },  // 当前的备忘录列表
}

创建备忘录时自动生成备忘录 ID,同时修改更新时间;activeMemos 的值会根据 active_cataid 状态的改变自动更新,这些状态刚好满足在模板中使用。

(3)编写 JavaScript 代码,创建备忘录弹框,输入标题并创建数据:

vue
<script setup lang="ts">
import { indexStore } from "@/stores";
import { ElMessageBox } from "element-plus";
import { FormatTime } from "@/utils";
const store = indexStore();
// 创建备忘录弹框
const toCreate = () => {
  ElMessageBox.prompt("输入备忘录标题", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
  }).then((res) => {
    if (res.value && store.active_cataid) {
      store.createMemo({
        cata_id: store.active_cataid,
        title: res.value,
        content: "",
      });
    }
  });
};
</script>

最终备忘录列表的页面效果如图 5-6 所示。