react+antd 制作Checkbox+Tag联动标签

实现效果:

 父组件:

import GameTabAll from './GameTabAll';

 const onSelect = (arr) => {
    console.log('onSelect=' + arr);
    onSelectTags(arr);
  };




//taglist:所有标签列表
//tagid:默认选中标签
//onSelect:乘接子组件修改后返回值
<GameTabAll options={taglist} tagid={JSON.parse(tagid)} onSelect={onSelect} /> 

子组件

1,创建一个div,包含两层div,一层为展示选中tag标签栏,一层为Checkbox展现标签列表栏

import { Tag, Checkbox } from 'antd';
import { RightOutlined } from '@ant-design/icons';
import React, { useState, useEffect } from 'react';

const GameTabAll = (props) => {
//获取父组件传递值
  const { options, tagid, onSelect } = props;
//tag栏右侧 > 图标,控制Checkbox所有标签李彪是否展开
 const [show, setShow] = useState(false);

  return (
    <div>
      //tag栏
      <div style={{ width: '300px', height: '30px' }}>
        <Tag closable onClose>
             tag标签
         </Tag>
        <RightOutlined
          style={{
            float: 'right',
            color: '#ccc',
            transform: show ? 'rotate(0deg)' : 'rotate(90deg)',
            lineHeight: '35px',
          }}
          onClick={() => {
            if (show) {
              setShow(false);
            } else {
              setShow(true);
            }
          }}
        />
      </div>

      //所有标签展示栏
      <div
        className="checkboxTag"
        style={{
          width: '400px',
          maxHeight: '300px',
          marginLeft: '-50px',
          padding: '10px',
          overflowY: 'scroll',
          lineHeight: '35px',
          textAlign: 'justify',
          display: show ? 'flex' : 'none',
        }}
      >
        <Checkbox.Group options={options}  />
      </div>
    </div>
  );
};

export default GameTabAll;

2、制作所有标签展示栏,默认已选中标签高亮提示,并将修改后的值转变为tag标签需要格式;

import { Tag, Checkbox } from 'antd';
import { RightOutlined } from '@ant-design/icons';
import React, { useState, useEffect } from 'react';

const GameTabAll = (props) => {
//获取父组件传递值
  const { options, tagid, onSelect } = props;
//tag栏右侧 > 图标,控制Checkbox所有标签李彪是否展开
 const [show, setShow] = useState(false);
//默认选中标签,展示格式[1,2,3]
 const [arrTagid, setArrTagid] = useState(tagid); 
//修改格式后选中标签,[{label:1,,value:1}]
const [getTagid, setTagid] = useState([]); 

/Checkbox格式[1,2,3]转tag格式[{label:1,,value:1}]
  const gettags = (list) => {
    if (!list) return;
    let taglist = [];
    Object.keys(options).forEach((key) => {
      let value = options[key].value;
      if (list.indexOf(value) > -1) {
        taglist.push(options[key]);
      }
    });
    setTagid(taglist);
  };


 //Checkbox选中标签,并同步到tag
  const onChangeCheckbox = (checkedValues) => {
    onSelect(checkedValues);
    setArrTagid(() => {     //useState以函数形式赋值,解决改变后值更新不及时问题
      let newData = checkedValues;
      gettags(newData);  //将选中标签同步成tag标签需要格式
      return newData;
    });
  };

  return (
    <div>
      //tag栏
        .........

      //所有标签展示栏
      <div
        className="checkboxTag"
        style={{
          width: '400px',
          maxHeight: '300px',
          marginLeft: '-50px',
          padding: '10px',
          overflowY: 'scroll',
          lineHeight: '35px',
          textAlign: 'justify',
          display: show ? 'flex' : 'none',
        }}
      >
        <Checkbox.Group options={options}  value={arrTagid} onChange={onChangeCheckbox}/>
      </div>
    </div>
  );
};

export default GameTabAll;

3、tag栏展示默认选中标签(最多展示5个);

     Checkbox栏部分有修改,tag栏同步修改

import { Tag, Checkbox } from 'antd';
import { RightOutlined } from '@ant-design/icons';
import React, { useState, useEffect } from 'react';

const GameTabAll = (props) => {
//获取父组件传递值
  const { options, tagid, onSelect } = props;
//tag栏右侧 > 图标,控制Checkbox所有元素列表是否展开
 const [show, setShow] = useState(false);


 //修改格式后选中标签,[{label:1,,value:1}]
  const [getTagid, setTagid] = useState([]); 

  //页面刚打开时将初始默认选中标签改变格式,并赋值;
  useEffect(() => {
    gettags(tagid);
  }, []);


  return (
    <div>
      //tag栏
      <div style={{ width: '300px', height: '30px' }}>
       //遍历选中元素,并以tag标签展示
       {getTagid.map((m, i) => {
          if (i < 5) {
            return (
              <Tag closable key={m.value}>
                {m.label}
              </Tag>
            );
          }
        })}
        <RightOutlined
          style={{
            float: 'right',
            color: '#ccc',
            transform: show ? 'rotate(0deg)' : 'rotate(90deg)',
            lineHeight: '35px',
          }}
          onClick={() => {
            if (show) {
              setShow(false);
            } else {
              setShow(true);
            }
          }}
        />
      </div>

      //所有标签展示栏
       ...........
    </div>
  );
};

export default GameTabAll;

4、tag标签错号删除,同时联动到下方元素选中列表

import { Tag, Checkbox } from 'antd';
import { RightOutlined } from '@ant-design/icons';
import React, { useState, useEffect } from 'react';

const GameTabAll = (props) => {
//获取父组件传递值
  const { options, tagid, onSelect } = props;
//tag栏右侧 > 图标,控制Checkbox所有元素列表是否展开
 const [show, setShow] = useState(false);
//默认选中标签,[1,2,3],Checkbox组件需要格式
 const [arrTagid, setArrTagid] = useState(tagid); 

//数组删除指定元素
  const delOne = (str, arr) => {
    var index = arr.indexOf(str);
    arr.splice(index, 1);
    return arr;
  };

  //tag删除标签,并同步到Checkbox
  const tagsDel = (tag, value) => {
    let newArr = delOne(value, arrTagid);
    setArrTagid(() => {
      let data = newArr.slice();  //通过slice() 返回一个新的对象去赋值
      onSelect(arrTagid); 
      return data;
    });
  };

  return (
    <div>
      //tag栏
      <div style={{ width: '300px', height: '30px' }}>
       //遍历选中元素,并以tag标签展示
       {getTagid.map((m, i) => {
          if (i < 5) {
            return (
              <Tag closable key={m.value} onClose={() => tagsDel(m, m.value)}>
                {m.label}
              </Tag>
            );
          }
        })}
        <RightOutlined
          style={{
            float: 'right',
            color: '#ccc',
            transform: show ? 'rotate(0deg)' : 'rotate(90deg)',
            lineHeight: '35px',
          }}
          onClick={() => {
            if (show) {
              setShow(false);
            } else {
              setShow(true);
            }
          }}
        />
      </div>

      //所有标签展示栏
       ...........
    </div>
  );
};

export default GameTabAll;

最后,附上完整代码(父组件看第一个代码块)

子组件

import { Tag, Checkbox } from 'antd';
import { RightOutlined } from '@ant-design/icons';
import React, { useState, useEffect } from 'react';

const GameTabAll = (props) => {
  const { options, tagid, onSelect } = props;
  const [show, setShow] = useState(false);
  const [arrTagid, setArrTagid] = useState(tagid); //默认选中标签,[1,2,3]
  const [getTagid, setTagid] = useState([]); //修改格式后选中标签,[{label:1,,value:1}]

  useEffect(() => {
    gettags(tagid);
  }, []);

  //Checkbox格式[1,2,3]转tag格式[{label:1,,value:1}]
  const gettags = (list) => {
    if (!list) return;
    let taglist = [];
    Object.keys(options).forEach((key) => {
      let value = options[key].value;
      if (list.indexOf(value) > -1) {
        taglist.push(options[key]);
      }
    });
    setTagid(taglist);
  };

  //数组删除指定元素
  const delOne = (str, arr) => {
    var index = arr.indexOf(str);
    arr.splice(index, 1);
    return arr;
  };

  //tag删除标签,并同步到Checkbox
  const tagsDel = (tag, value) => {
    let newArr = delOne(value, arrTagid);
    setArrTagid(() => {
      let data = newArr.slice(); //通过slice() 返回一个新的对象去赋值
      onSelect(arrTagid);
      return data;
    });
  };

  //Checkbox选中标签,并同步到tag
  const onChangeCheckbox = (checkedValues) => {
    onSelect(checkedValues);
    setArrTagid(() => {
      let newData = checkedValues;
      gettags(newData);
      return newData;
    });
  };

  return (
    <div>
      <div style={{ width: '300px', height: '30px' }}>
        {getTagid.map((m, i) => {
          if (i < 5) {
            return (
              <Tag closable onClose={() => tagsDel(m, m.value)} key={m.value}>
                {m.label}
              </Tag>
            );
          }
        })}
        <RightOutlined
          style={{
            float: 'right',
            color: '#ccc',
            transform: show ? 'rotate(0deg)' : 'rotate(90deg)',
            lineHeight: '35px',
          }}
          onClick={() => {
            if (show) {
              setShow(false);
            } else {
              setShow(true);
            }
          }}
        />
      </div>
      <div
        className="checkboxTag"
        style={{
          width: '400px',
          maxHeight: '300px',
          marginLeft: '-50px',
          padding: '10px',
          overflowY: 'scroll',
          lineHeight: '35px',
          textAlign: 'justify',
          display: show ? 'flex' : 'none',
        }}
      >
        <Checkbox.Group options={options} value={arrTagid} onChange={onChangeCheckbox} />
      </div>
    </div>
  );
};

export default GameTabAll;


版权声明:本文为hjy1006154810原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。