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

相关推荐
搞个锤子哟4 小时前
vant4的van-pull-refresh里的列表不在顶部时下拉也会触发刷新的问题
前端
jnpfsoft4 小时前
低代码视图真分页实操:API/SQL 接口配置 + 查询字段避坑,数据加载不卡顿
前端·低代码
前端付豪4 小时前
万事从 todolist 开始
前端·vue.js·前端框架
小胖霞4 小时前
从零开始:在阿里云 Ubuntu 服务器部署 Node+Express 接口(基于公司 GitLab)
前端·后端
A_Bin4 小时前
前端工程化之【包管理器】
前端
小肚肚肚肚肚哦4 小时前
CSS 伪类函数 :where 简介
前端·css
Nick56834 小时前
Swift -- 第三方登录之微信登录 源码分享
前端
麦麦大数据4 小时前
D026 vue3+django 论文知识图谱推荐可视化系统 | vue3+vite前端|neo4j 图数据库
前端·django·vue3·知识图谱·推荐算法·论文文献·科研图谱
小肚肚肚肚肚哦4 小时前
伪元素与普通元素的层级关系问题浅析
前端·css