提示词核心
以下是我目前经过多方面使用总结出来的DeepSeek前端识图最佳提示词
Markdown
角色:
你是一个前端业务组件生成专家,善于识别图片UI和根据用户的描述,生成对应的业务组件
描述:
这是一个科技大屏风格的设计图,UI布局分为header区域占满一整行,接着是左右结构占满内容区。header区域分为左侧title,右侧是一个tab切换按钮区。内容区左侧分为上下结构,上面是路况信息,下面是统计本周情况的echarts折线图;内容区右侧是一个table表格,统计路况信息。
限制:
1. 不要打破角色设定,只能回答和组件生成相关的问题
2. 不要胡言乱语,不要编造 API
3. 使用vue3+echarts+原生css实现需求
4. 使用flex布局
5. 代码生成符合solid原则
工作步骤:
1. 识别用户上传的图片,解析图片的背景色和UI风格
2. 根据用户描述和限制生成美观的UI风格和结构布局
3. 生成完整可运行的组件代码
4. 给出使用示例,告知用户如何使用
提示词核心有以下几点:
- 定角色:明确代码生成的方向
- 加描述:尽可能详细的描述设计图,包含UI风格、颜色、结构布局、字体、动画等等(一些通过figma转换输出前端页面的工具原理也是如此,figma上包含详细的数据,因此生成效果也更好)
- 给限制:按需添加限制条件,减少AI幻觉,降低输出内容错误率
- 提步骤:详细告知AI每个工作步骤,包含从开始到结束的完整过程,这一步也是越详细效果越好
实战演示
以将下图转换成组件为例
准备工作
1、访问deepseek官网,取消勾选【深度思考】【联网搜索】,则会默认使用DeepSeek-V3-0324模型(编程能力强,约等于claude3.7)
2、准备一个vue3初始化工程(vue-cli生成即可)
错误案例演示 ×
先来看个错误案例
提示词过于简单,生成效果也不理想
Markdown
帮我识别图片,使用vue3实现组件,确保100%还原UI效果
deepseek回复如下
按照回复将组件在demo项目中预览,效果如下,与实际UI差距非常大
正确案例演示 √
输入最佳实践提示词并上传图片
deepseek回复如下:
根据图片分析,这是一个科技蓝黑风格的大屏组件,采用深色背景和亮色数据展示。我将为您创建一个符合要求的Vue3组件。
组件代码
vue
<template>
<div class="dashboard-container">
<!-- Header区域 -->
<header class="dashboard-header">
<div class="header-title">公路运营运力调度</div>
<div class="header-tabs">
<button
:class="['tab-button', activeTab === 'status' ? 'active' : '']"
@click="activeTab = 'status'"
>
现况
</button>
<button
:class="['tab-button', activeTab === 'dispatch' ? 'active' : '']"
@click="activeTab = 'dispatch'"
>
调度
</button>
</div>
</header>
<!-- 内容区域 -->
<main class="dashboard-content">
<!-- 左侧内容 -->
<div class="content-left">
<!-- 今日路况 -->
<div class="today-status">
<h3 class="section-title">今日路况</h3>
<div class="status-grid">
<div class="status-item" v-for="item in todayStatus" :key="item.type">
<div class="status-value">{{ item.value }}</div>
<div class="status-label">{{ item.label }}</div>
</div>
</div>
</div>
<!-- 本周情况图表 -->
<div class="week-chart">
<h3 class="section-title">本周情况</h3>
<div class="chart-container" ref="chartRef"></div>
<div class="chart-dates">
<span v-for="date in weekDates" :key="date">{{ date }}</span>
</div>
</div>
</div>
<!-- 右侧表格 -->
<div class="content-right">
<h3 class="section-title">路况信息</h3>
<div class="table-container">
<table>
<thead>
<tr>
<th v-for="col in tableColumns" :key="col">{{ col }}</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) in tableData" :key="index">
<td>{{ row.type }}</td>
<td>{{ row.location }}</td>
<td>{{ row.weather }}</td>
<td>{{ row.impact }}</td>
<td>{{ row.flow }}</td>
<td>{{ row.change }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</main>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import * as echarts from 'echarts'
// 响应式数据
const activeTab = ref('status')
const chartRef = ref(null)
let chartInstance = null
// 今日路况数据
const todayStatus = ref([
{ value: '27.2', label: '车流拥堵' },
{ value: '31', label: '意外事故' },
{ value: '14.4', label: '路段施工' },
{ value: '10', label: '交通管制' },
{ value: '45', label: '高温热损' },
{ value: '1006', label: '暴雨台风' },
{ value: '30', label: '沙尘大雾' },
{ value: '17', label: '霜冻积雪' }
])
// 本周日期
const weekDates = ref(['10-18', '10-19', '10-20', '10-21', '10-22', '10-23', '昨日'])
// 表格数据
const tableColumns = ref(['路况类型', '交通路段', '气象预警', '影响预测', '小时流量', '车流变化'])
const tableData = ref([
{ type: '其他游区', location: '白云山', weather: '暴雨', impact: '未来3小时', flow: '1358', change: '' },
{ type: '温泉养生', location: '肇庆七星岩', weather: '高温', impact: '未来3小时', flow: '2733', change: '' },
{ type: '滨海娱乐', location: '惠州西湖', weather: '高温', impact: '未来3小时', flow: '8925', change: '' },
{ type: '主题乐园', location: '佛山祖庙', weather: '高温', impact: '未来3小时', flow: '1110', change: '' },
{ type: '乡村旅游', location: '开平碉楼', weather: '高温', impact: '未来3小时', flow: '1167', change: '' },
{ type: '自然风光', location: '丹霞山', weather: '高温', impact: '未来3小时', flow: '8805', change: '' },
{ type: '博物馆', location: '珠海长隆海洋王国', weather: '高温', impact: '未来3小时', flow: '8483', change: '' },
{ type: '人文荟萃', location: '深圳世界之窗', weather: '高温', impact: '未来3小时', flow: '2967', change: '' }
])
// 初始化图表
const initChart = () => {
if (!chartRef.value) return
chartInstance = echarts.init(chartRef.value)
const option = {
backgroundColor: 'transparent',
tooltip: {
trigger: 'axis'
},
grid: {
left: '3%',
right: '4%',
bottom: '15%',
top: '10%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
axisLine: {
lineStyle: {
color: '#4a7dbb'
}
},
axisLabel: {
color: '#fff',
fontSize: 12
},
show: false // 隐藏x轴
},
yAxis: {
type: 'value',
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
color: '#4a7dbb',
fontSize: 12
},
splitLine: {
lineStyle: {
color: 'rgba(74, 125, 187, 0.3)'
}
}
},
series: [
{
name: '温度',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 8,
lineStyle: {
width: 3,
color: '#00d8ff'
},
itemStyle: {
color: '#00d8ff',
borderColor: '#fff',
borderWidth: 2
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(0, 216, 255, 0.5)' },
{ offset: 1, color: 'rgba(0, 216, 255, 0.1)' }
])
},
data: [39, 36, 33, 30, 27, 24, 27]
}
]
}
chartInstance.setOption(option)
}
// 响应式调整图表大小
const resizeChart = () => {
if (chartInstance) {
chartInstance.resize()
}
}
// 生命周期钩子
onMounted(() => {
initChart()
window.addEventListener('resize', resizeChart)
})
onBeforeUnmount(() => {
if (chartInstance) {
chartInstance.dispose()
}
window.removeEventListener('resize', resizeChart)
})
</script>
<style scoped>
/* 基础样式 */
.dashboard-container {
width: 100%;
height: 100%;
background-color: #0a1a35;
color: #fff;
font-family: 'Arial', sans-serif;
display: flex;
flex-direction: column;
padding: 20px;
box-sizing: border-box;
}
/* Header样式 */
.dashboard-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid rgba(74, 125, 187, 0.3);
}
.header-title {
font-size: 24px;
font-weight: bold;
color: #00d8ff;
text-shadow: 0 0 10px rgba(0, 216, 255, 0.5);
}
.header-tabs {
display: flex;
gap: 15px;
}
.tab-button {
padding: 8px 20px;
background: transparent;
border: 1px solid #4a7dbb;
color: #fff;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s;
}
.tab-button.active {
background: rgba(0, 216, 255, 0.2);
border-color: #00d8ff;
color: #00d8ff;
box-shadow: 0 0 10px rgba(0, 216, 255, 0.5);
}
/* 内容区域样式 */
.dashboard-content {
display: flex;
flex: 1;
gap: 20px;
}
.content-left {
flex: 1;
display: flex;
flex-direction: column;
gap: 20px;
}
.content-right {
flex: 1;
}
.section-title {
font-size: 18px;
margin: 0 0 15px 0;
color: #00d8ff;
padding-left: 10px;
border-left: 3px solid #00d8ff;
}
/* 今日路况样式 */
.today-status {
background: rgba(16, 42, 90, 0.5);
border-radius: 8px;
padding: 15px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
}
.status-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 15px;
}
.status-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10px;
background: rgba(74, 125, 187, 0.1);
border-radius: 6px;
border: 1px solid rgba(74, 125, 187, 0.3);
}
.status-value {
font-size: 24px;
font-weight: bold;
margin-bottom: 5px;
color: #fff;
}
.status-label {
font-size: 14px;
color: #4a7dbb;
}
/* 本周图表样式 */
.week-chart {
flex: 1;
background: rgba(16, 42, 90, 0.5);
border-radius: 8px;
padding: 15px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
display: flex;
flex-direction: column;
}
.chart-container {
flex: 1;
width: 100%;
}
.chart-dates {
display: flex;
justify-content: space-between;
padding: 10px 5px 0;
color: #4a7dbb;
font-size: 12px;
}
/* 表格样式 */
.table-container {
height: 100%;
background: rgba(16, 42, 90, 0.5);
border-radius: 8px;
padding: 15px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
overflow: auto;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid rgba(74, 125, 187, 0.3);
}
th {
color: #00d8ff;
font-weight: normal;
background: rgba(16, 42, 90, 0.8);
position: sticky;
top: 0;
}
tbody tr:hover {
background: rgba(0, 216, 255, 0.1);
}
/* 响应式调整 */
@media (max-width: 1200px) {
.dashboard-content {
flex-direction: column;
}
.status-grid {
grid-template-columns: repeat(2, 1fr);
}
}
</style>
使用示例
vue
<template>
<div class="app-container">
<TrafficDashboard />
</div>
</template>
<script setup>
import TrafficDashboard from './components/TrafficDashboard.vue'
</script>
<style>
.app-container {
width: 100vw;
height: 100vh;
overflow: hidden;
}
</style>
组件说明
-
组件结构:
-
Header区域: 包含标题和两个tab切换按钮
-
内容区域: 分为左右两部分
左侧: 今日路况统计和本周温度折线图
右侧: 路况信息表格
-
-
技术特点:
- 使用Vue3的Composition API
- 集成ECharts实现折线图
- 纯CSS实现科技大屏风格
- 完全响应式设计
- 使用Flex布局
-
自定义配置:
- 可以通过修改todayStatus、tableData等响应式数据来更新内容
- 图表样式可以通过修改ECharts的option对象来调整
-
注意事项:
- 组件需要在一个固定尺寸的容器中使用(如示例中的100vw×100vh)
- 确保已安装echarts依赖: npm install echarts这个组件完美复现了您提供的设计图,并添加了适当的交互效果和响应式设计。
使用vue-cli创建一个vue3的基础工程,预览组件效果如下
可以发现生成的组件结构基本接近UI,且有一些小问题,目前任何模型都或多或少会遇到这种情况,我们只需要继续提要求让它修复即可
修复提示词(关键点:要肯定前面生成的代码没有大问题,同时提出小问题所在点)
Markdown
很好,现在右侧内容区table高度设置了100%,但缺少考虑title区域的高度,导致高度超出内容区了,请修复问题
将提示词发送给deepseek,回复如下
您指出的问题确实存在,我们需要调整右侧内容区的高度计算,确保包含标题区域后不会超出内容区。以下是修复后的代码:
vue
<template>
<!-- 其他部分保持不变... -->
<!-- 修改右侧内容区结构 -->
<div class="content-right">
<div class="table-section">
<h3 class="section-title">路况信息</h3>
<div class="table-container">
<table>
<!-- 表格内容保持不变... -->
</table>
</div>
</div>
</div>
</template>
<style scoped>
/* 修改右侧内容区样式 */
.content-right {
flex: 1;
display: flex;
flex-direction: column;
}
.table-section {
display: flex;
flex-direction: column;
height: 100%; /* 确保占据全部可用高度 */
}
.table-container {
flex: 1; /* 占据剩余空间 */
min-height: 0; /* 修复flex容器中的滚动问题 */
overflow: auto; /* 添加滚动条 */
}
/* 其他样式保持不变... */
</style>
完整修复方案
以下是完整的右侧内容区代码,确保高度计算正确:
vue
<template>
<!-- 右侧表格 -->
<div class="content-right">
<div class="table-section">
<h3 class="section-title">路况信息</h3>
<div class="table-container">
<table>
<thead>
<tr>
<th v-for="col in tableColumns" :key="col">{{ col }}</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) in tableData" :key="index">
<td>{{ row.type }}</td>
<td>{{ row.location }}</td>
<td>{{ row.weather }}</td>
<td>{{ row.impact }}</td>
<td>{{ row.flow }}</td>
<td>{{ row.change }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<style scoped>
.content-right {
flex: 1;
display: flex;
flex-direction: column;
}
.table-section {
display: flex;
flex-direction: column;
height: 100%;
background: rgba(16, 42, 90, 0.5);
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
overflow: hidden; /* 防止内部元素溢出圆角 */
}
.table-container {
flex: 1;
min-height: 0; /* 关键修复:允许flex容器内部滚动 */
overflow: auto;
padding: 0 15px 15px; /* 调整内边距 */
}
.section-title {
font-size: 18px;
margin: 0;
padding: 15px 15px 10px;
color: #00d8ff;
border-left: 3px solid #00d8ff;
background: rgba(16, 42, 90, 0.8);
position: sticky;
top: 0;
z-index: 1;
}
/* 表格样式保持不变... */
</style>
修复要点说明
-
结构调整:
- 将右侧内容区分为两层容器:table-section和table-container
- table-section负责整体高度控制和圆角等样式
- table-container负责表格内容的滚动
-
关键CSS属性:
- min-height: 0 - 解决flex容器中子元素的滚动问题
- flex: 1 - 确保容器能充分利用可用空间
- overflow: hidden - 防止内部元素溢出圆角边界
-
标题处理:
- 将标题设置为position: sticky使其固定在顶部
- 添加适当的z-index确保标题始终在表格内容之上
这样修改后,右侧内容区将正确计算高度,包含标题区域且不会超出父容器,同时保持表格内容的可滚动性。
按照给出的回复修改后,效果如下,基本没有什么太大问题,剩下的就是自己动手微调即可,后续需求可以继续追问和补充
识图生成组件代码工具对比
目前前端根据图片生成组件的最好工具我个人认为是v0,其次是claude3.7,接着是DeepSeek-V3-0324
- v0:识别图片能力顶尖,还原UI效果最好,使用提示词最简单
- claude3.7:识别图片能力一般,还原UI效果中等,使用提示词中等难度
- DeepSeek-V3-0324:识别图片能力微弱,还原UI效果取决于提示词工程,难度稍大
国产的一些大模型如豆包、通义千问等在编程领域识别图片转换代码的能力经过一段时间的使用,基本可以忽略,目前只能说期望未来吧
以下是我使用v0生成当前样例的demo,一共用了三次提示词
第一次提示
生成结果,基本还原UI布局和效果
第二次提示
生成结果,补充了按钮的交互事件,支持切换视图
第三次提示
生成结果,优化了UI效果,支持切换视图
可以看出来v0的提示词非常简单,不需要给出过多的描述和详细工作步骤就能生成效果非常好的组件代码,背后的逻辑也是预置了非常完善和规范的提示词工程。
如何编写提示词
如果你想使用其它模型来实战,但不知道怎么编写提示词,完全可以让AI来帮你做,例如:让deepseek帮忙生成标准化提示词
提示词如下:
Markdown
你是一位大模型提示词生成专家,请根据用户的需求编写一个前端组件生成智能助手的提示词,来指导大模型进行内容生成,要求:
1. 以 Markdown 格式输出
2. 贴合用户需求,描述智能助手的定位、能力、知识储备
3. 提示词应清晰、精确、易于理解,在保持质量的同时,尽可能简洁
4. 只输出提示词,不要输出多余解释
deepseek回复结果:
Markdown
## 定位
- 专业前端组件生成专家
- 设计稿转代码的AI执行引擎
- 现代Web开发规范的实施者
## 核心能力
1. **视觉解析**
- 识别设计稿布局结构(Flex/Grid/绝对定位)
- 提取颜色体系/间距系统/字体层级
- 解析交互状态(hover/active/disabled)
2. **组件识别**
- 判断组件类型(原子组件/复合组件)
- 识别UI模式(表单/导航/数据展示)
- 检测响应式断点(移动端/平板/桌面)
3. **代码生成**
- 输出React/Vue/Svelte组件
- 自动生成Tailwind CSS/SCSS样式
- 生成可配置的Props接口
- 添加语义化ARIA属性
- 符合solid原则
## 知识储备
1. **现代前端技术栈**
- React 18+/Vue 3+/Svelte 4+
- CSS Modules/Tailwind CSS/PostCSS
- TypeScript 5+/ECMAScript 2023
2. **设计系统规范**
- Material Design 3
- Apple Human Interface
- Ant Design 5.0
3. **组件库基准**
- Headless UI/Radix UI
- Chakra UI/Mantine
- Bootstrap 5
4. **跨平台适配**
- 移动端优先原则
- 容器查询实现方案
- 深色模式自动切换
## 输出要求
- 组件化:导出独立模块
- 可维护性:清晰的Props接口
- 可访问性:WAI-ARIA 1.2标准
- 性能优化:CSS原子化方案
- 响应式:基于容器查询的布局
- 类型安全:完整的TypeScript定义
通过deepseek回复的标准化提示词,再加以微调,基本可以应对当下百花齐放的各种大模型。
持续关注,保持学习,才能立于不败之地。