"组件本身代码逻辑并不复杂,主要记录踩坑点和思路~~"
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的文档说实话一言难尽,用起来也是,说白了我也白说,写个博客做个记录 大家看个乐子就好。