ホームページ >ウェブフロントエンド >Vue.js >vue3 で入力コンポーネントと統合フォームデータをカプセル化する方法

vue3 で入力コンポーネントと統合フォームデータをカプセル化する方法

WBOY
WBOY転載
2023-05-12 15:58:261962ブラウズ

準備

vue create exampleを使用してプロジェクトを作成します。パラメータはおおよそ次のとおりです:

vue3 で入力コンポーネントと統合フォームデータをカプセル化する方法

ネイティブ入力を使用します。

ネイティブ入力は主に値と変更であり、変更時にはデータを同期する必要があります。

App.tsx は次のとおりです。

import { ref } from 'vue';

export default {
  setup() {
    // username就是数据
    const username = ref('张三');
    // 输入框变化的时候,同步数据
    const onInput = ;
    return () => (
      <div>
        <input type="text"
            value={username.value}
            onInput={(e: any) => { username.value = e.target.value; }} />
        <div>input的值:{username.value}</div>
      </div>
    );
  },
};

入力のカプセル化

入力をカプセル化する利点は、値を直接渡すことができ、ロジックを削減でき、追加の # 必要がないことです。 ##e.target# が必要です。##、後続のカプセル化の準備をします。 <pre class="brush:js;">// Input.tsx import { defineComponent, ref } from &amp;#39;vue&amp;#39;; // defineComponent定义组件,有props const Input = defineComponent({ props: { value: { required: true, type: String, }, onChange: { required: true, type: Function, }, }, // 渲染用到props,需要在这里传参 setup(props) { // 值变化 的时候 调用传过来的onChange从而同步父组件的 数据 const onInput = (e: any) =&gt; { props.onChange &amp;&amp; props.onChange(e.target.value); }; return () =&gt; &lt;input type=&quot;text&quot; value={props.value} onInput={onInput} /&gt;; }, });</pre>入力コンポーネントを使用する

import { ref } from &#39;vue&#39;;
import Input from &#39;./components/Input&#39;;
export default {
  setup() {
    // 数据
    const username: any = ref(&#39;张三&#39;);
    return () => (
      <div>
        {/* 使用组件,传value和onChange */}
        <Input
          value={username.value}
          onChange={(value: string) => (username.value = value)} // 直接在这同步数据
        />
        <div>input的值:{username.value}</div>
      </div>
    );
  },
};

フォーム データをカプセル化する

フォーム データでは、多くの場合、値の割り当てと取得が必要になります。ここでは、クラスを使用して値を均一に処理し、属性を割り当てることができます。後続のコンポーネントは非常に便利です。

useForm の本質はプロキシであり、属性にアクセスするときにフィールド データを返します。これはフォーム コンポーネントで簡単に使用できます。

/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ref, Ref } from "vue";
export class FormData<T> {
  private data: Ref<any>;
  constructor(data: T) {
    this.data = ref(data || null);
  }

  // 设置某个字段的值
  setValue(name: string, val: any): void {
    const next = { ...this.data.value, [name]: val };
    this.data.value = next;
  }

  // 获取某个字段的值
  getValue(name: string): any {
    return this.data.value[name];
  }

  // 获取整个值
  getValues() {
    return this.data.value;
  }

  // 设置整个值
  setValues(values: T) {
    this.data.value = values;
  }

  // 获取field,字段和字段的修改事件
  getField(name: string) {
    return {
      value: this.data.value[name],
      onChange: (v: any) => {
        this.setValue(name, v);
      },
    };
  }
}

type FormDataProxy<T> = {
  [P in keyof T]: T[P];
};

export function useForm<T extends Record<string, any>>(data: T) {
  const form = new FormData(data);
  const ver = ref(0);

  const proxy = new Proxy(form, {
    // 写proxy的目的是:form.username的时候,直接返回 form.getField(username)
    get(target, name) {
      switch (name) {
        case "getValues":
          return form.getValues.bind(form);
        case "setValues":
          return form.setValues.bind(form);
        default:
          return form.getField(name as string);
      }
    },
    // 写form.username = xx  直接返回 form.setValue(&#39;username&#39;,xx)
    set(target, name, value) {
      switch (name) {
        case "getValues":
        case "setValues":
          break;
        default:
          form.setValue(name as string, value);
      }
      return true;
    },
  }) as any as FormDataProxy<T> & {
    setValues: (val: T) => void;
    getValues: () => Ref<T>;
  };
  return { form: proxy, ver };
}

フォーム データの使用

入力コンポーネントはフォームとうまく連携します。

rreeee

以上がvue3 で入力コンポーネントと統合フォームデータをカプセル化する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。