vue3简单封装input组件和统一表单数据详解
作者:颜酱 发布时间:2024-04-26 17:41:18
标签:vue3,封装,input
前言
vue3 支持用 jsx 实现组件,摆脱了 vue 文件式的组件,不再需要额外的指令,写法非常接近 React,减少记忆负担。
本文简单的练习,用 vue3 组件封装 input 组件和统一表单数据。
准备工作
用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>
{/* 使用组件,传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>
);
},
};
来源:https://juejin.cn/post/7100863271062175751


猜你喜欢
- SocketServer简化了网络服务器的编写。它有4个类:TCPServer,UDPServer,UnixStreamServer,Uni
- python数组添加整行或整列代码如下,见注释:import numpy as npm_list=[[1,2,3],[3,4,5]]m_ar
- selenuim模块定位方法1,我们想要操作html页面上的元素,首先必须要定位到这个元素上。每个元素都有他各自的属性,比如id,name,
- 在使用 SQL Server 的过程中,用户遇到的最多的问题莫过于连接失败了。一般而言,有以下两种连接 SQL Server 的方式,一是利
- 前言在新的一年里祝大家前端都用ES6,php都用PHP7,Java都是JAVA9,python都是3。好了,下面进入本文的主要的内容,大家可
- 临近春节,脚本之家小编带领大家用Python抢火车票!首先我们需要splinter安装:pip install splinter -i ht
- 无法远程登入MySQL数据库的几种解决办法方法一:尝试用MySQL Adminstrator GUI Tool登入MySQL Server,
- 很早就在这里看到过解决方案,与嗷嗷讨论后发现这个方案还是很可靠的。当然,唯一的缺点就是每一个属性都要去Hack,但我在很多实践中,只用‘修正
- 如下所示:def save(data, path): f = xlwt.Workbook() # 创建工作簿 she
- 如下所示:colum = ['性别','年龄','M','样本类型'] +
- 1、灵活运用样式熟悉网页设计的网友就知道,调用Style的方法很多,我们可以单击鼠标右键选择Custo
- 下标所谓下标就是编号,就好比超市中存储柜的编号,通过这个编号就能找到相应的存储空间。Python中字符串,列表,元祖均支持下标索引。例如:#
- itchat模块官方参考文档:https://itchat.readthedocs.io/zh/latest/安装pip install i
- 在一个项目中,制作呃echart图表的时候,遇到一个需求,需要从后端接口获取数据----售票员的姓名和业绩所以需要在订单表中,获取不同售票员
- 读文件打开文件(文件需要存在)#打开文件f = open("data.txt","r")
- 首先通过一个例子来看一下本文中可能用到的对象和相关概念。 #coding: UTF-8 import sys # 模块,sys指向这个模块对
- server:#coding=utf-8from BaseHTTPServer import BaseHTTPRequestHandleri
- 前言:Python 是一种脚本语言,相比 C/C++ 这样的编译语言,在效率和性能方面存在一些不足。但是,有很多时候,Python 的效率并
- 本文实例为大家分享了Vue自定义日历插件的具体代码,供大家参考,具体内容如下由于网上的插件没有符合项目的需求决定自己实现图示如下:默认选择今
- 1.安装pip我的个人桌面系统用的linuxmint,系统默认没有安装pip,考虑到后面安装requests模块使用pip,所以我这里第一步