背景
最近有个「网站建设」的需求,需要调研 AI 生成前端组件的可行性。本文将介绍如何利用 AI 技术生成前端组件,结合 Ant Design 库和 Tailwind Styled Components 搭建组件,同时使用 prompt 来约束组件的生成,提高开发效率。
AI生成前端组件
由于从未接触过 AI 生成组件,我们先尝试利用简单文案,看能不能生成前端组件。prompt 如下:
arduino
"请生成一个登录表单组件,使用React和Ant Design库,表单包含用户名和密码输入框,"
"以及一个登录按钮。当用户输入用户名和密码后,点击登录按钮时,触发一个回调函数。"
生成的代码
tsx
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示例:
markdown
请生成一个React表格组件,使用Ant Design库和tailwind-styled-components。表格需要支持以下功能:
1. 分页:用户可以通过点击分页按钮来切换页面;
2. 搜索:用户可以输入关键词来搜索表格中的数据;
3. 筛选:用户可以通过选择筛选条件来筛选表格中的数据;
4. 数据来源:表格的数据来源于一个名为fetchData的函数,该函数接收一个对象作为参数,包含分页信息、搜索关键词和筛选条件。
生成的代码更加丰富了
tsx
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 效果会更好一点
sql
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。
以下是一个可能的生成代码示例:
tsx
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 预期。我们需要优化一下 USER_OUTPUT 部分,这样可以生成更好看的 UI
sql
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 来确定元素列表的内容
总结
本文介绍了如何利用AI技术生成前端组件,结合Ant Design库和tailwind-styled-components搭建组件,并使用prompt来约束组件的生成。通过这种方法,我们可以提高生成组件的质量。但从整个实现过程发现,如果生成太复杂的组件,会很不可控,生成的代码容易运行出错。所以这种方案适用于生成简单组件,够用就行