91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue3怎么封裝input組件和統一表單數據

發布時間:2022-05-25 17:28:09 來源:億速云 閱讀:503 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“vue3怎么封裝input組件和統一表單數據”,內容詳細,步驟清晰,細節處理妥當,希望這篇“vue3怎么封裝input組件和統一表單數據”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

準備工作

vue create example創建項目,參數大概如下:

vue3怎么封裝input組件和統一表單數據

用原生 input

原生的 input,主要是 value 和 change,數據在 change 的時候需要同步。

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>
    );
  },
};

封裝 Input

封裝 input 的好處,直接傳值,減少邏輯,不再需要額外的e.target,為后面的繼續封裝做準備。

// Input.tsx
import { defineComponent, ref } from 'vue';

// defineComponent定義組件,有props
const Input = defineComponent({
  props: {
    value: {
      required: true,
      type: String,
    },
    onChange: {
      required: true,
      type: Function,
    },
  },
  // 渲染用到props,需要在這里傳參
  setup(props) {
    // 值變化 的時候  調用傳過來的onChange從而同步父組件的 數據
    const onInput = (e: any) => {
      props.onChange && props.onChange(e.target.value);
    };
    return () => <input type="text" value={props.value} onInput={onInput} />;
  },
});

使用Input組件

import { ref } from 'vue';
import Input from './components/Input';
export default {
  setup() {
    // 數據
    const username: any = ref('張三');
    return () => (
      <div>
        {/* 使用組件,傳value和onChange */}
        <Input
          value={username.value}
          onChange={(value: string) => (username.value = value)} // 直接在這同步數據
        />
        <div>input的值:{username.value}</div>
      </div>
    );
  },
};

封裝表單數據

表單數據,經常需要賦值、獲取值,這邊可以用類統一處理,在后面的組件賦值屬性的時候極其方便。

useForm的精華,在于proxy,訪問屬性的時候,返回field數據,這在表單組件里可以簡潔使用。

/* 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('username',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 };
}

使用表單數據

Input組件配合表單,使用效果奇佳。

import Input from './components/Input';
import { useForm } from './hooks/useForm';

// 使用組件
export default {
  setup() {
    // 數據
    const { form, ver } = useForm({ username: '張三', age: 33 });
    console.log(123, form, ver);
    return () => (
      <div>
        {/* 這里的form.username,實際是proxy返回的{value:xxx,onChange:fn} */}
        {/*  多表單組件的時候 這樣就非常方便了 */}
        <Input {...form.username} />
        <Input {...form.age} />

        <button
          onClick={() => {
            console.log(form.getValues());
          }}
        >
          提交
        </button>
      </div>
    );
  },
};

vue3怎么封裝input組件和統一表單數據

讀到這里,這篇“vue3怎么封裝input組件和統一表單數據”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

大悟县| 布尔津县| 行唐县| 菏泽市| 五原县| 光山县| 新干县| 绥化市| 苏尼特右旗| 册亨县| 内乡县| 班玛县| 瑞金市| 芦山县| SHOW| 明光市| 蒲城县| 定襄县| 苍梧县| 彰化市| 南丰县| 永泰县| 沈丘县| 社旗县| 远安县| 山东省| 东至县| 河南省| 瓦房店市| 任丘市| 抚宁县| 承德县| 黔西县| 濉溪县| 赤城县| 河池市| 柘荣县| 韩城市| 项城市| 仁布县| 潞城市|