const formRef = useRef();
setVisible(false), // 取消按钮回调
open: visible, // 对话框是否可见
afterClose: async () => {
const res = await getTreeNodes();
if (res.status === 'success') {
if (JSON.stringify(res?.data) != '{}') { // 判断数据源是否为空对象
setVisible(false);
} else {
setVisible(true);
message.error('请先添加数据源');
}
}
},// 关闭后的回调
maskClosable: false, // 点击蒙层是否允许关闭
}}
onFinish={async (values) => {
const res = await getDataSource(dataSourceId);
if (res.code === 200) {
setVisible(false);
// 更新树
getTreeData();
message.success('切换成功');
}
}}
// 开启grid布局
layout="horizontal"
grid={true}
>
{
// 通过formRef.current?.setFieldsValue来清除某个表单项的值
formRef.current?.setFieldsValue({
origin: undefined,
});
setDatatype3([]);
GainDataSource(value);
},
}}
/>
{
setDataSourceId(value);
},
}}
/>
// 这里是封装的Tags.tsx组件
import {forwardRef, useImperativeHandle, useState} from 'react';
import {Button, Input, message} from "antd";
import { MinusCircleOutlined } from '@ant-design/icons';
import style from './index.less';
import {updateTableTag} from "@/pages/dataDev/metaMgr/service";
const Tags = forwardRef((props, ref) => {
const [tags, setTags] = useState([]);
const [parentTags, setParentTags] = useState();
const [tagName, setTagName] = useState(''); // 输入框的值
const [show, setShow] = useState(true);
const [show2, setShow2] = useState(true);
const [show3, setShow3] = useState(false);
const [show4, setShow4] = useState(false);
useImperativeHandle(ref, () => ({
showModal: (record: any) => {
setParentTags(record);
if (record?.tags != null && record?.tags != '') {
setTags(record?.tags.split('|'));
} else {
setTags([]);
}
}
}));
/*请求方法*/
const Request = async (type:string,id:any,tags:any) => {
const res = await updateTableTag({id:id, tags:tags});
if (res.code == 200) {
if (type == 'add') {
message.success('保存成功');
} else {
message.success('删除成功');
}
props?.getList(); // 触发父组件的getList方法
} else {
if (type == 'add') {
message.error('保存失败');
} else {
message.error('删除失败');
}
}
}
/*新增*/
const addTag = () => {
setShow2(false);
setShow(false);
setShow4(true);
/*const newTags: any = {
id: new Date().getTime() + 1 + '',
name: tagName
};*/
const newTags: any = tagName;
setTags([...tags, newTags]);
setTagName('');
}
/*保存*/
const saveTag = async () => {
setShow(true);
setShow2(true);
setShow3(false);
setShow4(false);
const newTags = tags.filter((item:any) => item !== '');
setTags(newTags);
Request('add',parentTags?.id,newTags.join('|'));
}
/*删除*/
const deleteTag = (value:any) => {
const newTags = tags.filter((item:any) => item !== value);
setTags(newTags);
Request('delete',parentTags?.id,newTags.join('|'));
}
/*赋值*/
const changeTag = (e:any, value:any) => {
const newTags = tags.map((item:any) => {
if (item == value) {
item = e.target.value;
}
return item;
})
setTags(newTags);
}
/*取消*/
const onCancel = () => {
setShow(true);
setShow2(true);
setShow3(false);
setShow4(false);
const newTags = tags.filter((item:any) => item !== '');
setTags(newTags);
setTags(parentTags?.tags.split('|')); // 点击取消时, 将父组件的tags值还原
}
return (
标签:
{
tags?.map((item:any,index:any) => {
return (
changeTag(e,item) } />
{show2 == true ?
{deleteTag(item);}} />
: null
}
)
})
}
);
});
export default Tags;
核心代码:
// 因为react跟vue不一样,vue的数据可以双向绑定,但是react不可行,所以这里的input回显之后,再输入的话需要我们再处理一下
/*Input赋值*/
const changeTag = (e:any, value:any) => { // e.target.value是输入框的值
const newTags = tags.map((item:any) => { // item是数组中的每一项
if (item == value) { // 如果数组中的某一项等于输入框的值, 就将该项的值改为输入框的值
item = e.target.value; // 将输入框的值赋值给数组中的某一项
}
return item; // 返回数组中的每一项
})
setTags(newTags); // 将新的数组赋值给tags
}
// 父组件中使用 Tags.tsx组件
import Tags from './Tags'; // 引入 Tags.tsx
const cRef = useRef(null); // 用于获取子组件实例
/*子组件触发*/
const getTags = () => {
getTableInfo(tableId);
}
// 在需要的地方进行调用
setTimeout(() => { // 这里的定时器是为了解决调用Tags组件时,Tags组件还没有创建,而引发的问题
cRef.current?.showModal(res?.data); // 通过ref调用showModal方法,给标签组件传值
}, 50);
// getList是父组件传递给子组件的方法 getTags是子组件传递给父组件的方法