基于react-vant实现弹窗搜索功能

学习一下项目中的代码

弹出层的顶部用到了Search组件

1. action

Search组件中需要自定义右侧的按钮,可以使用showAction(默认文字为取消)+ actionText自定义按钮文字;也可以使用action自定义右边部分操作区域

官网文档使用方法1:

jsx 复制代码
<Search
  showAction
  label="地址"
  actionText={<div onClick={() => Toast.info(value)}>搜索</div>}
  value={value}
  onChange={setValue}
  placeholder="请输入搜索关键词"
/>

2. value

value 用于控制搜索框中的文字

value绑定的变量,通过onChange更新即可

3.点击进行搜索

jsx 复制代码
// 搜索关键词
const onSearchClinic = async () => {
    // 前置校验
    if (!searchName) {
      Toast('请输入名称关键字再进行搜索')
      return
    }
    // 开始搜索
    try {
      setSearchLoading('loading')
      const {
        data: { rows },
      } = await triggerClinicList()
      const _rows = [...rows].map((item) => ({
        ...item,
        value: item.code,
        text: item.name,
      }))
      setClinicList(_rows)
      setSearchLoading('sucess')
    } catch (error) {
      setSearchLoading('sucess')
    }
}

数据列表 - List 组件

List 组件滚动到底部时,会触发 onLoad 事件,此时可以发起异步操作并更新数据,若数据已全部加载完毕,则直接将 finished 设置成 true 即可。

react-vant - List 内部包含了防止并发的重复请求的逻辑,使用中不需要额外处理

如果有分页,则可以使用onLoad事件,项目中为全量返回,所以不需要这个。

选择则某个诊所之后进行反显

搜索的字段和外层最终反显的字段分为两个记录,关闭的时候或者每次打开的时候要清除内部的字段(看业务要求)

jsx 复制代码
const [clinicName, setClinicName] = useState('') // 外层业务字段
  const [searchName, setSearchName] = useState('') // 弹窗记录搜索的关键字
// 点击cell,进行选择
const setClinicHandle = (v: any) => {
    // 更新外层输入框名称
    // 关闭弹窗
    onCloseClinicPop()
}

占位组件 - Empty

占位组件的图片有两个状态:1.图片显示 2. loading显示

占位组件的文案有两个状态:1.初始化时的搜索提醒 2. 搜索结果为空时的提醒

jsx 复制代码
  // loading -- 加载中,wait -- 初始化, sucess -- 搜索完成(不论结果如何)
  const [searchLoading, setSearchLoading] = useState<'wait' | 'loading' | 'sucess'>('wait')

其他小细节:

  1. 点击外层按钮,唤起弹窗时自动聚焦到搜索输入框
jsx 复制代码
const searchRef = useRef<SearchInstance | any>(null)
// 显示
const onShowClinicPop = () => {
    // do something 点击前校验,清空搜索关键词 onClearClinic
    setShowClinicPop(true) // 弹窗
    setTimeout(() => {
      if (searchRef && searchRef.current) {
        searchRef.current?.focus() // 设置焦点
      }
    }, 0)
 }
// 关闭弹窗
const onCloseClinicPop = () => {
    if (searchRef && searchRef.current) {
      searchRef.current?.blur() // 设置焦点
    }
    setShowClinicPop(false)
}

部分代码如下:

jsx 复制代码
<Popup
position="bottom"
round={true}
visible={showClinicPop}
onClose={onCloseClinicPop}
style={{ height: '60vh' }}
>
    <div className="popup-header">
      <VantButton
        style={{
          border: 'none',
          boxShadow: 'none',
          backgroundColor: 'transparent',
          color: 'inherit',
        }}
        icon={<Cross />}
        onClick={onCloseClinicPop}
      />
    </div>
    <Search
      action={
        <div
          className="search-text"
          onClick={onSearchClinic}
        >
          搜索
        </div>
      }
      value={searchName}
      onChange={(v) => {
        setSearchName(v)
      }}
      placeholder="输入名称关键字"
      onSearch={onSearchClinic}
      onClear={onClearClinic}
      ref={searchRef}
    />
    <div style={{ height: 'calc(60vh - 98px)', overflowY: 'auto' }}>
      {clinicList?.length > 0 ? (
        <List
          onLoad={() => new Promise(() => {})}
          finished={true}
        >
          {clinicList.map((item, index) => (
            <Cell
              key={index}
              value={item.text}
              isLink
              arrowDirection="right"
              valueClass="text-[#323232]"
              onClick={() => {
                setClinicHandle(item.code)
              }}
            />
          ))}
        </List>
      ) : (
        <Empty
          image={
            searchLoading === 'loading' ? (
              <div className="empty-loading">
                <Loading type="ball" />
              </div>
            ) : (
              'search'
            )
          }
          description={
            searchLoading === 'sucess'
              ? '搜索列表为空'
              : searchLoading === 'wait'
                ? '点击搜索查找您的诊所'
                : ''
          }
        />
      )}
    </div>
</Popup>
相关推荐
打小就很皮...29 分钟前
HBuilder 发行Android(apk包)全流程指南
前端·javascript·微信小程序
集成显卡1 小时前
PlayWright | 初识微软出品的 WEB 应用自动化测试框架
前端·chrome·测试工具·microsoft·自动化·edge浏览器
前端小趴菜052 小时前
React - 组件通信
前端·react.js·前端框架
Amy_cx3 小时前
在表单输入框按回车页面刷新的问题
前端·elementui
dancing9993 小时前
cocos3.X的oops框架oops-plugin-excel-to-json改进兼容多表单导出功能
前端·javascript·typescript·游戏程序
HarderCoder3 小时前
学习React的一些知识
react.js
后海 0_o3 小时前
2025前端微服务 - 无界 的实战应用
前端·微服务·架构
Scabbards_3 小时前
CPT304-2425-S2-Software Engineering II
前端
小满zs3 小时前
Zustand 第二章(状态处理)
前端·react.js
程序猿小D3 小时前
第16节 Node.js 文件系统
linux·服务器·前端·node.js·编辑器·vim