勇哥

勇哥开发之路

I build things on web.

Vue3 において、子コンポーネント間でイベントを伝達する方法

最近勇哥は知識ベースに基づく AI アプリケーションを開発しており、MVP はすでにオンラインになっています。現在、製品運営者が文書をアップロードしやすくするための知識ベース管理バックエンドを作成しています。

知識ベース管理バックエンドは、Vue3 + Element Plusvue-pure-admin に基づいています。

vue-pure-admin は Element Plus をラップしており、バックエンド管理システムの構築が非常に便利で、基本的にすぐに使えます。

しかし、一部のインタラクションは自分で実装する必要があります。

例えば、大部分のバックエンド管理システムにある機能:
リストページのヘッダーに「新規追加」の操作があり、新規追加が成功した後、リストが自動的に更新され、最新のデータが表示されます。

Vue3 を使ってこのインタラクションを実現するのは非常にスムーズです。親コンポーネントで更新メソッドを定義し、関連する子コンポーネントに渡すだけで済みます。

この機能は主に 3 つのファイルに関係しています:

  1. リストエントリの親コンポーネント knowledge/index.vue
  2. リストデータを表示する子コンポーネント knowledge/table/index.vue
  3. 新規追加機能の子コンポーネント knowledge/dialog/dialog.vue

実装手順は以下の通りです:

親コンポーネントに ref 参照と更新メソッドを追加#

親コンポーネント knowledge/index.vue の核心コードは以下の通りです:

<script setup lang="ts">
import Search from "./form/search.vue";
import Table from "./table/index.vue";
import DialogForm from "./dialog/dialog.vue";
import { ref } from "vue";

const tableRef = ref();

// 更新メソッドを定義
const refreshTable = () => {
  tableRef.value?.refresh();
};

defineOptions({
  name: "KnowledgeIndex"
});
</script>

<template>
  <el-card shadow="never">
    <template #header>
      <div class="flex items-center">
        <component :is="Search" class="flex-1" />
        <component :is="DialogForm" class="flex-none" @success="refreshTable" />
      </div>
    </template>
    <template #default>
      <component :is="Table" ref="tableRef" />
    </template>
  </el-card>
</template>

データを表示する子コンポーネントで更新メソッドを公開#

子コンポーネント knowledge/table/index.vue でデータリストを表示する核心コードは以下の通りです:

<script setup lang="ts">
const getDataList  = function (){
  // リストデータの具体的な実装
  ...
};

// 親コンポーネントに更新メソッドを公開
defineExpose({
  refresh: getDataList
});
</script>

新規追加機能の子コンポーネントで成功時のトリガーイベントを追加#

子コンポーネント knowledge/dialog/dialog.vue でポップアップフォームを実装する核心コードは以下の通りです:

const emit = defineEmits(['success']);

const handleConfirm = async () => {
  const params = values.value as unknown as ParamsDatahub;
  const res = await saveKnowledgeDatahub(params);
  if (res.success) {
    visible.value = false;
    emit('success'); // 成功イベントをトリガー
  }
};
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。