👾 “天呐,我找到开发捷径了!”
第一次打开 Copilot,就像打开了一扇通往未来的门。
怀着激动的小心情,我敲下了第一行提示:“帮我写个登录界面代码。” 结果,屏幕上一串流畅的代码蹦了出来!
不过,中间也闹了点小乌龙——我本以为它会问我喜欢的语言,结果直接“无情”地生成了 React 代码。🙃 好家伙,Copilot 你比我还懂我自己?
代码如下:
// @ts-ignore;
import React from 'react';
// @ts-ignore;
import { Card, CardContent, CardHeader, CardTitle, Input, Button, Checkbox, Label, CardFooter } from '@/components/ui';
export default function LoginPage(props) {
return <div className="min-h-screen flex items-center justify-center bg-gray-50 p-4">
<Card className="w-full max-w-md p-6 rounded-lg shadow-md bg-white">
<CardHeader className="mb-4">
<CardTitle className="text-2xl font-semibold">登录</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<Label htmlFor="email">邮箱</Label>
<Input id="email" type="email" placeholder="请输入您的邮箱" className="w-full" />
</div>
<div className="space-y-2">
<Label htmlFor="password">密码</Label>
<Input id="password" type="password" placeholder="请输入您的密码" className="w-full" />
</div>
<div className="flex items-center space-x-2">
<Checkbox id="remember">记住我</Checkbox>
<a href="#" className="text-sm text-gray-500">忘记密码?</a>
</div>
</CardContent>
<CardFooter className="flex justify-between items-center mt-6">
<Button variant="primary" className="w-full">登录</Button>
<div className="text-sm text-gray-500">还没有账号? <a href="#" className="text-primary">立即注册</a></div>
</CardFooter>
</Card>
</div>;
}
🎉 优点:简单易用,效率拉满
😅 槽点:让我怀疑自己存在感
为了全面测试 Copilot 的能力,我决定开发一个 “每日记账”小程序,记录收入、支出并生成月度报表。以下是完整的开发过程:
🛠️ 步骤一:生成代码
输入提示:“开发一个每日记账小程序,包含 记录管理、报表生成功能。”
生成的代码如下:
// @ts-ignore;
import React, { useState } from 'react';
// @ts-ignore;
import { Button, Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Table, TableBody, TableCell, TableHeader, TableHead, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Label, DialogFooter } from '@/components/ui';
// @ts-ignore;
import { Search, Plus, ArrowUpDown, Trash2 } from 'lucide-react';
const ExpenseTrackerApp = ({
className,
style,
$w
}) => {
const [expenses, setExpenses] = useState([]);
const [newExpense, setNewExpense] = useState({
date: '',
category: '',
amount: '',
description: ''
});
const [searchTerm, setSearchTerm] = useState('');
const [sortConfig, setSortConfig] = useState({
key: null,
direction: 'ascending'
});
const [selectedTab, setSelectedTab] = useState('management');
const handleAddExpense = () => {
if (newExpense.date && newExpense.category && newExpense.amount) {
setExpenses([...expenses, {
...newExpense,
id: Date.now()
}]);
setNewExpense({
date: '',
category: '',
amount: '',
description: ''
});
}
};
const handleDeleteExpense = id => {
setExpenses(expenses.filter(expense => expense.id !== id));
};
const handleSort = key => {
let direction = 'ascending';
if (sortConfig.key === key && sortConfig.direction === 'ascending') {
direction = 'descending';
}
setSortConfig({
key,
direction
});
};
const sortedExpenses = React.useMemo(() => {
let sortableExpenses = [...expenses];
if (sortConfig.key !== null) {
sortableExpenses.sort((a, b) => {
if (a[sortConfig.key] < b[sortConfig.key]) {
return sortConfig.direction === 'ascending' ? -1 : 1;
}
if (a[sortConfig.key] > b[sortConfig.key]) {
return sortConfig.direction === 'ascending' ? 1 : -1;
}
return 0;
});
}
return sortableExpenses;
}, [expenses, sortConfig]);
const filteredExpenses = sortedExpenses.filter(expense => expense.description.toLowerCase().includes(searchTerm.toLowerCase()) || expense.category.toLowerCase().includes(searchTerm.toLowerCase()));
const handleTabChange = tab => {
setSelectedTab(tab);
};
return <div className={`p-4 bg-gray-100 min-h-screen ${className}`} style={style}>
<h1 className="text-2xl font-bold mb-4 text-gray-800">Daily Expense Tracker</h1>
<Tabs defaultValue={selectedTab} className="mb-4">
<TabsList>
<TabsTrigger value="management">记录管理</TabsTrigger>
<TabsTrigger value="report">报表生成</TabsTrigger>
</TabsList>
<TabsContent value={selectedTab}>
{selectedTab === 'management' && <div>
<div className="mb-4 flex justify-between items-center">
<Input className="max-w-xs" placeholder="Search expenses..." value={searchTerm} onChange={e => setSearchTerm(e.target.value)} icon={<Search className="h-4 w-4 text-gray-500" />} />
<Dialog>
<DialogTrigger asChild>
<Button><Plus className="h-4 w-4 mr-2" /> Add Expense</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Add New Expense</DialogTitle>
</DialogHeader>
<div className="grid gap-4 py-4">
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="date" className="text-right">Date</Label>
<Input id="date" type="date" value={newExpense.date} onChange={e => setNewExpense({
...newExpense,
date: e.target.value
})} className="col-span-3" />
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="category" className="text-right">Category</Label>
<Select value={newExpense.category} onValueChange={value => setNewExpense({
...newExpense,
category: value
})}>
<SelectTrigger className="col-span-3">
<SelectValue placeholder="Select category" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Food">Food</SelectItem>
<SelectItem value="Transport">Transport</SelectItem>
<SelectItem value="Entertainment">Entertainment</SelectItem>
<SelectItem value="Utilities">Utilities</SelectItem>
<SelectItem value="Other">Other</SelectItem>
</SelectContent>
</Select>
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="amount" className="text-right">Amount</Label>
<Input id="amount" type="number" value={newExpense.amount} onChange={e => setNewExpense({
...newExpense,
amount: e.target.value
})} className="col-span-3" />
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="description" className="text-right">Description</Label>
<Input id="description" value={newExpense.description} onChange={e => setNewExpense({
...newExpense,
description: e.target.value
})} className="col-span-3" />
</div>
</div>
<DialogFooter>
<Button onClick={handleAddExpense}>Add Expense</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-[100px]">
<Button variant="ghost" onClick={() => handleSort('date')}>
Date <ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
</TableHead>
<TableHead>
<Button variant="ghost" onClick={() => handleSort('category')}>
Category <ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
</TableHead>
<TableHead>
<Button variant="ghost" onClick={() => handleSort('amount')}>
Amount <ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
</TableHead>
<TableHead>Description</TableHead>
<TableHead className="w-[100px]">Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{filteredExpenses.map(expense => <TableRow key={expense.id}>
<TableCell>{expense.date}</TableCell>
<TableCell>{expense.category}</TableCell>
<TableCell>${expense.amount.toFixed(2)}</TableCell>
<TableCell>{expense.description}</TableCell>
<TableCell>
<Button variant="ghost" size="icon" onClick={() => handleDeleteExpense(expense.id)}>
<Trash2 className="h-4 w-4" />
</Button>
</TableCell>
</TableRow>)}
</TableBody>
</Table>
</div>}
{selectedTab === 'report' && <div>
<h2 className="text-2xl font-bold mb-4">Expense Report</h2>
<p>Coming soon...</p>
</div>}
</TabsContent>
</Tabs>
</div>;
};
export default ExpenseTrackerApp;
🔧 步骤二:调试与优化
可以根据右边的组建和配置完成界面调整和优化。
🔧 步骤三:测试与上线
最终小程序运行流畅,可以直接配置如下信息测试发布体验。
💡 操作流畅性
Copilot 的操作流畅性令人惊艳,大多数提示都能秒级响应,生成代码逻辑清晰、可读性高。
🎁 “惊喜发现”
比如,它能自动处理云函数部署的细节,大幅减少了我查文档的时间!还有一些实用的小工具,比如自动优化 CSS 排版,这个“彩蛋”让我省了好几小时的调整时间。
📝 改进建议
Copilot 的出现,确实让开发变得更轻松、更有趣。虽然它有点“小脾气”,但瑕不掩瑜,是个极具潜力的开发助手。
最终的开发灵感、代码风格和产品完成度,仍然离不开人的智慧。毕竟,技术是人类创造力的延伸,而不是替代。
所以,别犹豫了,试试 Copilot 吧,也许会激发你的开发灵感! 😊
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。