## 提示词工程
有了文档,接下来就是如何向 AI 准确传达意图。我们使用通义灵码 Agent,将上述文档内容作为上下文输入,明确指定框架和目录结构。
> 仔细阅读 apps/samples/src/views/language-learn/Readme.md 文档,根据文档在 apps/samples/src/views/language-learn/ 文件夹下生成 language-learn-app 的页面代码,要使用 TypeDom 前端框架参考项目下的其它页面的代码。
这种指令方式能让 AI 理解具体的业务逻辑和技术约束,而不仅仅是生成通用模板。
## 核心代码实现
AI 生成的代码通常包含完整的组件逻辑、数据结构和样式定义。虽然部分细节可能需要人工微调,但整体架构已经成型。以下是经过整理后的核心 TypeScript 代码,展示了如何利用 TypeDOM 构建这个应用。
```typescript
import {
TypeDiv,
Div,
Head,
P,
Span,
Button,
addDomClass,
removeClass,
renderClass,
} from '@type-dom/framework';
import { TdButton } from '@type-dom/ui';
export class LanguageLearnApp extends TypeDiv {
className: 'LanguageLearnApp';
appData!: AppData;
currentView: 'home' | 'lessons' | 'vocabulary' | 'quiz' = 'home';
currentLessonIndex: number = 0;
currentVocabIndex: number = 0;
quizScore: number = 0;
totalQuizQuestions: number = 0;
constructor() {
super();
this.className = 'LanguageLearnApp';
this.initializeData();
this.setupStyles();
this.renderHomeView();
}
private initializeData(): void {
this.appData = {
appName: 'Language Master',
appSubtitle: '掌握语言的艺术',
user: {
name: '学习者',
level: '初级',
streak: 5,
totalXP: 1250,
},
lessons: [
{
id: 1,
title: '基础问候语',
description: '学习日常问候和基本表达',
level: '入门',
duration: '15 分钟',
completed: false,
content: [
'Hello - 你好',
'Good morning - 早上好',
'How are you? - 你好吗?',
'Thank you - 谢谢',
'Goodbye - 再见',
],
},
{
id: 2,
title: '数字和时间',
description: '掌握数数和询问时间',
level: '入门',
duration: '20 分钟',
completed: false,
content: [
'One, Two, Three - 一、二、三',
'What time is it? - 现在几点?',
'Today - 今天',
'Tomorrow - 明天',
'Yesterday - 昨天',
],
},
{
id: 3,
title: '家庭成员',
description: '认识家庭成员的称呼',
level: '初级',
duration: '18 分钟',
completed: false,
content: [
'Father/Mother - 父亲/母亲',
'Brother/Sister - 兄弟/姐妹',
'Grandfather/Grandmother - 祖父/祖母',
'Uncle/Aunt - 叔叔/阿姨',
'Cousin - 表兄弟姐妹',
],
},
],
vocabulary: [
{
id: 1,
word: 'Hello',
translation: '你好',
pronunciation: '/həˈloʊ/',
example: 'Hello, how are you today?',
exampleTranslation: '你好,今天怎么样?',
category: '问候语',
},
{
id: 2,
word: 'Thank you',
translation: '谢谢',
pronunciation: '/θæŋk juː/',
example: 'Thank you for your help.',
exampleTranslation: '谢谢你的帮助。',
category: '礼貌用语',
},
{
id: 3,
word: 'Family',
translation: '家庭',
pronunciation: '/ˈfæməli/',
example: 'My family is very supportive.',
exampleTranslation: '我的家人很支持我。',
category: '家庭',
},
{
id: 4,
word: 'Learning',
translation: '学习',
pronunciation: '/ˈlɜːrnɪng/',
example: 'I enjoy learning new languages.',
exampleTranslation: '我喜欢学习新语言。',
category: '学习',
},
{
id: 5,
word: 'Practice',
translation: '练习',
pronunciation: '/ˈpræktɪs/',
example: 'Practice makes perfect.',
exampleTranslation: '熟能生巧。',
category: '学习',
},
],
quizQuestions: [
{
id: 1,
question: '"Hello" 的中文意思是?',
options: ['再见', '你好', '谢谢', '对不起'],
correctAnswer: 1,
explanation: '"Hello" 是最基本的英语问候语,中文意思是'你好'',
},
{
id: 2,
question: '如何用英语说'谢谢'?',
options: ['Sorry', 'Thank you', 'Goodbye', 'Please'],
correctAnswer: 1,
explanation: '"Thank you" 是表达感谢的标准英语说法',
},
{
id: 3,
question: '"Family" 的中文翻译是?',
options: ['朋友', '学校', '家庭', '工作'],
correctAnswer: 2,
explanation: '"Family" 指的是家庭成员的集合',
},
{
id: 4,
question: '早上见面时应该说什么?',
options: ['Good night', 'Good evening', 'Good morning', 'Good afternoon'],
correctAnswer: 2,
explanation: '"Good morning" 是早上见面时的标准问候语',
},
{
id: 5,
question: '如何表达'我爱你'?',
options: ['I love you', 'I like you', 'I miss you', 'I need you'],
correctAnswer: 0,
explanation: '"I love you" 是表达爱意的标准英语表达',
},
],
};
}
private setupStyles(): void {
this.setStyleObj({
fontFamily: "'Inter', 'Poppins', Arial, sans-serif",
maxWidth: '1200px',
margin: '0 auto',
padding: '20px',
backgroundColor: '#f8fafc',
minHeight: '100vh',
});
// Add CSS styles
const style = document.createElement('style');
style.textContent = `
.app-container {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.header {
background: white;
border-radius: 16px;
padding: 25px;
margin-bottom: 30px;
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
display: flex;
justify-content: space-between;
align-items: center;
}
.user-info {
display: flex;
align-items: center;
gap: 15px;
}
.avatar {
width: 50px;
height: 50px;
border-radius: 50%;
background: linear-gradient(45deg, #3498db, #27ae60);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
font-size: 20px;
}
.nav-buttons {
display: flex;
gap: 12px;
}
.nav-btn {
background: #3498db;
color: white;
border: none;
padding: 12px 20px;
border-radius: 8px;
cursor: pointer;
font-weight: 600;
transition: all 0.3s ease;
}
.nav-btn:hover {
background: #2980b9;
transform: translateY(-2px);
}
.nav-btn.active {
background: #27ae60;
}
.content-area {
background: white;
border-radius: 16px;
padding: 30px;
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
min-height: 500px;
}
.home-view {
text-align: center;
}
.welcome-section {
margin-bottom: 40px;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin: 30px 0;
}
.stat-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 25px;
border-radius: 12px;
text-align: center;
}
.stat-number {
font-size: 2.5em;
font-weight: bold;
margin: 10px 0;
}
.lesson-card,
.vocab-card {
background: #f8f9fa;
border-radius: 12px;
padding: 20px;
margin: 15px 0;
border-left: 4px solid #3498db;
transition: transform 0.2s ease;
}
.lesson-card:hover,
.vocab-card:hover {
transform: translateX(5px);
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}
.card-title {
font-size: 1.3em;
font-weight: 600;
color: #2c3e50;
margin-bottom: 10px;
}
.card-meta {
display: flex;
gap: 15px;
margin: 10px 0;
color: #7f8c8d;
font-size: 0.9em;
}
.quiz-question {
background: #f8f9fa;
padding: 25px;
border-radius: 12px;
margin: 20px 0;
}
.option-btn {
display: block;
width: 100%;
padding: 15px;
margin: 10px 0;
border: 2px solid #ddd;
border-radius: 8px;
background: white;
cursor: pointer;
text-align: left;
font-size: 1.1em;
transition: all 0.3s ease;
}
.option-btn:hover {
border-color: #3498db;
background: #e3f2fd;
}
.option-btn.selected {
border-color: #3498db;
background: #bbdefb;
}
.option-btn.correct {
border-color: #27ae60;
background: #c8e6c9;
}
.option-btn.incorrect {
border-color: #e74c3c;
background: #ffcdd2;
}
.progress-bar {
height: 12px;
background: #ecf0f1;
border-radius: 6px;
overflow: hidden;
margin: 20px 0;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #27ae60, #3498db);
transition: width 0.5s ease;
}
.action-btn {
background: linear-gradient(45deg, #3498db, #27ae60);
color: white;
border: none;
padding: 15px 30px;
border-radius: 8px;
cursor: pointer;
font-size: 1.1em;
font-weight: 600;
margin: 10px;
transition: all 0.3s ease;
}
.action-btn:hover {
transform: translateY(-3px);
box-shadow: 0 6px 20px rgba(0,0,0,0.2);
}
.badge {
display: inline-block;
padding: 5px 12px;
border-radius: 20px;
font-size: 0.8em;
font-weight: 600;
}
.badge-primary {
background: #3498db;
color: white;
}
.badge-success {
background: #27ae60;
color: white;
}
.badge-warning {
background: #f39c12;
color: white;
}
`;
document.head.appendChild(style);
}
private renderHomeView(): void {
this.currentView = 'home';
this.clearChildren();
const container = new Div({ class: 'app-container' });
// Header
container.addChild(this.createHeader());
// Content Area
const contentArea = new Div({ class: 'content-area' });
const welcomeSection = new Div({ class: 'home-view' });
welcomeSection.addChildren(
new Head({
tag: 'h1',
slot: `欢迎来到 ${this.appData.appName}`,
styleObj: {
fontSize: '2.5em',
color: '#2c3e50',
marginBottom: '15px',
},
}),
new P({
slot: this.appData.appSubtitle,
styleObj: {
fontSize: '1.2em',
color: '#7f8c8d',
marginBottom: '30px',
},
}),
new P({
slot: `你好,${this.appData.user.name}!你已经连续学习 ${this.appData.user.streak} 天了。`,
styleObj: {
fontSize: '1.1em',
color: '#27ae60',
fontWeight: '600',
},
})
);
// Stats Grid
const statsGrid = new Div({ class: 'stats-grid' });
statsGrid.addChildren(
this.createStatCard('总经验值', this.appData.user.totalXP.toString(), '🏆'),
this.createStatCard('学习天数', this.appData.user.streak.toString(), '🔥'),
this.createStatCard('课程完成', '3/15', '📚'),
this.createStatCard('词汇掌握', '25/100', '🧠')
);
welcomeSection.addChild(statsGrid);
// Quick Actions
const actions = new Div({ styleObj: { marginTop: '30px' } });
actions.addChildren(
new Button({
slot: '开始今日课程 📚',
class: 'action-btn',
onClick: () => this.renderLessonsView(),
}),
new Button({
slot: '复习词汇卡片 🃏',
class: 'action-btn',
onClick: () => this.renderVocabularyView(),
}),
new Button({
slot: '挑战小测验 🎯',
class: 'action-btn',
onClick: () => this.renderQuizView(),
})
);
welcomeSection.addChild(actions);
contentArea.addChild(welcomeSection);
container.addChild(contentArea);
if (this.isMounted) {
container.mount(this.dom);
} else {
this.addChild(container);
}
}
private createHeader(): Div {
const header = new Div({ class: 'header' });
// Logo and Title
const logoSection = new Div();
logoSection.addChildren(
new Head({
tag: 'h1',
slot: this.appData.appName,
styleObj: {
margin: 0,
color: '#2c3e50',
fontSize: '1.8em',
},
}),
new P({
slot: this.appData.user.level,
class: 'badge badge-primary',
})
);
// User Info
const userInfo = new Div({ class: 'user-info' });
userInfo.addChildren(
new Div({
class: 'avatar',
slot: this.appData.user.name.charAt(0),
}),
new Div({
slot: [
new P({
slot: this.appData.user.name,
styleObj: {
fontWeight: '600',
margin: '0 0 5px 0',
},
}),
new P({
slot: `${this.appData.user.totalXP} XP`,
styleObj: {
color: '#7f8c8d',
margin: 0,
fontSize: '0.9em',
},
}),
],
})
);
// Navigation Buttons
const navButtons = new Div({ class: 'nav-buttons' });
navButtons.addChildren(
new Button({
slot: '首页',
class: `nav-btn ${this.currentView === 'home' ? 'active' : ''}`,
onClick: () => this.renderHomeView(),
}),
new Button({
slot: '课程',
class: `nav-btn ${this.currentView === 'lessons' ? 'active' : ''}`,
onClick: () => this.renderLessonsView(),
}),
new Button({
slot: '词汇',
class: `nav-btn ${this.currentView === 'vocabulary' ? 'active' : ''}`,
onClick: () => this.renderVocabularyView(),
}),
new Button({
slot: '测验',
class: `nav-btn ${this.currentView === 'quiz' ? 'active' : ''}`,
onClick: () => this.renderQuizView(),
})
);
header.addChildren(logoSection, userInfo, navButtons);
return header;
}
private createStatCard(title: string, value: string, icon: string): Div {
const card = new Div({ class: 'stat-card' });
card.addChildren(
new Div({
slot: icon,
styleObj: {
fontSize: '2em',
marginBottom: '10px',
},
}),
new Div({ slot: value, class: 'stat-number' }),
new P({
slot: title,
styleObj: {
margin: 0,
opacity: 0.9,
},
})
);
return card;
}
private renderLessonsView(): void {
this.currentView = 'lessons';
this.clearChildren();
const container = new Div({ class: 'app-container' });
container.addChild(this.createHeader());
const contentArea = new Div({ class: 'content-area' });
contentArea.addChildren(
new Head({
tag: 'h2',
slot: '📖 我的课程',
styleObj: {
color: '#2c3e50',
marginBottom: '25px',
},
})
);
this.appData.lessons.forEach((lesson, index) => {
const lessonCard = new Div({ class: 'lesson-card' });
lessonCard.addChildren(
new Div({
class: 'card-title',
slot: `${index + 1}. ${lesson.title}`,
}),
new P({
slot: lesson.description,
styleObj: {
color: '#7f8c8d',
marginBottom: '15px',
},
}),
new Div({
class: 'card-meta',
slot: [
new Span({
slot: `⏱️ ${lesson.duration}`,
class: 'badge badge-warning',
}),
new Span({
slot: `📊 ${lesson.level}`,
class: 'badge badge-primary',
}),
new Span({
slot: lesson.completed ? '✅ 已完成' : '⏳ 未开始',
class: `badge ${lesson.completed ? 'badge-success' : 'badge-warning'}`,
}),
],
}),
new Button({
slot: lesson.completed ? '复习课程' : '开始学习',
class: 'action-btn',
styleObj: { marginTop: '15px' },
onClick: () => this.startLesson(index),
})
);
contentArea.addChild(lessonCard);
});
container.addChild(contentArea);
container.mount(this.dom);
}
private renderVocabularyView(): void {
this.currentView = 'vocabulary';
this.clearChildren();
const container = new Div({ class: 'app-container' });
container.addChild(this.createHeader());
const contentArea = new Div({ class: 'content-area' });
contentArea.addChildren(
new Head({
tag: 'h2',
slot: '🃏 词汇卡片',
styleObj: {
color: '#2c3e50',
marginBottom: '25px',
},
})
);
this.appData.vocabulary.forEach((vocab, index) => {
const vocabCard = new Div({ class: 'vocab-card' });
vocabCard.addChildren(
new Div({ class: 'card-title', slot: vocab.word }),
new P({
slot: `/${vocab.pronunciation}/`,
styleObj: {
fontStyle: 'italic',
color: '#7f8c8d',
},
}),
new P({
slot: vocab.translation,
styleObj: {
fontSize: '1.2em',
fontWeight: '600',
color: '#27ae60',
},
}),
new P({
slot: `分类:${vocab.category}`,
class: 'badge badge-primary',
styleObj: { marginTop: '10px' },
}),
new Div({
styleObj: { marginTop: '15px' },
slot: [
new P({
slot: `例句:${vocab.example}`,
styleObj: {
fontStyle: 'italic',
color: '#555',
},
}),
new P({
slot: vocab.exampleTranslation,
styleObj: {
color: '#7f8c8d',
marginTop: '5px',
},
}),
],
})
);
contentArea.addChild(vocabCard);
});
container.addChild(contentArea);
container.mount(this.dom);
}
private renderQuizView(): void {
console.log('renderQuizView');
this.currentView = 'quiz';
this.quizScore = 0;
this.totalQuizQuestions = this.appData.quizQuestions.length;
this.clearChildren();
const container = new Div({ class: 'app-container' });
container.addChild(this.createHeader());
const contentArea = new Div({ class: 'content-area' });
contentArea.addChildren(
new Head({
tag: 'h2',
slot: '🎯 语言测验',
styleObj: {
color: '#2c3e50',
marginBottom: '25px',
},
}),
new P({
slot: '测试你的语言掌握程度!',
styleObj: {
fontSize: '1.1em',
color: '#7f8c8d',
marginBottom: '20px',
},
})
);
const startButton = new Button({
slot: '开始测验',
class: 'action-btn',
onClick: () => this.startQuiz(),
});
contentArea.addChild(startButton);
container.addChild(contentArea);
this.addChild(container);
container.mount(this.dom);
}
private startLesson(index: number): void {
alert(`开始学习课程:${this.appData.lessons[index].title} 内容预览:${this.appData.lessons[index].content.join('')}`);
// 这里可以跳转到具体的课程详情页面
}
private startQuiz(): void {
this.currentView = 'quiz';
let currentQuestionIndex = 0;
let selectedAnswer: number | null = null;
const showQuestion = () => {
this.clearChildren();
const container = new Div({ class: 'app-container' });
container.addChild(this.createHeader());
const contentArea = new Div({ class: 'content-area' });
// Progress bar
const progressPercent = ((currentQuestionIndex) / this.totalQuizQuestions) * 100;
const progressBar = new Div({ class: 'progress-bar' });
progressBar.addChild(
new Div({
class: 'progress-fill',
styleObj: {
width: `${progressPercent}%`,
},
})
);
contentArea.addChildren(
new P({
slot: `题目 ${currentQuestionIndex + 1} / ${this.totalQuizQuestions}`,
styleObj: {
textAlign: 'center',
color: '#7f8c8d',
marginBottom: '10px',
},
}),
progressBar
);
const question = this.appData.quizQuestions[currentQuestionIndex];
const questionDiv = new Div({ class: 'quiz-question' });
questionDiv.addChildren(
new Head({
tag: 'h3',
slot: question.question,
styleObj: {
color: '#2c3e50',
marginBottom: '20px',
},
})
);
const optionsDiv = new Div();
question.options.forEach((option, index) => {
const optionBtn = new Button({
slot: `${String.fromCharCode(65 + index)}. ${option}`,
class: 'option-btn',
onClick: () => {
// Remove previous selections
const allButtons = optionsDiv.children as Button[];
allButtons.forEach((btn) => {
// btn.removeClass('selected');
removeClass(btn, 'selected');
});
// Select current option
// optionBtn.addClass('selected');
renderClass(optionBtn, 'selected');
selectedAnswer = index;
},
});
optionsDiv.addChild(optionBtn);
});
questionDiv.addChild(optionsDiv);
const submitButton = new Button({
slot: '提交答案',
class: 'action-btn',
onClick: () => {
console.log('提交答案');
if (selectedAnswer === null) {
alert('请选择一个答案!');
return;
}
// Show result
const allButtons = optionsDiv.children as Button[];
allButtons.forEach((btn, idx) => {
if (idx === question.correctAnswer) {
// btn.addClass('correct');
addDomClass(btn.dom, 'correct');
} else if (idx === selectedAnswer && selectedAnswer !== question.correctAnswer) {
// btn.addClass('incorrect');
addDomClass(btn.dom, 'incorrect');
}
});
setTimeout(() => {
if (selectedAnswer === question.correctAnswer) {
this.quizScore++;
alert(`🎉 回答正确!\n\n解析:${question.explanation}`);
} else {
alert(`❌ 回答错误!\n\n正确答案:${question.options[question.correctAnswer]}\n解析:${question.explanation}`);
}
currentQuestionIndex++;
selectedAnswer = null;
if (currentQuestionIndex < this.totalQuizQuestions) {
showQuestion();
} else {
this.showQuizResults();
}
}, 1500);
},
});
questionDiv.addChild(submitButton);
contentArea.addChild(questionDiv);
container.addChild(contentArea);
container.mount(this.dom);
};
showQuestion();
}
private showQuizResults(): void {
this.clearChildren();
const container = new Div({ class: 'app-container' });
container.addChild(this.createHeader());
const contentArea = new Div({
class: 'content-area',
styleObj: { textAlign: 'center' },
});
const scorePercent = Math.round((this.quizScore / this.totalQuizQuestions) * 100);
let resultMessage = '';
let resultEmoji = '';
if (scorePercent >= 90) {
resultMessage = '优秀!你是语言天才!';
resultEmoji = '🌟';
} else if (scorePercent >= 70) {
resultMessage = '很好!继续保持!';
resultEmoji = '👍';
} else if (scorePercent >= 50) {
resultMessage = '不错!还有进步空间!';
resultEmoji = '💪';
} else {
resultMessage = '继续努力!多加练习!';
resultEmoji = '📚';
}
contentArea.addChildren(
new Head({
tag: 'h2',
slot: '测验结果',
styleObj: {
color: '#2c3e50',
marginBottom: '30px',
},
}),
new Div({
slot: resultEmoji,
styleObj: {
fontSize: '4em',
marginBottom: '20px',
},
}),
new Head({
tag: 'h1',
slot: `${this.quizScore}/${this.totalQuizQuestions}`,
styleObj: {
fontSize: '3em',
color: '#27ae60',
margin: '20px 0',
},
}),
new P({
slot: `得分率:${scorePercent}%`,
styleObj: {
fontSize: '1.5em',
color: '#7f8c8d',
marginBottom: '30px',
},
}),
new P({
slot: resultMessage,
styleObj: {
fontSize: '1.3em',
color: '#2c3e50',
marginBottom: '30px',
},
}),
new TdButton({
slot: '返回首页',
type: 'primary',
onClick: () => this.renderHomeView(),
})
);
container.addChild(contentArea);
container.mount(this.dom);
}
}
// Data interfaces
interface AppData {
appName: string;
appSubtitle: string;
user: User;
lessons: Lesson[];
vocabulary: VocabularyItem[];
quizQuestions: QuizQuestion[];
}
interface User {
name: string;
level: string;
streak: number;
totalXP: number;
}
interface Lesson {
id: number;
title: string;
description: string;
level: string;
duration: string;
completed: boolean;
content: string[];
}
interface VocabularyItem {
id: number;
word: string;
translation: string;
pronunciation: string;
example: string;
exampleTranslation: string;
category: string;
}
interface QuizQuestion {
id: number;
question: string;
options: string[];
correctAnswer: number;
explanation: string;
}