react + ts 的 treeSelect 组件实现(4) | 青训营笔记

245 阅读3分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 16 天,在上一节中,我们实现了树形结构的显示,但是我们还没有实现选择结果的输入框。对于这个功能,我们将要将其封装成为一个组件,以提高代码的可读性和重用性。

选择结果输入框

对于选择结果的输入框,我们将使用一个新的组件来实现。这个组件的功能是将选择的结果以输入框的形式显示出来。

选择结果输入框的显示

考虑到这个组件的功能,我们将使用一个变量来控制是否显示这个组件,当点击输入框时,我们将变量设置为true,当点击树形结构时,我们将变量设置为false。同样是使用useState来实现。

const [displayInput, setDisplayInput] = useState(false);

在这个组件中,我们使用了一个div来包裹输入框,这个div的样式是inputClass。当displayInput为true时,我们将inputClass的样式设置为inputClass-active,这样就可以实现点击输入框时,输入框的显示。

const inputClass = classNames('inputClass', {
  'inputClass-active': displayInput === true,
});

如果我们要将树状结构的数据显示在输入框中,我们需要将树状结构的数据传入到输入框组件中。所以在inputProps中,我们需要添加一个data属性。并且为了方便我们的使用,我们将data的类型定义为一个数组,数组中的每一项都是一个对象,对象中包含valuelabel两个属性。

value作为唯一标识,label作为显示的内容。

为了实现双向的数据传递,我们需要在TreeSelectInput组件中添加一个deleteItem属性,当点击输入框中的删除按钮时,我们将调用这个属性,并将value值传入。

export interface data<T> {
  value: T;
  label: string;
}

interface inputProps<T> {
  data: Array<data<T>>; //The data of the selected item
  itemColor?: string; //The color of the selected item
  width?: string; //The width of the input box
  height?: string; //The height of the input box
  defaultShow?: boolean; //Whether to display the input box
  placeholder?: string; //The placeholder of the input box
  deleteItem?: (value: T) => void; //Delete the selected item
  showTree?: (showTree: boolean) => void; //Whether to display the drop-down box
  inputRef?: React.RefObject<HTMLDivElement>; //The reference of the input box
}

根据输入框的位置显示树状结构

我们需要获取输入框的位置,然后计算树形选择栏的位置,这样就可以在不同的位置显示树形选择栏了。

首先在inputProps中添加一个inputRef属性,这个属性的类型是React.RefObject<HTMLDivElement>,这个属性的作用是获取输入框的位置。然后在TreeSelectInput组件中,我们将这个属性传入到输入框的ref中。

const getLeftPos = () => {
  if (inputRef.current && dropDownRef.current) {
    const { width } = inputRef.current.getBoundingClientRect();
    if (dropDownPosition === 'leftBottom') {
      console.log('left');
      return `${-width}px`; 
    }
    if (dropDownPosition === 'rightBottom') {
      return `${width}px`;
    }
    console.log(dropDownPosition);
    return '0px';
  }
};
const topPos = getTopPos();
const leftPos = getLeftPos();

在这个函数中,我们首先判断inputRefdropDownRef是否存在,如果存在,我们就获取输入框的宽度,然后根据dropDownPosition的值来计算树形选择栏的位置。

主要的逻辑已经实现的差不多了,剩下的是对于样式和具体想要的操作方式的实现。