50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | NotesApp(便签笔记组件)

📅 我们继续 50 个小项目挑战!—— NotesApp组件

仓库地址:https://github.com/SunACong/50-vue-projects

项目预览地址:https://50-vue-projects.vercel.app/。

在这里插入图片描述

使用 Vue 3 的 Composition API 搭配 TailwindCSSmarked 库,构建一个支持 Markdown 渲染的笔记应用。该应用允许用户添加、编辑、删除笔记,并且内容会自动保存到 localStorage 中。每个笔记支持实时 Markdown 预览,提供良好的交互体验。


🎯 应用目标

  • 支持创建多个笔记卡片
  • 每个笔记可切换“编辑”与“预览”模式
  • 实时渲染 Markdown 内容
  • 支持删除笔记
  • 自动保存内容到 localStorage
  • 使用 Vue 3 Composition API 管理状态
  • 使用 TailwindCSS 快速构建响应式 UI

⚙️ 技术实现点

技术点描述
Vue 3 <script setup>使用 reactive 管理笔记数组和状态
watchEffect监听数据变化并自动保存到 localStorage
marked渲染 Markdown 内容为 HTML
v-html 指令插入渲染后的 HTML 内容
TailwindCSS快速构建响应式布局和样式
自定义方法实现添加、删除、编辑、切换模式等操作

🧱 组件实现

模板结构 <template>

<template><!-- 顶部固定的添加按钮 --><div class="fixed top-4 right-4 z-50"><button@click="addNote"class="rounded bg-lime-500 px-4 py-2 text-white shadow transition hover:bg-lime-600 active:scale-95"><i class="fas fa-plus mr-2"></i>添加笔记</button></div><div class="flex flex-wrap p-16"><divv-for="(note, index) in notes":key="index"class="m-6 flex h-[400px] w-[400px] flex-col overflow-y-auto bg-white shadow-lg"><!-- 工具栏 --><div class="flex justify-end bg-lime-500 p-2"><button class="ml-2 text-lg text-white" @click="toggleEdit(index)"><i class="fas fa-edit"></i></button><button class="ml-2 text-lg text-white" @click="deleteNote(index)"><i class="fas fa-trash-alt"></i></button></div><!-- Markdown 预览 --><divv-if="!note.editing"class="prose prose-sm max-w-none p-5"v-html="renderMarkdown(note.text)"></div><!-- 编辑器 --><textareav-elsev-model="note.text"@input="updateNote(index)"class="w-full flex-1 resize-none border-none p-5 font-sans text-base outline-none"></textarea></div></div>
</template>

模板结构清晰地划分了笔记卡片的各个部分:工具栏、Markdown 预览和编辑器。通过 v-if 控制显示预览或编辑状态。


脚本逻辑 <script setup>

<script setup>
import { reactive, watchEffect } from 'vue'
import { marked } from 'marked'// 初始化:从 localStorage 读取
const notes = reactive(JSON.parse(localStorage.getItem('notes') || '[]').map((text) => ({text,editing: false,}))
)// 渲染 Markdown 文本
const renderMarkdown = (text) => {return marked(text)
}// 添加新笔记
const addNote = () => {notes.push({text: '',editing: true,})
}// 删除笔记
const deleteNote = (index) => {notes.splice(index, 1)
}// 切换编辑/展示模式
const toggleEdit = (index) => {notes[index].editing = !notes[index].editing
}// 更新笔记内容(仅用于触发保存)
const updateNote = (index) => {// 此处无需手动更新 rendered,展示时直接调用 renderMarkdown 函数
}// 自动保存笔记内容到 localStorage
watchEffect(() => {localStorage.setItem('notes', JSON.stringify(notes.map((n) => n.text)))
})
</script>

该脚本使用 reactive 管理笔记数组,并通过 watchEffect 监听数据变化,将内容自动保存至 localStorage。使用 marked 将 Markdown 转换为 HTML 并通过 v-html 渲染。


样式部分(TailwindCSS)

本组件完全依赖 TailwindCSS 来构建美观的界面和交互体验。以下是关键类及其作用:

🎨 TailwindCSS 样式重点讲解
类名作用
fixed, top-4, right-4, z-50固定在右上角的添加按钮
bg-lime-500, text-white, hover:bg-lime-600按钮的背景色、悬停效果
transition, active:scale-95添加按钮的动画反馈
flex, flex-wrap, p-16布局容器,支持响应式排版
m-6, h-[400px], w-[400px]每个笔记卡片的大小和间距
overflow-y-auto支持滚动查看长内容
bg-white, shadow-lg卡片背景和阴影效果
bg-lime-500, p-2工具栏背景和内边距
text-lg, text-white图标按钮的样式
v-html 渲染区:prose, prose-sm, max-w-none使用 Tailwind 的 prose 类美化 Markdown 渲染结果
textarea 区域:resize-none, border-none, outline-none移除默认边框和调整大小功能,提升编辑体验

这些 TailwindCSS 类构建出一个现代、美观、响应式的笔记应用。


🔍 关键功能解析

✅ Markdown 实时渲染

使用 marked 库将用户输入的 Markdown 文本即时转换为 HTML,并通过 v-html 指令插入 DOM。这种方式简单高效,适合小型 Markdown 编辑器。

💾 自动保存机制

通过 watchEffect 监听 notes 数组的变化,自动将内容保存到 localStorage,确保用户数据不会丢失。

✏️ 编辑与预览切换

通过 editing 状态切换,用户可以在编辑器和 Markdown 预览之间自由切换,提升交互体验。

🗑️ 删除功能

每个笔记卡片都提供删除按钮,点击后将从 notes 数组中移除该项,同时自动更新 localStorage


📁 常量定义 + 组件路由

constants/index.js 添加组件预览常量:

{id: 33,title: 'Notes App',image: 'https://50projects50days.com/img/projects-img/33-notes-app.png',link: 'NotesApp',},

router/index.js 中添加路由选项:

{path: '/NotesApp',name: 'NotesApp',component: () => import('@/projects/NotesApp.vue'),},

🏁 总结

通过这篇文章,我们使用 Vue 3 Composition API、TailwindCSS 和 marked 构建了一个功能完善的 Markdown 笔记应用。它不仅支持添加、编辑、删除笔记,还能自动保存内容,并实时渲染 Markdown。该应用结构清晰,易于扩展,是一个非常适合初学者和进阶者学习的项目。

  • ✅ 支持导出为 Markdown 文件,将当前笔记导出为 .md 文件下载。
  • ✅ 根据关键词搜索笔记内容。
  • ✅ 允许用户通过拖拽重新排列笔记顺序。
  • ✅ 支持暗色/亮色主题切换。

👉 下一篇,我们将完成NoteApp组件,实现了小便签笔记的组件,可以对便签增删改查,支持MarkDown语法解析。🚀

感谢阅读,欢迎点赞、收藏和分享 😊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/90098.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/90098.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于JAVA实现基于“obj--html--pdf” 的PDF格式文本生成

背景&#xff1a;因一个特定的项目需要&#xff0c;将java对象内容以特定样式的PDF格式输出&#xff0c;查看了很多文档&#xff0c;有收费的、免费的、基础集成的。收费的工具就表现突出&#xff0c;免费的工具基本很难满足需求&#xff0c;故着手采用基础集成方案。过程中尝试…

Laravel 静态方法的合理使用考量【超详细】

Laravel 静态方法的合理使用考量 在 Laravel 开发中&#xff0c;静态方法的使用需要谨慎权衡。本文将从多个维度分析静态方法的适用场景与注意事项&#xff0c;帮助开发者在保持代码简洁性的同时&#xff0c;确保可维护性和可测试性。 一、静态方法的本质与特性 静态方法属于类…

在本地127.0.0.1上跨实例访问远程数据库

1.确保可以和远程目标库连接通畅2.确保开启了sqlserver的TCP/IP3.创建LInked server-------先删除掉已存在的Remote203 IF EXISTS (SELECT 1 FROM sys.servers WHERE name Remote203) BEGINEXEC sp_dropserver Remote203, droplogins; END GO ------------创建链接 EXEC sp_ad…

Freemarker实现下载word可能遇到的问题

73万字的Java面试题库【全网最详细-找工作/实习必备神器】&#xff1a; https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzE5MTY1NzczOA&actiongetalbum&album_id4057608455186808839 Java面试题库ps&#xff1a;网上面试题多而杂&#xff0c;自己整理了一套面试题&a…

涉及海量数据的查询SQL建议使用“数据库函数”封装并调用

一、问题描述生产环境中&#xff0c;核心业务表数据量随业务增长迅速膨胀&#xff0c;原统计查询SQL因执行计划劣化、索引失效而突然变慢。若按传统流程修复&#xff0c;需要优化SQL、测试、重新打包、发版&#xff0c;并且SQL优化往往需要多轮迭代、持续打磨&#xff1b;若每次…

OBLoader和OBDumper导数工具介绍

OBLoader和OBDumper导数工具介绍使用指南产品功能使用须知使用示例旁路导入性能调优导入性能优化导出性能优化数据处理控制文件预处理函数条件表达式注意事项使用指南 产品功能 &#x1f418; OBLOADER是什么&#xff1a; Java语言开发的客户端工具&#xff0c;仅适用于Ocea…

Jenkins+Docker+Git实现自动化CI/CD

你是否还在手动构建、测试、部署过程中频繁等待&#xff1f;或者担心“我本地没问题&#xff0c;部署却报错”&#xff1f;在敏捷开发和 DevOps 时代&#xff0c;**持续集成与持续交付&#xff08;CI/CD&#xff09;**变得至关重要。将 Jenkins、Docker、Git 三者结合&#xff…

Apache Ignite 的 SQL 功能和分布式查询机制

这段内容讲的是 Apache Ignite 的 SQL 功能和分布式查询机制。我们可以从几个关键点来理解&#xff1a;一、Ignite 是一个分布式 SQL 数据库 ✅ 特点&#xff1a; 符合 ANSI-99 SQL 标准水平扩展&#xff08;可扩展到多个节点&#xff09;容错&#xff08;fault-tolerant&#…

C++中的deque容器

deque容器基本概念功能&#xff1a;双端数组&#xff0c;可以对头端进行插入和删除操作deque与vector区别&#xff1a;vector对于头部的插入删除掉率低&#xff0c;数据量越大&#xff0c;效率越低deque相对而言&#xff0c;对头部的插入删除速度会比vector快vetcor访问元素时的…

闲庭信步使用图像验证平台加速FPGA的开发:第三十课——车牌识别的FPGA实现(2)实现车牌定位

&#xff08;本系列只需要modelsim即可完成数字图像的处理&#xff0c;每个工程都搭建了全自动化的仿真环境&#xff0c;只需要双击top_tb.bat文件就可以完成整个的仿真&#xff0c;大大降低了初学者的门槛&#xff01;&#xff01;&#xff01;&#xff01;如需要该系列的工程…

前端性能优化:从“龟速“到“闪电“的终极加速指南

一、性能指标:你的网站"体检报告" 📊 1. 核心Web指标(Google排名因素) 指标 全称 优秀标准 优化方向 LCP 最大内容绘制 ≤2.5s 关键资源预加载 FID 首次输入延迟 ≤100ms 减少长任务 CLS 累计布局偏移 ≤0.1 预留图片尺寸 测量方法: // 使用web-vitals库测量…

Linux 重定向和缓冲区

序言&#xff1a; 前面在Linux 基础文件IO操作-CSDN博客这篇博客里说了很多函数无论是在语言层还是在系统调用的方面。在调用系统调用open的时候会返回一个整型&#xff0c;在write传参的时候第一个参数是一个叫fd的东西&#xff0c;这个是什么东西&#xff1f;这篇博客会详细…

web登录页面

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>简易登录页面</title><style>* {mar…

Java中关于线程池的解析

引语在学习了线程与多线程的相关知识后&#xff0c;我们已经能够实现在程序中使多个任务并行&#xff0c;但是我们在操作时候&#xff0c;往往每执行一个的任务就需要创建一个新的线程。这种方式在需要执行任务很多时不利于我们对线程的管理&#xff0c;且创建过多线程也非常占…

J2EE模式---前端控制器模式

前端控制器模式基础概念前端控制器模式&#xff08;Front Controller Pattern&#xff09;是一种结构型设计模式&#xff0c;其核心思想是将应用程序的所有请求集中到一个中央处理器&#xff08;前端控制器&#xff09;进行处理&#xff0c;由它负责接收请求、协调处理流程并返…

模块加载、ES、TS、Babel 浅析

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…

day056-Dockerfile案例与Docker Compose

文章目录0. 老男孩思想-老男孩名言警句1. Dockerfile指令&#xff1a;ENV与ARG的区别&#xff1f;2. 创建WordPress镜像2.1 CA证书2.1.1 客户端访问HTTPS站点&#xff08;阿里云镜像源&#xff09;过程2.1.2 查看Windows的CA证书2.1.3 ubuntu查看CA证书是否安装2.2 准备apt下载…

gcc 源码分析:从IR-RTL 到汇编输出

在完成了IR-RTL的优化与寄存器分配后就来到汇编代码的输出&#xff1a;实现如下&#xff1a;class pass_final : public rtl_opt_pass { public:pass_final (gcc::context *ctxt): rtl_opt_pass (pass_data_final, ctxt){}/* opt_pass methods: */unsigned int execute (functi…

STC89C52系列单片机内部结构详解

STC89C52 是基于 MCS-51 内核的增强型单片机&#xff0c;其内部结构集成了多种功能模块&#xff0c;具备强大的数据处理和控制能力&#xff0c;是嵌入式系统中常用的一种微控制器。本文将结合内部结构框图&#xff0c;详细介绍 STC89C52 的各个核心组成部分及其功能作用。一、中…

Linux防火墙管理和基础服务(FTP/SFTP)

防火墙管理# 开放端口firewalld-cmd --add-port880/tcp --permanent# 移除端口或阻止端口firewalld-cmd --remove-port880/tcp --permanent# 重启服务systemctl restart firewalld# 查看防火墙开放哪些端口&#xff08;查看当前区域的规则&#xff09;firewall-cmd --lis…