使用阿里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的文档说实话一言难尽,用起来也是,说白了我也白说,写个博客做个记录 大家看个乐子就好。

相关推荐
天蓝色的鱼鱼1 天前
都2026年了还不会Vite插件开发?手写一个版本管理插件,5分钟包会!
前端·vite
苏武难飞1 天前
分享一个33号远征队的效果!
前端
鹏程十八少1 天前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
亿元程序员1 天前
这款值68亿的游戏,你不实战一下吗?安排!
前端
摸鱼的春哥1 天前
Agent教程15:认识LangChain(中),状态机思维
前端·javascript·后端
明月_清风1 天前
告别遮挡:用 scroll-padding 实现优雅的锚点跳转
前端·javascript
明月_清风1 天前
原生 JS 侧边栏缩放:从 DOM 监听到底层优化
前端·javascript
万少1 天前
HarmonyOS 开发必会 5 种 Builder 详解
前端·harmonyos
橙序员小站1 天前
Agent Skill 是什么?一文讲透 Agent Skill 的设计与实现
前端·后端
炫饭第一名2 天前
速通Canvas指北🦮——基础入门篇
前端·javascript·程序员