本篇内容主要讲解“vue3如何封装input组件和统一表单数据”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue3如何封装input组件和统一表单数据”吧!
用vue create example
创建项目,参数大概如下:
原生的 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 的好处,直接传值,减少逻辑,不再需要额外的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组件和统一表单数据”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。