Ven*_*son 13 javascript reactjs
我正面临search. 它是前端搜索而不是远程搜索,我使用react.js它是因为它是问题中的一个要求并创建了一个名为App. 我的任务是根据类型值显示并突出显示匹配的部分。
我会很感激的。如果你为此提供了一个很好的解决方案。
让我告诉你整个场景。我将这个问题分为 3 个部分。
第 1 部分: 数据的形状是什么?
数据的形状是这样的:
源代码/数据.js:
export default [
{
id: 1,
name: 'Wordpress',
list: [
{
id: 1,
name: 'Best Mobile App Builder',
slug: '/'
},
{
id: 2,
name: 'Best Wordpress Themes',
slug: '/'
},
{
id: 3,
name: 'Best Website Creator',
slug: '/'
},
{
id: 4,
name: 'Best Wordpress Builder',
slug: '/'
}
]
},
{
id: 2,
name: 'SaaS',
list: [
{
id: 1,
name: 'Appointment Scheduling Software',
slug: '/'
},
{
id: 2,
name: 'Design Services',
slug: '/'
},
{
id: 3,
name: 'Online Cloud Storage',
slug: '/'
},
{
id: 4,
name: 'Remote PC Access',
slug: '/'
}
]
},
];
Run Code Online (Sandbox Code Playgroud)
注意:
基本上这是我的过滤功能。
源代码/过滤器.js:
import _ from 'lodash';
import match from 'autosuggest-highlight/match';
import parse from 'autosuggest-highlight/parse';
/**
* Returns the new filtered array with highlighted parts.
* @param data {Array<Object>} - The collection to iterate over.
* @param inputValue {string} - The input value.
* @return {Array} - Returns the new filtered array.
*/
export const filterByNames = (data, inputValue) => {
// Create a dynamic regex expression object with ignore case sensitivity
const re = new RegExp(_.escapeRegExp(inputValue), 'i');
const results = data.filter((object) => {
if (re.test(object.name)) {
return true;
} else {
return object.list.some((item) => {
if (re.test(item.name)) {
// Calculates the characters to highlight in text based on query
const matches = match(item.name, inputValue);
// Breaks the given text to parts based on matches.
// After that create a new property named `parts` and assign an array to it.
item['parts'] = parse(item.name, matches);
return true;
} else {
return false;
}
});
}
});
return results;
};
Run Code Online (Sandbox Code Playgroud)
搜索工作正常,但面临两个主要问题。
当name属性的上述匹配发生时,它就会停止并且不会更深入。嵌套列表name属性也会发生同样的事情。
当过滤在幕后发生时,我们通过添加一个名为的新属性来改变原始数据,该属性parts包含突出显示的部分,它是一个对象数组。但我不想改变原始数据,而是想返回包含parts属性的新过滤数组。
看到这个。
工作演示:
第 2 部分: 我使用哪些第三方库进行过滤和突出显示?
lodash字符串函数escapeRegExp用于转义RegExp 特殊字符。
autosuggest-highlight 匹配函数根据查询计算文本中要突出显示的字符。
之后,来自同一个库的parse函数帮助我们parts根据匹配将给定的文本分解为。最后,它将返回一个带有匹配字符串和highlight
布尔标志的对象数组。所以我们很容易在 UI 上加粗突出显示parts。
第 3 部分:应用程序组件
import React, { useState } from 'react';
import { filterByNames } from './filter';
import data from './data';
/**
* Return the JSX for the List
* @param data {Array<Object>} - The collection to iterate over.
* @return {null|*} - Returns the JSX or null.
*/
const renderList = (data) => {
if (Array.isArray(data) && data.length > 0) {
return data.map((object) => {
return (
<div key={object.id}>
<h1>{object.name}</h1>
<ul className="list">
{object.list.map((item) => {
return (
<li key={item.id}>
{item.parts ? (
<a href={item.slug}>
{item.parts.map((part, index) => (
<span
key={index}
style={{ fontWeight: part.highlight ? 700 : 400 }}
>
{part.text}
</span>
))}
</a>
) : (
<a href={item.slug}>{item.name}</a>
)}
</li>
)
})}
</ul>
</div>
)
})
} else {
return null
}
};
// Main App Component
const App = () => {
const [value, setValue] = useState('');
const onChangeHandler = (event) => {
const { target } = event;
const val = target.value;
setValue(val);
};
const results = !value ? data : filterByNames(data, value);
return (
<div className="demo">
<input type="text" value={value} onChange={onChangeHandler}/>
<div className="demo-result">
{ renderList(results) }
</div>
</div>
);
};
export default App;
Run Code Online (Sandbox Code Playgroud)
小智 2
这是修改后的代码。
export const filterByNames = (data, inputValue) => {
// Create a dynamic regex expression object with ignore case sensitivity
const re = new RegExp(_.escapeRegExp(inputValue), "i");
const clonedData = _.cloneDeep(data);
const results = clonedData.filter((object) => {
return object.list.filter((item) => {
if (re.test(item.name)) {
// Calculates the characters to highlight in text based on query
const matches = match(item.name, inputValue);
// Breaks the given text to parts based on matches.
// After that create a new property named `parts` and assign an array to it.
item["parts"] = parse(item.name, matches);
return true;
} else {
return false;
}
}).length > 0 || re.test(object.name);
});
return results;
};
Run Code Online (Sandbox Code Playgroud)
此处分叉链接。 https://codesandbox.io/s/search-frontend-forked-e3z55