vue3怎么封装input组件和统一表单数据
短信预约 -IT技能 免费直播动态提醒
准备工作
用vue create example
创建项目,参数大概如下:
用原生 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>
{}
<Input
value={username.value}
onChange={(value: string) => (username.value = value)} // 直接在这同步数据
/>
<div>input的值:{username.value}</div>
</div>
);
},
};
封装表单数据
表单数据,经常需要赋值、获取值,这边可以用类统一处理,在后面的组件赋值属性的时候极其方便。
useForm的精华,在于proxy,访问属性的时候,返回field数据,这在表单组件里可以简洁使用。
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>
{}
{}
<Input {...form.username} />
<Input {...form.age} />
<button
onClick={() => {
console.log(form.getValues());
}}
>
提交
</button>
</div>
);
},
};
以上就是vue3怎么封装input组件和统一表单数据的详细内容,更多请关注编程网其它相关文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341