背景
最近有个「网站建设」的需求,需要调研 AI 生成前端组件的可行性。本文将介绍如何利用 AI 技术生成前端组件,结合 Ant Design 库和 tailwind-styled-components 搭建组件,同时使用 prompt 来约束组件的生成,提高开发效率。
AI生成前端组件
由于从未接触过 AI 生成组件,我们先尝试利用简单文案,看能不能生成前端组件。prompt 如下:
"请生成一个登录表单组件,使用React和Ant Design库,表单包含用户名和密码输入框,"
"以及一个登录按钮。当用户输入用户名和密码后,点击登录按钮时,触发一个回调函数。"
生成的代码
import React, { useState } from 'react';
import { Form, Input, Button } from 'antd';
const LoginForm = ({ onLogin }) => {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
const handleSubmit = async (values) => {
setLoading(true);
await onLogin(values);
setLoading(false);
};
return (
<Form form={form} onFinish={handleSubmit}>
<Form.Item
name="username"
rules={[{ required: true, message: 'Please enter your username' }]}
>
<Input placeholder="Username" />
</Form.Item>
<Form.Item
name="password"
rules={[{ required: true, message: 'Please enter your password' }]}
>
<Input.Password placeholder="Password" />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" loading={loading}>
Login
</Button>
</Form.Item>
</Form>
);
};
export default LoginForm;
还生成了表单校验逻辑
这段 prompt,要求生成一个登录表单组件。AI 模型会根据这个 prompt 生成相应的代码,并返回给我们。方案基本可行。但这样的代码在项目中肯定不能直接用,我们继续优化
使用prompt约束组件的生成
大家都知道,AI 经常会出现幻觉,为了让结果更加的稳定可控,我们需要约束力更强的 prompt。我们可以使用 Ant Design
库和 tailwind-styled-components
来搭建组件。
为了生成满足特定需求的组件,我们需要编写一个详细的prompt来约束AI模型的生成。在上面的例子中,我们已经编写了一个简单的prompt来生成登录表单组件。当然,我们还可以编写更复杂的prompt来生成更复杂的组件,如包含分页、搜索、筛选等功能的表格组件。
以下是一个生成包含分页、搜索、筛选功能的表格组件的prompt示例:
请生成一个React表格组件,使用Ant Design库和tailwind-styled-components。表格需要支持以下功能:
1. 分页:用户可以通过点击分页按钮来切换页面;
2. 搜索:用户可以输入关键词来搜索表格中的数据;
3. 筛选:用户可以通过选择筛选条件来筛选表格中的数据;
4. 数据来源:表格的数据来源于一个名为fetchData的函数,该函数接收一个对象作为参数,包含分页信息、搜索关键词和筛选条件。
生成的代码更加丰富了
import React, { useState } from 'react';
import { Table, Input, Select } from 'antd';
import styled from 'styled-components/macro';
import tw from 'tailwind-styled-components';
const { Option } = Select;
const StyledTableContainer = tw.div`
bg-white
rounded-lg
shadow-md
p-4
`;
const StyledTableHeader = tw.div`
flex
justify-between
items-center
mb-4
`;
const StyledSearchContainer = tw.div`
flex
items-center
`;
const StyledSearchInput = tw(Input)`
w-64
mr-4
`;
const StyledSelect = tw(Select)`
w-64
`;
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
];
const data = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: '4',
name: 'Jim Red',
age: 32,
address: 'London No. 2 Lake Park',
},
];
const TableComponent = () => {
const [currentPage, setCurrentPage] = useState(1);
const [searchValue, setSearchValue] = useState('');
const [filterValue, setFilterValue] = useState('');
const handlePageChange = (page) => {
setCurrentPage(page);
};
const handleSearch = (event) => {
setSearchValue(event.target.value);
};
const handleFilterChange = (value) => {
setFilterValue(value);
};
const filteredData = data.filter((item) =>
item.name.toLowerCase().includes(searchValue.toLowerCase())
);
const filteredAndSortedData = filterValue
? filteredData.filter((item) => item.age === Number(filterValue))
: filteredData;
return (
<StyledTableContainer>
<StyledTableHeader>
<StyledSearchContainer>
<StyledSearchInput
placeholder="Search by name"
value={searchValue}
onChange={handleSearch}
/>
<StyledSelect
placeholder="Filter by age"
allowClear
onChange={handleFilterChange}
value={filterValue}
>
<Option value="32">32</Option>
<Option value="42">42</Option>
</StyledSelect>
</StyledSearchContainer>
<div>Page {currentPage}</div>
</StyledTableHeader>
<Table
columns={columns}
dataSource={filteredAndSortedData}
pagination={{
current: currentPage,
pageSize: 2,
total: filteredAndSortedData.length,
onChange: handlePageChange,
}}
/>
</StyledTableContainer>
);
};
export default TableComponent;
但实际效果不行
优化 prompt
我们可以将文案优化为:我们将确定 prompt 的过程分为两个部分。
- 第一部分专注于约束组件的生成范围,例如使用 antd 库、包含 interface 和默认值等。
- 第二部分关注组件的业务信息,如需包含图片、列表等。
请注意,第一部分可以固定在 prompt 模板中,而第二部分可由用户自行输入。
另外,我们采用的是 ChatGPT 3.5,使用英文 prompt 可获得更佳效果。
You are a React developer and an excellent markdown developer who generates React components based on user input and meets the following requirements:
1. The component name must be in English with uppercase letters
2. The typescript interface that needs to be generated for the component, and all props are optional
3. Used Ant Design component library to create components
4. use tailwind-styled-components for styling the component
5. The default value for image address is Picsum
6. The default values for all other props will be in Chinese
7. write all the components and style in one file
USER_OUTPUT:
名称:表格组件
描述:table
元素列表:
1. 分页:用户可以通过点击分页按钮来切换页面;
2. 搜索:用户可以输入关键词来搜索表格中的数据;
3. 筛选:用户可以通过选择筛选条件来筛选表格中的数据;
Remember, you need to clarify the user input requirements before generating the document.
Begin!
在这个优化后的文案中,我们对 prompt 的约束增加了严谨性。除了限制使用的库外,还要求生成相应的样式和 interface。
以下是一个可能的生成代码示例:
import React from 'react';
import { Table, Pagination, Input, Select } from 'antd';
import tw from 'tailwind-styled-components';
interface TableComponentProps {
pagination?: boolean;
search?: boolean;
filter?: boolean;
pageSize?: number;
currentPage?: number;
searchText?: string;
filterOptions?: string[];
filterValue?: string;
imageUrl?: string;
}
const { Option } = Select;
const TableContainer = tw.div`
.ant-table {
margin-bottom: 1rem;
}
`;
const SearchContainer = tw.div`
flex
justify-end
items-center
mb-4
`;
const FilterContainer = tw.div`
flex
justify-end
items-center
mb-4
`;
const TableComponent: React.FC<TableComponentProps> = ({
pagination = true,
search = true,
filter = true,
pageSize = 10,
currentPage = 1,
searchText = '请输入搜索关键词',
filterOptions = ['请选择筛选条件'],
filterValue = '请选择',
imageUrl = 'https://picsum.photos/200',
}) => {
const columns = [
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
},
{
title: '地址',
dataIndex: 'address',
key: 'address',
},
];
const data = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: '4',
name: 'Jim Red',
age: 32,
address: 'London No. 2 Lake Park',
},
];
const handlePageChange = (page: number) => {
console.log(page);
};
const handleSearch = (value: string) => {
console.log(value);
};
const handleFilterChange = (value: string) => {
console.log(value);
};
return (
<TableContainer>
{search && (
<SearchContainer>
<Input.Search
placeholder={searchText}
onSearch={handleSearch}
enterButton
/>
</SearchContainer>
)}
{filter && (
<FilterContainer>
<Select
defaultValue={filterValue}
style={{ width: 200 }}
onChange={handleFilterChange}
>
{filterOptions.map((option) => (
<Option key={option} value={option}>
{option}
</Option>
))}
</Select>
</FilterContainer>
)}
<Table
dataSource={data}
columns={columns}
pagination={
pagination
? {
pageSize,
current: currentPage,
onChange: handlePageChange,
}
: false
}
/>
<img src={imageUrl} alt="placeholder" />
</TableContainer>
);
};
export default TableComponent;
在此示例中,我们采用了 Ant Design 库中的 Table、Input、Pagination 和 Select 组件,以及 tailwind-styled-components 提供的样式。生成的代码基本满足 prompt 的预期。为了实现更美观的 UI,我们需要对 USER_OUTPUT 部分进行优化。
You are a React developer and an excellent markdown developer who generates React components based on user input and meets the following requirements:
1. The component name must be in English with uppercase letters
2. The typescript interface that needs to be generated for the component, and all props are optional
3. All labels must use the antd label
4. Component style using tailwindcss
5. The default value for image address is Picsum
6. Component properties must have Chinese default values
7. All components are written in one file
8. Using Card components as the basic container for components
Remember, you need to clarify the user input requirements before generating the document.
USER_OUTPUT:
名称:Pet Services Component
描述:This component is suitable for displaying information about our pet services.
元素列表:
- Display pictures list of pets
- Brief description of our pet services
- Link to see more details about our services
- Tag list of our services, such as "Veterinary Care", "Grooming", "Training", etc.
- Description of pets
Begin!
进一步的优化中,我们可以让用户输入一段描述,然后利用 AI 来确定元素列表的内容。在将生成的内容和这次的 prompt 结合。
总结
本文探讨了如何借助 AI 技术生成前端组件,结合 Ant Design 库和 tailwind-styled-components 构建组件,并使用 prompt 来约束组件生成范围。通过这种方法,我们能够提升生成组件的质量。然而,在整个实现过程中,我们发现生成过于复杂的组件可能导致不可控的情况,从而使得生成的代码容易出错。因此,这种方案更适用于生成简单的组件,满足基本需求即可。