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

相关推荐
JosieBook12 小时前
【Vue】01 Vue技术——Vue简介
前端·javascript·vue.js
HIT_Weston12 小时前
48、【Ubuntu】【Gitlab】拉出内网 Web 服务:Nginx 事件驱动分析(二)
前端·ubuntu·gitlab
EB_Coder12 小时前
前端面试题-JavaScript中级篇
前端·javascript·面试
Beginner x_u12 小时前
从接口文档到前端调用:Axios 封装与实战全流程详解
前端·javascript·ajax·接口·axios
HIT_Weston12 小时前
46、【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 分析(三)
前端·ubuntu·gitlab
测试-鹏哥12 小时前
ITP平台全新Mock服务上线 —— 助力高效API测试
前端·python·测试工具
BlackWolfSky12 小时前
ES6 教程学习笔记
前端·javascript·es6
IT_陈寒12 小时前
Redis性能翻倍的5个冷门技巧:从缓存穿透到集群优化实战指南
前端·人工智能·后端
不会写DN12 小时前
如何实现UniApp登录拦截?
前端·javascript·vue.js·typescript·uni-app·vue
不老刘12 小时前
深入理解 React Native 的 Metro
javascript·react native·react.js·metro