Vue3のdefineComponentの役割についての簡単な説明

Vue3のdefineComponentの役割についての簡単な説明

defineComponent 関数は、単にセットアップ関数をカプセル化し、オプション オブジェクトを返します。

エクスポート関数defineComponent(オプション: 不明) {
  isFunction(options) を返します? { setup: options } : options
}

defineComponent に関して最も重要なことは、TypeScript ではコンポーネントに正しいパラメータ型推論を与えることです。

ここに画像の説明を挿入

defineComponent オーバーロード関数

1: ダイレクトセットアップ機能

// オーバーロード 1: 直接セットアップ関数
// (ユーザー定義の props インターフェースを使用)
エクスポート関数defineComponent<Props, RawBindings = object>(
  設定: (
    プロパティ: 読み取り専用<Props>、
    ctx: セットアップコンテキスト
  ) => RawBindings | RenderFunction
): DefineComponent<Props, RawBindings>

ここに画像の説明を挿入

2: プロパティのないオブジェクト形式

// オーバーロード 2: プロパティのないオブジェクト形式
// (ユーザー定義の props インターフェースを使用)
// 戻り値の型は Vetur と TSX のサポート用です
エクスポート関数defineComponent<
  プロパティ = {},
  生バインディング = {},
  D = {},
  C は ComputedOptions = {} を拡張します。
  M は MethodOptions = {} を拡張します。
  Mixin は ComponentOptionsMixin = ComponentOptionsMixin を拡張します。
  ComponentOptionsMixin を拡張します = ComponentOptionsMixin、
  E は EmitsOptions = EmitsOptions を拡張します。
  EE は文字列を拡張します = 文字列
>(
  オプション: ComponentOptionsWithoutProps<Props,RawBindings,D,C,M,Mixin,Extends,E,EE>
): DefineComponent<Props、RawBindings、D、C、M、Mixin、Extends、E、EE>

ここに画像の説明を挿入

3: 配列プロパティ宣言によるオブジェクト形式

// オーバーロード 3: 配列プロパティ宣言によるオブジェクト形式
// props は { [PropNames 内のキー]?: any } として推論されます
// 戻り値の型は Vetur と TSX のサポート用です
エクスポート関数defineComponent<
  PropNamesは文字列を拡張します。
  生バインディング、
  D、
  C は ComputedOptions = {} を拡張します。
  M は MethodOptions = {} を拡張します。
  Mixin は ComponentOptionsMixin = ComponentOptionsMixin を拡張します。
  ComponentOptionsMixin を拡張します = ComponentOptionsMixin、
  E は EmitsOptions = Record<文字列、任意> を拡張します。
  EE は文字列を拡張します = 文字列
>(
  オプション: ComponentOptionsWithArrayProps<
    プロップ名、
    RawBindings、...>
): コンポーネントの定義<
  読み取り専用<{ [PropNames のキー]?: any }>,
  RawBindings、...>

ここに画像の説明を挿入

4: オブジェクトプロパティ宣言を含むオブジェクト形式

// オーバーロード 4: オブジェクト プロパティ宣言によるオブジェクト形式
// ./componentProps.ts の `ExtractPropTypes` を参照
エクスポート関数defineComponent<
  // Readonly制約により、TSは{ required: true }の型を扱うことができます。
  // ブール値ではなく定数として。
  PropsOptionsはReadonly<ComponentPropsOptions>を拡張します。
  生バインディング、
  D、
  C は ComputedOptions = {} を拡張します。
  M は MethodOptions = {} を拡張します。
  Mixin は ComponentOptionsMixin = ComponentOptionsMixin を拡張します。
  ComponentOptionsMixin を拡張します = ComponentOptionsMixin、
  E は EmitsOptions = Record<文字列、任意> を拡張します。
  EE は文字列を拡張します = 文字列
>(
  オプション: ComponentOptionsWithObjectProps<
    PropsOptions、RawBindings、D、C、M、Mixin、Extends、E、EE>
): DefineComponent<PropsOptions、RawBindings、D、C、M、Mixin、Extends、E、EE>

ここに画像の説明を挿入

開発実務

ユニット テストでの基本的な使用法とは別に、次の ParentDialog コンポーネントには注意すべき点がいくつかあります。

カスタムコンポーネントとグローバルコンポーネントの書き方

inject、ref などの型制約。

セットアップとそれに対応するh注入問題の書き方

tsx で v-model と scopedSlots を書く方法

親ダイアログ.vue

<script lang="tsx">
'lodash' から { noop, trim } をインポートします。
輸入 {
  挿入、Ref、defineComponent、getCurrentInstance、ref
} '@vue/composition-api' から;
'@/filters' からフィルターをインポートします。
'@/components/CommonDialog' から CommonDialog をインポートします。
'./ChildTable.vue' から ChildTable をインポートします。{ getEmptyModelRow }
 
エクスポートインターフェースIParentDialog{
  表示: ブール値;
  specFn: (component_id: HostComponent['id']) => Promise<{ data: DictSpecs }>;
}
 
エクスポートデフォルトdefineComponent<IParentDialog>({
  // tsx 内のカスタム コンポーネントでは、コンポーネントを登録する必要があります: {
    子テーブル
  },
  小道具: {
    見せる: {
      タイプ: ブール値、
      デフォルト: false
    },
    仕様関数: {
      タイプ: 関数、
      デフォルト: なし
    }
  },
 
  // 注意: セットアップでは矢印関数を使用する必要があります setup: (props, context) => {
 
    // 'h' 関数が tsx に自動的に挿入されない問題を修正 // eslint-disable-next-line no-unused-vars
    const h = getCurrentInstance()!.$createElement;
 
    const { 出力 } = コンテキスト;
    const { specFn, show } = props;
 
    // フィルターの使用 const { withColon } = filters;
 
    // 使用法を挿入 const pageType = inject<CompSpecType>('pageType', 'foo');
    const dictComponents = inject<Ref<DictComp[]>>('dictComponents', ref([]));
    
    // ref 型制約 const dictSpecs = ref<DictSpecs>([]);
    const ロード = ref(false);
 
    const _lookupSpecs = async (component_id: HostComponent['id']) => {
      読み込み値 = true;
      試す {
        const json = specFn(component_id) を待機します。
        dictSpecs.value = json.data;
      ついに
        読み込み値 = false;
      }
    };
 
    const フォームデータ = ref<Spec>({
      コンポーネントID: ''、
      スペックID: ''、
      モデル: [getEmptyModelRow()]
    });
    err1 は ref('');
    err2 は ref('');
    
    定数_doCheck = () => {
      err1.値 = '';
      err2.値 = '';
      
      const {component_id、specs_id、model} = formdata.value;
      コンポーネントIDが
        err1.value = 'コンポーネントを選択してください';
        false を返します。
      }
      (i = 0 とします; i < model.length; i++) {
        const { brand_id, data } = model[i];
        ブランドIDが
          err2.value = 'ブランドを選択してください';
          false を返します。
        }
        もし (
          フォームデータ.値.モデル.some(
            (m, midx) => midx !== i && String(m.brand_id) === String(brand_id)
          )
        ){
          err2.value = 'ブランドが重複しています';
          false を返します。
        }
      }
      true を返します。
    };
 
    定数 onClose = () => {
      出力('update:show', false);
    };
    定数onSubmit = async() => {
      定数ブール値 = _doCheck();
      (!bool) の場合、戻り値:
      定数パラメータ = フォームデータ.値;
      出力('submit', パラメータ);
      閉じる
    };
 
    // 注意: tsx では、element-ui などのグローバルに登録されたコンポーネントでは、依然としてケバブケース形式を使用する必要がありますか?
    戻り値 () => (
      <コモンダイアログ
        クラス="comp"
        title="新着"
        幅="1000px"
        labelCancel="キャンセル"
        ラベル送信="OK"
        vLoading={loading.value}
        表示={表示}
        onClose={onClose}
        onSubmit={onSubmit}
      >
        <el-form labelWidth="140px" class="create-page">
         <el-form-item label={withColon('コンポーネント タイプ')} 必須={true} エラー={err1.value}>
            <el-選択
              クラス="全幅"
              モデル={{
                値: formdata.value.component_id、
                コールバック: (v: 文字列) => {
                  フォームデータ.value.component_id = v;
                  _lookupSpecs(v);
                }
              }}
            >
              {dictComponents.value.map((dictComp: DictComp) => (
                <el-option キー = {dictComp.id} ラベル = {dictComp.component_name} 値 = {dictComp.id} />
              ))}
            </el-select>
          </el-form-item>
          {フォームデータ.値.コンポーネントID?(
              <el-form-item labelWidth="0" label="" 必須={true} エラー={err2.value}>
                <子テーブル
                  リスト={formdata.value.model}
                  onChange={(v: Spec['model']) => {
                    フォームデータ値モデル = v;
                  }}
                  onError={(err: 文字列) => {
                    err3.値 = err;
                  }}
                  スコープスロット={{
                      デフォルト: (スコープ: 任意) => (
                        <p>{ スコープ.foo }</p>
                      )
                  }}
                />
              </el-form-item>
          ) : ヌル}
        </el-form>
      </コモンダイアログ>
    );
  }
});
</スクリプト>
 
<style lang="scss" スコープ>
</スタイル>

まとめ

  • setup() コンポーネントのパラメータ タイプを正しく推測するために、defineComponent() を導入しました。
  • defineComponent は、プロパティなし、配列プロパティなどのフォームに正しく適応できます。
  • defineComponentは、明示的なカスタムpropsインターフェースを受け入れるか、プロパティ検証オブジェクトから自動的に推論することができます。
  • tsxでは、element-uiなどのグローバルに登録されたコンポーネントは、依然としてケバブケース形式を使用する必要があります。
  • tsxでは、v-modelはmodel={を使用する必要があります{ 値、コールバック }} 構文
  • tsxでは、スコープ付きスロットはscopedSlots={を使用する必要があります{ foo: (scope) => () }} 構文
  • defineComponent は関数コンポーネントには適用されません。代わりに RenderContext を使用してください。

Vue3 defineComponent の役割についての記事はこれで終わりです。Vue3 defineComponent の役割についてさらに詳しく知りたい方は、123WORDPRESS.COM の過去記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • vue3 ですべての onSomething をデフォルトで v-on イベントとしてバインドすることについて考える
  • この記事では、Vue 3.0 レスポンシブの使い方を説明します。
  • vue3.0+vant3.0の迅速なプロジェクト構築の実装
  • Vue3を使用してjsで呼び出せるコンポーネントを実装する
  • vue3.2 で追加された defineCustomElement の基本原理の詳細な説明
  • Vue3 Vue イベント処理ガイド

<<:  Docker で MySQL データベースを使用して LAN アクセスを実現する

>>:  MySQL 8.0.18 のインストールと設定のグラフィックチュートリアル

推薦する

docker システムコマンドセットの使用

目次docker システム df docker システム プルーンdocker systemc 情報...

ページキャッシュを無効にするいくつかの方法を共有する

本日、開発中に、顧客からページをキャッシュしないように要求される方法に遭遇しました。調べたところ、ペ...

Mysql を 5.7 にアップグレードした後のグループ クエリの問題を解決する

問題を見つける最近MySQLをMySQL 5.7にアップグレードした後、次のようなクエリでグループ化...

Linux での MongoDB のインストールと設定のチュートリアル

MongoDBインストールYumを使用してインストールすることを選択する1. repoファイルを作成...

Jenkins を通じて None のイメージを定期的にクリーンアップする方法

序文継続的なコード配信のプロセスで、Jenkins を利用して Docker イメージを作成すると、...

すべてのウェブ開発者が知っておくべき61のこと

通常、全員のスピーチを最初から最後まで読む必要があります。ただし、Stack Overflow には...

JavaScript WeakMap の使い方の詳しい説明

WeakMap オブジェクトは、キーが弱参照であるキー/値のペアのコレクションです。キーはオブジェク...

Mysql関数呼び出しの最適化の詳細な説明

目次関数呼び出しの最適化関数呼び出しの最適化MySQL 関数は、内部的に決定論的または非決定論的とし...

外部キー制約を持つテーブルデータを削除する MySQL メソッドの紹介

MySQLでテーブルやデータを削除する場合、 [エラー] 1451 - 親行を削除または更新できませ...

Windows/Mac で Docker を使用して MySQL (utf8 を含む) をインストールする

目次1. MacへのDockerのインストール2. Win 10 システムでの Docker のイン...

Nginx 構成検出サービスのステータスを実装する方法

1. チェックステータスモジュールがインストールされているかどうかを確認します。 [root@loc...

HTML フォーム_PowerNode Java アカデミー

1. フォーム1. フォームの役割HTML フォームは、さまざまな種類のユーザー入力を受け取り、ユー...

Javascript ファイルと Blob の詳細な説明

目次ファイル()文法パラメータ例ブロブ()文法パラメータ財産方法例要約するファイル() File()...

MySQL でデータを削除してもテーブル ファイルのサイズが変更されないのはなぜですか?

長期間稼働しているデータベースの場合、テーブルがストレージ領域を占有しすぎるという問題がよく発生しま...

MySQL 5.7.10 winx64 のインストールと設定方法のグラフィック チュートリアル (win10)

MySQL は比較的使いやすいリレーショナル データベースです。今日は、win10 システムを再イ...