欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

vue3如何封裝input組件和統(tǒng)一表單數(shù)據(jù)

本篇內(nèi)容主要講解“vue3如何封裝input組件和統(tǒng)一表單數(shù)據(jù)”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“vue3如何封裝input組件和統(tǒng)一表單數(shù)據(jù)”吧!

企業(yè)建站必須是能夠以充分展現(xiàn)企業(yè)形象為主要目的,是企業(yè)文化與產(chǎn)品對外擴展宣傳的重要窗口,一個合格的網(wǎng)站不僅僅能為公司帶來巨大的互聯(lián)網(wǎng)上的收集和信息發(fā)布平臺,創(chuàng)新互聯(lián)面向各種領(lǐng)域:成都雨棚定制成都網(wǎng)站設(shè)計全網(wǎng)營銷推廣解決方案、網(wǎng)站設(shè)計等建站排名服務(wù)。


準(zhǔn)備工作

vue create example創(chuàng)建項目,參數(shù)大概如下:

vue3如何封裝input組件和統(tǒng)一表單數(shù)據(jù)

用原生 input

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

App.tsx如下:

import { ref } from 'vue';

export default {
  setup() {
    // username就是數(shù)據(jù)
    const username = ref('張三');
    // 輸入框變化的時候,同步數(shù)據(jù)
    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,為后面的繼續(xù)封裝做準(zhǔn)備。

// 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) {
    // 值變化 的時候  調(diào)用傳過來的onChange從而同步父組件的 數(shù)據(jù)
    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() {
    // 數(shù)據(jù)
    const username: any = ref('張三');
    return () => (
      <div>
        {/* 使用組件,傳value和onChange */}
        <Input
          value={username.value}
          onChange={(value: string) => (username.value = value)} // 直接在這同步數(shù)據(jù)
        />
        <div>input的值:{username.value}</div>
      </div>
    );
  },
};

封裝表單數(shù)據(jù)

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

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

/* 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);
  }

  // 設(shè)置某個字段的值
  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;
  }

  // 設(shè)置整個值
  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 };
}

使用表單數(shù)據(jù)

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

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

// 使用組件
export default {
  setup() {
    // 數(shù)據(jù)
    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組件和統(tǒng)一表單數(shù)據(jù)

到此,相信大家對“vue3如何封裝input組件和統(tǒng)一表單數(shù)據(jù)”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

當(dāng)前名稱:vue3如何封裝input組件和統(tǒng)一表單數(shù)據(jù)
文章源于:http://www.aaarwkj.com/article10/igcedo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、小程序開發(fā)網(wǎng)站排名營銷型網(wǎng)站建設(shè)、網(wǎng)站收錄、移動網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
欧美日韩免费r在线视频| 视频二区国产欧美日韩| 日本亚洲欧洲一区二区| 日韩不卡的一区免费视频| 欧美日韩一区二区三区色拉拉| 青春草草视频在线观看| 国产男女视频免费观看| 中文字幕人妻在线播放| 日韩欧美国产精品一区二区| 视频一区二区三区不卡| 后入视频国产在线观看| 少妇高潮惨叫久久麻豆传| 高级会所口爆视频在线播放视频 | 一区二区三区人妻日韩| 精品亚洲国产成人av| 天堂在线精品亚洲综合网| 四虎在线观看最新免费| 成年爽片在线观看播放欧美| 国产三级尤物在线观看| 超碰在线免费视频97| 97公开视频在线观看| 欧美精品一区二区三区黄片| 日本高清有码视频在线观看| 18岁未成年禁止观看视频| 亚洲精品一区二区午夜| 亚洲六月丁香六月婷婷| 日本精品亚洲一区二区三区| 日韩精品在线观看电影| 亚洲精品福利一二三区| 黄色大全欧美在线观看| 日日骚国产欧美一区二区| 国产经典三级在线看| 久久麻豆精亚洲av品国产一区| 亚洲伦理在线一区二区| 国产精品伦一区二区三级| 国产大学生露脸在线视频| 亚洲中文字幕乱码丝袜在线精品| 成人深夜福利视频在线| 亚洲色图视频免费观看| 欧美大片免费在线播放| 欧美护士激情第一欧美精品|