【震撼】🎉用字节全家桶手把手打造你的专属智能笔记平台

什么是字节全家桶?

这节我们使用字节全家桶进行开发一个笔记平台

什么是字节全家桶呢?,大概也就是我们我们所有使用的组件都跟都使用字节开发, 使用的UI 组件、编辑器,样式,全部使用字节开源的产品 大概如下:

字节全家桶:

其实你写文章的时候点击这里就可以跳转开源的地址到开源的MD编辑器:

上次我们用trae AI 完成了 一个接口调试工具,这次我们依旧使用trae AI 整一个笔记平台效果如下:

项目需求设计

这个章节,我们还是老规矩,首先第一步使用 trae AI 完成项目需求的设计

官网地址: www.trae.com.cn/

那么有了上次和大家开发的那个工具的经验后,我们这次就很行云流水了,首先我们使用trae AI的 Chat AI 模型

注意: 注意这里在我们的需求设计阶段,我们一定要使用DeepSeek-V3-0324 虽然这个模型不支持图片,但是可以很好的理解和实现我们的需求,这个模型对中文的理解非常强,适合用于需求的分析,但是编码能力比Gemini2.5 Pro和 克劳德3.5、3.7 差很多,个人日常使用下来的感受哈

  • 提示词

    你是一个专业且资深的产品工程师,
    现在我需要使用Vue3+Vite构建一个笔记网站,
    请你帮我进行详细的需求设计,我的要求是轻量级,并且你可以列出具体的功能详细列表

可以看到生成的速度非常的快!!!! very Good!

md 复制代码
# 轻量级笔记网站需求分析

## 技术栈
- 前端框架: Vue 3 + Composition API
- 构建工具: Vite
- UI组件: 原生HTML/CSS (保持轻量)
- 状态管理: Pinia (轻量替代Vuex)
- 路由: Vue Router
- 本地存储: localStorage (无需后端)

## 核心功能

### 1. 笔记管理
- 创建/编辑/删除笔记
- Markdown格式支持
- 自动保存功能
- 笔记分类/标签系统

### 2. 界面功能
- 响应式布局(适配PC/移动端)
- 暗黑/明亮主题切换
- 简洁的侧边栏导航
- 笔记列表缩略图展示

### 3. 搜索与过滤
- 实时全文搜索
- 按标签/分类过滤
- 最近编辑笔记排序

### 4. 数据管理
- 本地数据导入/导出(JSON格式)
- 笔记备份功能
- 数据统计(字数统计等)

## 详细功能清单

### 笔记编辑功能
| 功能点 | 描述 | 优先级 |
|-------|------|--------|
| 富文本编辑 | 支持Markdown语法高亮 | P0 |
| 图片粘贴 | 支持直接粘贴图片 | P1 |
| 代码块 | 支持代码高亮 | P0 |
| 数学公式 | 支持LaTeX公式渲染 | P2 |

### 用户界面
| 功能点 | 描述 | 优先级 |
|-------|------|--------|
| 主题切换 | 明亮/暗黑模式 | P0 |
| 布局调整 | 可调整编辑区/预览区比例 | P1 |
| 快捷键 | 常用操作快捷键支持 | P1 |

### 数据安全
| 功能点 | 描述 | 优先级 |
|-------|------|--------|
| 自动备份 | 定时自动保存到本地 | P0 |
| 版本历史 | 保留最近5次编辑记录 | P2 |
| 数据恢复 | 从备份文件恢复数据 | P1 |

## 非功能性需求
1. 性能要求:
   - 页面加载时间 < 1s
   - 笔记切换响应时间 < 300ms

2. 兼容性:
   - 支持Chrome/Firefox/Edge最新版
   - 移动端Safari/Chrome基础功能支持

3. 可维护性:
   - 清晰的组件结构
   - 完善的TypeScript类型定义

根据大家的喜好,自行调整哈,这个需求分析什么时候才算是完善呢?就是你自己可以多读几遍,换位思考一下,这个是否足够完善,或者也有让Trae AI 帮你检查一下

复制代码
作为一个资深的产品经理,你认为这个需求设计的咋样,
请你优化下,使其更加的完善

完善后的(就不贴了,搭建可以自行试试,防止说我水文章):

脚手架搭建

上节,我们完成了需求的概要设计,这个章节我们主要核心是脚手架搭建,先将架子搭建起来,看下最终效果,这样能极大的增强我们的自信心,就像游戏一样,总得看到成果,不然没兴趣整了,哈哈哈

顺便说下,编码使用Gemini Pro这个模型真的很提效,因为它能自动分析你当前的环境,给你举个例子:

比如检测你的Node 环境不对,他会思考他会被动的给你切换,这一点是我没有想到的,虽然Cursor也有,但是在国产的AI IDE 还是很舒服

大功告成,搭建完成!

项目开发

你就将这项目文件夹和需求文档设计丢给他,让他实现就行

我们可以从下方的代码片段看一下AI生成的质量,非常的优秀!,赶上初级程序员了

js 复制代码
<template>
  <div class="note-list-container">
    <div class="note-list-header">
      <a-input-search
        v-model="searchText"
        placeholder="搜索笔记标题或内容"
        allow-clear
      />
      <a-tooltip content="创建新笔记">
        <a-button type="primary" shape="circle" @click="handleCreateNote">
          <template #icon><icon-plus /></template>
        </a-button>
      </a-tooltip>
    </div>
    
    <div class="note-list-content">
      <a-empty v-if="filteredNotes.length === 0" description="暂无笔记,点击右上角+创建吧!">
        <template #image>
          <icon-file size="50" />
        </template>
      </a-empty>
      
      <a-list v-else>
        <transition-group name="note-item">
          <a-list-item
            v-for="note in filteredNotes"
            :key="note.id"
            :class="{ 'note-selected': currentNoteId === note.id }"
            @click="handleSelectNote(note.id)"
            class="note-item"
          >
            <a-list-item-meta>
              <template #title>
                <div class="note-title">{{ note.title || '无标题笔记' }}</div>
              </template>
              <template #description>
                <div class="note-meta">
                  <span class="note-date">{{ formatDate(note.updatedAt) }}</span>
                  <span class="note-preview" v-if="note.content">{{ getContentPreview(note.content) }}</span>
                </div>
              </template>
            </a-list-item-meta>
            
            <template #actions>
              <a-tooltip content="删除笔记">
                <a-button
                  type="text"
                  status="danger"
                  shape="circle"
                  @click.stop="openDeleteModal(note.id, note.title)"
                  class="delete-btn"
                >
                  <template #icon><icon-delete /></template>
                </a-button>
              </a-tooltip>
            </template>
          </a-list-item>
        </transition-group>
      </a-list>
    </div>
    
    <!-- 删除确认对话框 -->
    <DeleteConfirmModal
      :visible="deleteModalVisible"
      :noteTitle="noteToDeleteTitle"
      @confirm="confirmDelete"
      @cancel="cancelDelete"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { Note } from '../types';
import { formatDate } from '../services/noteService';
import DeleteConfirmModal from './DeleteConfirmModal.vue';

const props = defineProps<{
  notes: Note[];
  currentNoteId: string | null;
}>();

const emit = defineEmits<{
  (e: 'select', id: string): void;
  (e: 'create'): void;
  (e: 'delete', id: string): void;
}>();

const searchText = ref('');
const deleteModalVisible = ref(false);
const noteToDeleteId = ref('');
const noteToDeleteTitle = ref('');

// 过滤笔记列表
const filteredNotes = computed(() => {
  if (!searchText.value) return props.notes;
  
  const keyword = searchText.value.toLowerCase();
  return props.notes.filter(note => 
    note.title.toLowerCase().includes(keyword) ||
    note.content.toLowerCase().includes(keyword)
  );
});

// 获取内容预览
const getContentPreview = (content: string) => {
  // 移除Markdown语法,只保留纯文本
  const plainText = content
    .replace(/#{1,6}\s+/g, '') // 移除标题标记
    .replace(/\*\*(.+?)\*\*/g, '$1') // 移除粗体标记
    .replace(/\*(.+?)\*/g, '$1') // 移除斜体标记
    .replace(/\[(.+?)\]\(.+?\)/g, '$1') // 移除链接标记
    .replace(/```[\s\S]*?```/g, '') // 移除代码块
    .replace(/`(.+?)`/g, '$1') // 移除行内代码
    .trim();
  
  return plainText.length > 50 ? plainText.slice(0, 50) + '...' : plainText;
};

// 选择笔记
const handleSelectNote = (id: string) => {
  emit('select', id);
};

// 创建笔记
const handleCreateNote = () => {
  emit('create');
};

// 打开删除确认对话框
const openDeleteModal = (id: string, title: string) => {
  noteToDeleteId.value = id;
  noteToDeleteTitle.value = title || '无标题笔记';
  deleteModalVisible.value = true;
};

// 确认删除
const confirmDelete = () => {
  emit('delete', noteToDeleteId.value);
  deleteModalVisible.value = false;
};

// 取消删除
const cancelDelete = () => {
  deleteModalVisible.value = false;
};
</script>

<style scoped>
.note-list-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  border-right: 1px solid var(--color-border);
  box-shadow: inset -1px 0 0 rgba(0, 0, 0, 0.05);
}

.note-list-header {
  padding: 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid var(--color-border);
  background-color: var(--color-bg);
  z-index: 1;
}

.note-list-content {
  flex: 1;
  overflow-y: auto;
  padding: 0;
  scrollbar-width: thin;
  scrollbar-color: var(--color-text-3) transparent;
}

.note-list-content::-webkit-scrollbar {
  width: 6px;
}

.note-list-content::-webkit-scrollbar-thumb {
  background-color: var(--color-text-3);
  border-radius: 3px;
}

.note-list-content::-webkit-scrollbar-track {
  background-color: transparent;
}

.note-item {
  transition: all 0.2s ease;
  border-left: 3px solid transparent;
  position: relative;
}

.note-selected {
  background-color: var(--color-fill-2);
  border-left: 3px solid var(--color-primary);
}

.note-title {
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 4px;
}

.note-meta {
  display: flex;
  flex-direction: column;
  line-height: 1.4;
}

.note-date {
  font-size: 0.75rem;
  color: var(--color-text-3);
}

.note-preview {
  color: var(--color-text-3);
  font-size: 0.8rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.delete-btn {
  opacity: 0.7;
  transition: opacity 0.2s;
}

.delete-btn:hover {
  opacity: 1;
}

:deep(.arco-list-item) {
  padding: 12px 16px;
  cursor: pointer;
  transition: background-color 0.2s;
}

:deep(.arco-list-item:hover) {
  background-color: var(--color-fill-1);
}

:deep(.arco-input-search) {
  width: 70%;
}

/* 动画效果 */
.note-item-enter-active,
.note-item-leave-active {
  transition: all 0.3s ease;
}

.note-item-enter-from,
.note-item-leave-to {
  opacity: 0;
  transform: translateY(20px);
}

.note-item-move {
  transition: transform 0.3s ease;
}

@media (max-width: 768px) {
  .note-list-header {
    padding: 12px;
  }
  
  :deep(.arco-input-search) {
    width: 65%;
  }
}
</style> 

我们先不去启动,在让他优化下,顺便大家可以把这个编辑器告诉Trae ,这样它开发的时候,就会使用这个markdown编辑器 github.com/pd4d10/byte...

这块体验不太好,首先它需要去查看,我等了大概2分钟,思考过程比较久,可能是代码太长的原因导致的,不过影响不大

等待片刻,当你看到下方情况,请你爽不爽,咱们打工就跟老板一样,只需要选择是否接受某个片段就行,哈哈哈哈!

接下来,我们启动一下

手机端展示

电脑端展示

一口气直接响应式,猛猛的!

项目美化

接下来,我们在优化下,我感觉项目优化下还是太丑了,沟通式编程开始

让我们来看看最终美化UI的效果:

手机端

电脑端

接下来我们继续优化下 加入更换皮肤的效果,让笔记更加的牛批,我们在加入一个更换皮肤的按钮 我感觉跟大多数一样,当我们使用AI 开发出了一个简单基本的demo,真就想慢慢的给他堆更多的功能,就像是自己的崽一样,想给他更多的爱,哈哈哈!

接下来,我们逐步来,不要急

接下来我们看下效果:

出现BUG了!!! 点击没反应,我们F12,看下控制台是否有报错,它喵的,算了直接让AI来吧

解决了!

发现了是变没有创建!好像CSS 变量的问题

效果展示

接下来,我们来展示吧效果吧

PC端展示

  • 自然主题
  • 赛博朋克
  • 复古朋克

手机端展示

结尾

说实话,这两天周末去用Trae AI 开发的过程中,最大的感受是 两个字 震撼 难以想象未来 克劳德、GPT 到 6 7 版本的时候,互联网会变成什么样子 打字打得我手都算了,写文章也挺费时间,不知不觉天都黑了,哈哈, 谢谢大家看到这里

相关推荐
卸任8 小时前
Vibe coding工具使用心得
前端·ai编程
brien98 小时前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance9 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M9 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写9 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李9 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易9 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
风骏时光牛马9 小时前
前沿视界
前端
kyriewen9 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易10 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员