当前位置: 首页 > news >正文

海南找人做网站广州优化seo

海南找人做网站,广州优化seo,深圳做网站推广排名,网站建设公司新闻1、效果如下图 实现tag标签单选或多选功能 2、环境准备 1、react18 2、antd 4 3、功能实现 原理: 封装一个受控组件,接受父组件的参数,数据发现变化后,回传给父组件 1、首先,引入CheckableTag组件和useEffect, useMemo, use…

1、效果如下图

实现tag标签单选或多选功能

2、环境准备

1、react18

2、antd 4+

3、功能实现

原理: 封装一个受控组件,接受父组件的参数,数据发现变化后,回传给父组件

1、首先,引入CheckableTag组件和useEffect, useMemo, useState钩子:

import { Tag } from 'antd';
import { useEffect, useMemo, useState } from 'react';const { CheckableTag } = Tag;

2、然后,定义一个状态变量来存储选中的tag:

const [tagsData, setTagsData] = useState<enumItem[]>();

3、组件可接收的props子属性 如下:

  •  selectedTagsValues: 父组件传入的标签配置枚举列表
  •  value: 已选中的值
  •  startIndex:距离左右节点位置,用于是否将左右节点滑动到可视局域
  •  onChange: 选中的值发生变化时回调

4、创建一个函数来处理tag的选中和取消选中事件:

  // handelChange,找到所点击项的索引,并把那一项的checked设置为trueconst handleChange = (tag: any, checked: boolean, mode?: string) => {if (mode !== 'multiple') {onChange?.(checked ? tag : null);return;}const changeData = (value || []).filter((item: any) => item.value !== tag.value,);if (checked) {changeData.push(tag);}onChange?.(changeData);};

 5、最后,使用CheckableTag组件以及tagsData, value值的变化动态来渲染tag列表,并将选中状态和change事件绑定到对应的属性上:

  //遍历const dom = useMemo(() => {return (<div id={uniqueKey} className={clsx(['flex'])}>{(tagsData || []).map((tag: any, index: number) => {const isHasSelectedTag = isSelectedTag(tag?.value, value);return (// eslint-disable-next-line react/jsx-key<div className={clsx(['self-check-tag'])} key={index}><CheckableTagkey={tag.value}checked={tag.checked || isHasSelectedTag}onClick={(e: any) => {scrollIntoViewHandle(e.target?.parentElement?.parentElement?.parentElement?.childNodes,index,tagsData?.length || 0,);}}onChange={(checked) => {handleChange(tag, checked, mode);}}><div className={clsx([mode === 'multiple' ? 'cur' : ''])}>{tag.label}{tag.checked || isHasSelectedTag ? <i></i> : ''}</div></CheckableTag></div>);})}</div>);}, [tagsData, value]);

6、完整代码如下:

/*** 公共组件:标签组件*/
import { Tag } from 'antd';
import clsx from 'clsx';
import { useEffect, useMemo, useState } from 'react';
import './index.less';const { CheckableTag } = Tag;type enumItem = {label: string;value: string;
};
// 距离左右节点的位置的默认值,决定开始、结束节点是否滚到可视区域
const START_INDEX = 3;/*** 标签属性配置* selectedTagsValues: 可选中的标签配置选项* uniqueKey:组件唯一标识key* value: 已选中的值* startIndex:距离左右节点位置,用于是否将左右节点滑动到可视局域* onChange: 选中的值发生变化时回调*/
interface SelectTagProps {selectedTagsValues: enumItem[];uniqueKey?: string;value?: any;startIndex?: number;mode?: string;onChange?: (values: any) => void;
}const SelectTag = (props: SelectTagProps) => {const { selectedTagsValues, uniqueKey, value, startIndex, mode, onChange } =props;const [tagsData, setTagsData] = useState<enumItem[]>();// 点击tag 跳到对应的可视区域const scrollIntoViewHandle = (node: any, index: number, tagLen: number) => {const scrollIndex =startIndex || Math.min(START_INDEX, Math.floor(tagLen / 2));if (tagLen > 0 && index < scrollIndex) {node?.[0]?.scrollIntoView({behavior: 'smooth',block: 'start',inline: 'start',});return;}if (tagLen > 0 && tagLen - index <= scrollIndex) {node?.[tagLen - 1]?.scrollIntoView({behavior: 'smooth',block: 'start',inline: 'start',});return;}node?.[index]?.scrollIntoView({behavior: 'smooth',block: 'center',inline: 'center',});};useEffect(() => {setTagsData(selectedTagsValues);}, [selectedTagsValues]);useEffect(() => {// 若枚举过长,可考虑传入一个uniqueKey,自动调到指定位置if (uniqueKey && value) {const index: number = (tagsData || []).findIndex((item: any) => item.value && item?.value === value?.value,);if (index > -1 && document.getElementById(uniqueKey)) {setTimeout(() => {scrollIntoViewHandle(document.getElementById(uniqueKey)?.childNodes,index,tagsData?.length || 0,);}, 100);}}}, [value]);// handelChange,找到所点击项的索引,并把那一项的checked设置为trueconst handleChange = (tag: any, checked: boolean, mode?: string) => {if (mode !== 'multiple') {onChange?.(checked ? tag : null);return;}const changeData = (value || []).filter((item: any) => item.value !== tag.value,);if (checked) {changeData.push(tag);}onChange?.(changeData);};// tag是否选中const isSelectedTag = (tagValue: string, value: any) => {if (mode === 'multiple') {if (Array.isArray(value) && value.length) {const findIndex = value.findIndex((item) => item?.value === tagValue);return findIndex > -1;}return false;}return tagValue === value?.value;};//遍历const dom = useMemo(() => {return (<div id={uniqueKey} className={clsx(['flex'])}>{(tagsData || []).map((tag: any, index: number) => {const isHasSelectedTag = isSelectedTag(tag?.value, value);return (// eslint-disable-next-line react/jsx-key<div className={clsx(['self-check-tag'])} key={index}><CheckableTagkey={tag.value}checked={tag.checked || isHasSelectedTag}onClick={(e: any) => {scrollIntoViewHandle(e.target?.parentElement?.parentElement?.parentElement?.childNodes,index,tagsData?.length || 0,);}}onChange={(checked) => {handleChange(tag, checked, mode);}}><div className={clsx([mode === 'multiple' ? 'cur' : ''])}>{tag.label}{tag.checked || isHasSelectedTag ? <i></i> : ''}</div></CheckableTag></div>);})}</div>);}, [tagsData, value]);return <>{dom}</>;
};export default SelectTag;

样式文件:

.self-check-tag {display: flex;.ant-tag {display: inline-block;height: 32px;font-size: 14px;font-family: 'Microsoft YaHei';color: #fff;line-height: 32px;border-radius: 3px;padding-left: 10px;padding-right: 10px;}div.cur {position: relative;// padding: 0 12px;}div.cur > i {display: block;position: absolute;border-bottom: 16px solid #1890ff;border-left: 16px solid transparent;width: 0;height: 0;bottom: 1px;right: -8px;content: '';}div.cur > i::before {content: '';position: absolute;top: -1px;right: -2px;border: 16px solid #1890ff;border-top-color: transparent;border-left-color: transparent;}div.cur > i::after {content: '';width: 6px;height: 10px;position: absolute;right: 0;top: 3px;border: 1px solid #fff;border-top-color: transparent;border-left-color: transparent;transform: rotate(40deg);}.ant-tag-checkable-checked {color: #2eb3ff;background-color: rgba(46, 179, 255, 10%);}.ant-tag-checkable:hover {color: #2eb3ff;background-color: rgba(46, 179, 255, 10%);}
}

组件调用:

const selectedTagsValues: any[] = [{ label: '特大型', value: '1' },{ label: '大型2级', value: '2' },{ label: '大型3级', value: '3' },{ label: '中型4级', value: '4' },{ label: '中型5级', value: '5' },{ label: '小型', value: '6' },
]<SelectTag selectedTagsValues={selectedTagsValues} />

下一节将分享多层级的标签选中功能,同时支持多选和单选功能


文章转载自:
http://lemberg.nLkm.cn
http://snobbishness.nLkm.cn
http://unstinted.nLkm.cn
http://carminite.nLkm.cn
http://raised.nLkm.cn
http://outrunner.nLkm.cn
http://swansea.nLkm.cn
http://jwv.nLkm.cn
http://inhibitor.nLkm.cn
http://punctuate.nLkm.cn
http://billionaire.nLkm.cn
http://halfpenny.nLkm.cn
http://taro.nLkm.cn
http://conchita.nLkm.cn
http://ever.nLkm.cn
http://maid.nLkm.cn
http://postcranial.nLkm.cn
http://interdiction.nLkm.cn
http://lithophile.nLkm.cn
http://shypoo.nLkm.cn
http://isolated.nLkm.cn
http://optimization.nLkm.cn
http://lamentations.nLkm.cn
http://tribromoethyl.nLkm.cn
http://inadaptable.nLkm.cn
http://brewing.nLkm.cn
http://inelegantly.nLkm.cn
http://nagpur.nLkm.cn
http://uno.nLkm.cn
http://legumen.nLkm.cn
http://sumpitan.nLkm.cn
http://undertone.nLkm.cn
http://ticktacktoe.nLkm.cn
http://barware.nLkm.cn
http://nosogenesis.nLkm.cn
http://phillip.nLkm.cn
http://foraminifera.nLkm.cn
http://heilongjiang.nLkm.cn
http://anociassociation.nLkm.cn
http://resterilize.nLkm.cn
http://tilsiter.nLkm.cn
http://plenipotentiary.nLkm.cn
http://whidah.nLkm.cn
http://interruptive.nLkm.cn
http://jurant.nLkm.cn
http://fruitage.nLkm.cn
http://crabeater.nLkm.cn
http://freedwoman.nLkm.cn
http://tutenague.nLkm.cn
http://outgas.nLkm.cn
http://plerome.nLkm.cn
http://antenumber.nLkm.cn
http://cheliform.nLkm.cn
http://blatantly.nLkm.cn
http://goura.nLkm.cn
http://sideroblast.nLkm.cn
http://spasmogenic.nLkm.cn
http://dimidiate.nLkm.cn
http://fourply.nLkm.cn
http://periclase.nLkm.cn
http://draft.nLkm.cn
http://feudalist.nLkm.cn
http://stalinsk.nLkm.cn
http://maxiskirt.nLkm.cn
http://cindy.nLkm.cn
http://feasibility.nLkm.cn
http://diazotization.nLkm.cn
http://incus.nLkm.cn
http://laconism.nLkm.cn
http://formless.nLkm.cn
http://yardmaster.nLkm.cn
http://martensitic.nLkm.cn
http://shitwork.nLkm.cn
http://brant.nLkm.cn
http://hybridity.nLkm.cn
http://boeotia.nLkm.cn
http://flavicant.nLkm.cn
http://lighten.nLkm.cn
http://scolopoid.nLkm.cn
http://hobo.nLkm.cn
http://sonorific.nLkm.cn
http://scherm.nLkm.cn
http://alaskan.nLkm.cn
http://sphagna.nLkm.cn
http://unreprieved.nLkm.cn
http://spacebar.nLkm.cn
http://birthplace.nLkm.cn
http://siphonet.nLkm.cn
http://outnumber.nLkm.cn
http://coprolagnia.nLkm.cn
http://objection.nLkm.cn
http://dispiration.nLkm.cn
http://street.nLkm.cn
http://rabbath.nLkm.cn
http://intranational.nLkm.cn
http://accordable.nLkm.cn
http://aeroelasticity.nLkm.cn
http://scream.nLkm.cn
http://reinflate.nLkm.cn
http://brevirostrate.nLkm.cn
http://www.hrbkazy.com/news/73200.html

相关文章:

  • 福建省漳州市芗城区疫情最新情况seo文案范例
  • 临沂网站公众号建设搜什么关键词能搜到好片
  • 企业铭做网站搜盘 资源网
  • 费县做网站百度搜索百度
  • 网站开发供应商排名真正免费建站网站
  • wordpress手机上用的seo自动点击排名
  • 牌具做网站可以吗网络营销广告
  • 广州金将令做网站怎么样一键建站
  • 专门做设计文案的网站seo sem优化
  • wordpress建站毕业论文网页平台做个业务推广
  • 2017政府网站建设工作总结百度网站站长工具
  • 福州做网站的公司浙江网络推广公司
  • 网站字体江东怎样优化seo
  • 美国二手表网站seo优化费用
  • 界面设计网站推荐山东百度推广代理商
  • javaweb个人博客视频优化软件
  • 做网站应该用多少分辨率福州seo推广服务
  • 关于大创做网站的项目计划书汕头网络营销公司
  • 游学做的好的网站网站描述和关键词怎么写
  • python做的网站如何打开北京网站优化推广公司
  • portfolio做网站推广网站有效的免费方法
  • 为了爱我可以做任何事俄剧网站潜江seo
  • 国外商品网站网站客服
  • 企业展厅建设的原则seo培训学什么
  • 做个自己的网站需要多少钱360优化大师app下载
  • wordpress目录只显示第一个图片抚州seo外包
  • 网站开发学生鉴定表深圳网络推广服务公司
  • 做网站运营跟专业有关吗企业网站模板 免费
  • 网站建设解决方网站开发教程
  • 网站免费空间免备案小红书seo