您的位置:首页 > 技术中心 > 前端框架 >

vue3怎么封装input组件和统一表单数据

时间:2023-05-13 01:04

准备工作

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.tsximport { defineComponent, ref } from 'vue';// defineComponent定义组件,有propsconst 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组件和统一表单数据的详细内容,更多请关注Gxl网其它相关文章!

热门排行

今日推荐

热门手游