使用阿里lowcode,封装SearchDropdown 搜索下拉组件

"组件本身代码逻辑并不复杂,主要记录踩坑点和思路~~"

1、先做记录吧

由于alilowcode和alifd/next深度集成,做之前也是先看了下alifd/next的组件库,发现有现成的可以直接用,这不cv就完s事了(暗爽~),也是做出第一版了。
官方案例:

第一版

SearchDropdown.tsx

tsx 复制代码
import React, { createElement, useState } from 'react';
import { Search } from '@alifd/next';
import './index.scss';

export interface SearchDropdownProps {
  placeholder?: string;
  data?: { label: string; value: string }[];
  onSelect?: (value: string) => void;
  onSearch?: (value: string) => void;
  buttonText?: string;
}

const SearchDropdown: React.FC<SearchDropdownProps> = ({
  placeholder = '请输入搜索内容',
  data = [],
  onSelect,
  onSearch,
}) => {
  const [searchValue, setSearchValue] = useState('');

  const handleSearch = (value: string) => {
    onSearch?.(value);
  };
  
  const handleChange = (value: string) => {
    onSelect?.(value);
    setSearchValue(value)
  };

  return (
    <div className="search-dropdown">
      <Search
        placeholder={placeholder}
        value={searchValue}
        autoHighlightFirstItem={false}
        fillProps="label"
        dataSource={data}
        onChange={handleChange}
        onSearch={handleSearch}
        shape="simple"
        hasClear
      />
    </div>
  );
};

export default SearchDropdown;

meta.ts

ts 复制代码
import { IPublicModelComponentMeta } from '@alilc/lowcode-types';

const SearchDropdownMeta: IPublicModelComponentMeta = {
  componentName: 'SearchDropdown',
  title: '搜索下拉弹层',
  group: '组件',
  category: 'xxxx',
  devMode: 'proCode',
  npm: {
    package: 'xxx',
    version: '0.1.0',
    exportName: 'SearchDropdown',
    main: 'src/index.tsx',
    destructuring: true,
  },

  props: [
    {
      name: 'placeholder',
      title: {
        label: '占位文字',
        tip: '输入框未输入时的提示文字',
      },
      setter: 'StringSetter',
      defaultValue: '请输入搜索内容',
    },
    {
      name: 'data',
      setter: {
        componentName: 'JsonSetter',
        isRequired: true,
        props: {},
      },
    },
    {
      name: 'onSearch',
      title: {
        label: '搜索事件',
        tip: '当搜索框输入或回车时触发',
      },
      setter: 'FunctionSetter',
    },
    {
      name: 'onSelect',
      title: {
        label: '选中事件',
        tip: '当选择下拉项时触发',
      },
      setter: 'FunctionSetter',
    },
  ],

  supports: {
    style: true,
    events: ['onSearch', 'onSelect'],
  },


  snippets: [
    {
      title: '搜索下拉弹层',
      schema: {
        componentName: 'SearchDropdown',
        props: {
          placeholder: '请输入搜索内容',
          buttonText: 'Delete',
          data: [
            { label: '选项1', value: '1' },
            { label: '选项2', value: '2' },
            { label: '选项3', value: '3' },
          ],
        }
      },
    },
  ],
};

export default SearchDropdownMeta;

坑与思路

坑:

第一版写出来效果和功能初步来看还是很好的,但是自己一番测试下来发现这个handleChange每次都会触发onselect事件,但是看了官方文档Search组件是没有onSelect事件的,所以每次都会触发onselect的逻辑是不对的,而我要的需求是:点击select下拉框里面的才去触发onSelect事件

原始思路:

因为我知道dataSource的数据和数据结构,这个就很简单了我在onSelect逻辑里面去做判断每次输入的值和dataSource里面的label是否一致,再去判断是否触发对应业务逻辑就行。

这么做可以解决用户在模糊输入时去点击选择精确对象时触发onSelect事件的问题,但是用户要是精确输入的话之前的问题还是存在的

最终思路:

仔细观察官方demo里面发现onChange里面有三个入参,通过看控制台发现输入内容时打印结果是:

但是选中下拉时打印结果是:

那么问题就解决了

最终版SearchDropdown.tsx

tsx 复制代码
import React, { createElement, useState, useRef } from 'react';
import { Search, Overlay, Menu, Button } from '@alifd/next';
import './index.scss';

export interface SearchDropdownProps {
  placeholder?: string;
  data?: { label: string; value: string }[];
  onSelect?: (value: string) => void;
  onSearch?: (value: string) => void;
  buttonText?: string;
}

const SearchDropdown: React.FC<SearchDropdownProps> = ({
  placeholder = '请输入搜索内容',
  data = [],
  onSelect,
  onSearch,
}) => {
  const [searchValue, setSearchValue] = useState('');

  const handleSearch = (value: string) => {
    onSearch?.(value);
  };
  
  const handleChange = (value: string, type: any, e: any) => {
    // console.log(value, type, e);
    if(type === 'itemClick') { // 这里判断下就能完美解决
      onSelect?.(value);
    }
    setSearchValue(value)
  };

  return (
    <div className="search-dropdown">
      <Search
        placeholder={placeholder}
        value={searchValue}
        autoHighlightFirstItem={false}
        fillProps="label"
        dataSource={data}
        onChange={handleChange}
        onSearch={handleSearch}
        shape="simple"
        hasClear
      />
    </div>
  );
};

export default SearchDropdown;

总结:组件代码逻辑其实真的很简单,alifd/next的文档说实话一言难尽,用起来也是,说白了我也白说,写个博客做个记录 大家看个乐子就好。

相关推荐
jlspcsdn1 天前
20251222项目练习
前端·javascript·html
行走的陀螺仪1 天前
Sass 详细指南
前端·css·rust·sass
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ1 天前
React 怎么区分导入的是组件还是函数,或者是对象
前端·react.js·前端框架
LYFlied1 天前
【每日算法】LeetCode 136. 只出现一次的数字
前端·算法·leetcode·面试·职场和发展
子春一21 天前
Flutter 2025 国际化与本地化工程体系:从多语言支持到文化适配,打造真正全球化的应用
前端·flutter
前端无涯1 天前
React/Vue 代理配置全攻略:Vite 与 Webpack 实战指南
vue.js·react.js
QT 小鲜肉1 天前
【Linux命令大全】001.文件管理之file命令(实操篇)
linux·运维·前端·网络·chrome·笔记
羽沢311 天前
ECharts 学习
前端·学习·echarts
LYFlied1 天前
WebAssembly (Wasm) 跨端方案深度解析
前端·职场和发展·wasm·跨端