VUE+Node.js+mysq实现响应式个人博客|项目初始化+路由配置+基础组件搭建

news/2024/12/25 3:02:56/

Day 1 开发文档:项目初始化与基础架构搭建

一、项目初始化

1. 创建项目

首先,我们使用 Vite 创建一个基于 Vue 3 的项目:

# 创建项目
npm create vite@latest my-blog -- --template vue
# 这条命令会创建一个名为 my-blog 的新项目,使用 Vue 3 模板# 进入项目目录
cd my-blog# 安装项目依赖
npm install

2. 安装必要依赖

接下来,我们需要安装项目所需的核心依赖:

# 安装核心依赖
npm install vue-router@4 vuex@4 axios marked dompurify
# vue-router@4: Vue 3 的路由管理器,用于处理页面导航
# vuex@4: Vue 3 的状态管理库,用于管理全局状态
# axios: HTTP 请求库,用于与后端 API 通信
# marked: Markdown 解析器,用于解析文章内容
# dompurify: HTML 净化库,用于防止 XSS 攻击# 安装开发依赖
npm install -D sass @types/node
# sass: CSS 预处理器,提供更强大的样式编写功能
# @types/node: Node.js 的 TypeScript 类型定义

3. 项目结构规划

创建以下目录结构,每个目录都有其特定用途:

blog-website/
├── src/
│   ├── components/     # 公共组件目录
│   │   ├── TheHeader.vue    # 网站头部导航
│   │   ├── ScrollProgress.vue    # 滚动进度条
│   │   ├── BlogCard.vue    # 博客卡片
│   │   └── TheFooter.vue    # 网站底部
│   ├── views/         # 页面组件目录
│   │   ├── HomeView.vue    # 首页
│   │   └── BlogView.vue    # 博客列表页
│   ├── router/        # 路由配置目录
│   │   └── index.js    # 路由配置文件
│   ├── store/         # 状态管理目录
│   │   └── index.js    # Vuex 配置文件
│   ├── api/          # API 接口目录
│   │   └── blog.js    # 博客相关接口
│   └── assets/       # 静态资源目录
│       └── styles/    # 样式文件目录
│           ├── main.css    # 主样式文件
│           └── responsive.css    # 响应式样式
├── index.html    # 入口 HTML 文件
└── package.json    # 项目配置文件

二、基础组件开发

1. 响应式导航栏组件

[文件位置: src/components/TheHeader.vue]

TheHeader.vue 组件说明:
1. 功能:实现响应式导航栏
2. 主要特点:- 自适应布局:在不同屏幕尺寸下自动调整显��方式- 移动端菜单:在小屏幕设备上显示汉堡菜单按钮- 动态交互:菜单展开/收起动画,滚动时自动隐藏/显示
3. 核心实现:- 使用 Vue 3 组合式 API- 响应式状态管理- CSS 过渡动画
<template><header class="header" :class="{ 'header-hidden': isHeaderHidden }"><div class="container"><nav class="nav"><!-- Logo 区域 --><router-link to="/" class="logo"><h1>✨ My Blog ✨</h1></router-link><!-- 移动端菜单按钮 --><div class="menu-toggle" @click="toggleMenu"><i class="fas fa-bars"></i></div><!-- 导航链接 --><ul class="nav-links" :class="{ active: isMenuOpen }"><li v-for="item in menuItems" :key="item.path"><router-link :to="item.path" @click="closeMenu"active-class="active"><i :class="item.icon"></i>{{ item.name }}</router-link></li></ul></nav></div></header>
</template><script setup>
import { ref } from 'vue'// 控制菜单显示状态
const isMenuOpen = ref(false)
// 控制导航栏显示/隐藏
const isHeaderHidden = ref(false)// 导航菜单项配置
const menuItems = [{ path: '/', name: '首页', icon: 'fas fa-home' },{ path: '/blog', name: '博客', icon: 'fas fa-cloud' }
]// 切换菜单显示状态
const toggleMenu = () => {isMenuOpen.value = !isMenuOpen.value
}// 关闭菜单
const closeMenu = () => {isMenuOpen.value = false
}
</script>

2. 滚动进度条组件

[文件位置: src/components/ScrollProgress.vue]

ScrollProgress.vue 组件说明:
1. 功能:显示页面阅读进度
2. 主要特点:- 实时进度更新:随页面滚动实时计算和显示进度- 平滑动画:使用 CSS 过渡实现流畅的进度更新- 性能优化:使用节流函数优化滚动事件处理
3. 核心实现:- 滚动事件监听- 进度计算逻辑- 组件生命周期管理
<template><div class="scroll-progress" :style="{ width: progress + '%' }"></div>
</template><script setup>
import { ref, onMounted, onUnmounted } from 'vue'// 存储滚动进度
const progress = ref(0)// 更新滚动进度
const updateProgress = () => {// 计算页面总高度(减去视口高度)const windowHeight = document.documentElement.scrollHeight - window.innerHeight// 计算滚动百分比const scrolled = (window.scrollY / windowHeight) * 100progress.value = scrolled
}// 组件挂载时添加滚动监听
onMounted(() => {window.addEventListener('scroll', updateProgress)
})// 组件卸载时移除监听,防止内存泄漏
onUnmounted(() => {window.removeEventListener('scroll', updateProgress)
})
</script>

3. 博客卡片组件

[文件位置: src/components/BlogCard.vue]

BlogCard.vue 组件说明:
1. 功能:展示博客文章预览卡片
2. 主要特点:- 响应式布局:适应不同屏幕尺寸- 图片处理:懒加载和错误处理- 内容格式化:日期和摘要的智能处理
3. 核心实现:- 图片懒加载- Markdown 解析- XSS 防护- 路由导航
<template><div class="blog-card" @click="handleClick"><!-- 文章封面图片 --><div class="card-image"><img :src="post.image || '/images/placeholder.jpg'" :alt="post.title"@error="handleImageError"></div><!-- 文章内容预览 --><div class="card-content"><h3 class="card-title">{{ post.title }}</h3><p class="card-excerpt">{{ formatExcerpt(post.excerpt) }}</p><!-- 文章元信息 --><div class="card-meta"><span class="date"><i class="far fa-calendar-alt"></i>{{ formatDate(post.date) }}</span><span class="category"><i class="fas fa-folder"></i>{{ post.category }}</span></div></div></div>
</template><script setup>
import { ref } from 'vue'
import { marked } from 'marked'
import DOMPurify from 'dompurify'
import { useRouter } from 'vue-router'// 定义组件属性
const props = defineProps({post: {type: Object,required: true}
})const router = useRouter()// 处理卡片点击,跳转到文章详情
const handleClick = () => {const id = props.post?.idif (!id) returnrouter.push(`/blog/${id}`)
}// 格式化文章摘要,去除 HTML 标签限制长度
const formatExcerpt = (excerpt) => {if (!excerpt) return ''const html = DOMPurify.sanitize(marked(excerpt))const div = document.createElement('div')div.innerHTML = htmllet text = div.textContent || div.innerText || ''return text.length > 200 ? text.slice(0, 200) + '...' : text
}// 格式化日期显示
const formatDate = (date) => {return new Date(date).toLocaleDateString('zh-CN')
}// 处理图片加载失败
const handleImageError = (e) => {e.target.src = '/images/placeholder.jpg'
}
</script>

三、路由配置

1. 基础路由设置

[文件位置: src/router/index.js]

配置页面路由和导航规则:

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '@/views/HomeView.vue'
import BlogView from '@/views/BlogView.vue'const routes = [{path: '/',name: 'home',component: HomeView,meta: {title: '首页'}},{path: '/blog',name: 'blog',component: BlogView,meta: {title: '博客'}}
]const router = createRouter({history: createWebHistory(),routes,scrollBehavior(to, from, savedPosition) {// 页面切换时滚动到顶部return { top: 0 }}
})export default router
路由配置说明:
1. 功能:实现页面导航和路由控制
2. 主要特点:- 历史模式:使用 HTML5 History API- 路由懒加载:优化首屏加载时间- 滚动行为:自动滚动到页面顶部
3. 核心实现:- 路由注册- 导航守卫- 滚动控制

3. 懒加载优化

[文件位置: src/router/index.js, src/components/BlogCard.vue, src/App.vue]

为了提升性能,我们在以下几个方面实现了懒加载:

  1. 路由懒加载
// [文件位置: src/router/index.js]
const routes = [{path: '/',name: 'home',component: () => import('@/views/HomeView.vue') // 懒加载首页},{path: '/blog',name: 'blog',component: () => import('@/views/BlogView.vue') // 懒加载博客页}
]
  1. 图片懒加载
// [文件位置: src/components/BlogCard.vue]
<template><div class="blog-card"><div class="card-image"><img :src="post.image || '/images/placeholder.jpg'" :alt="post.title"loading="lazy" // 使用浏览器原生懒加载@error="handleImageError"></div></div>
</template>
  1. 组件懒加载
// [文件位置: src/App.vue]
<script setup>
import { defineAsyncComponent } from 'vue'// 懒加载非关键组件
const TheFooter = defineAsyncComponent(() => import('./components/TheFooter.vue')
)// 带加载状态的懒加载组件
const BlogEditor = defineAsyncComponent({loader: () => import('./components/BlogEditor.vue'),loadingComponent: LoadingSpinner,delay: 200,timeout: 3000
})
</script>
  1. 懒加载效果
  • 首屏加载时间优化:只加载必要的组件
  • 图片加载优化:减少首屏请求数量
  • 路由切换优化:按需加载页面组件
  • 内存使用优化:减少初始化时的内存占用

四、状态管理

1. Vuex Store 配置

[文件位置: src/store/index.js]

配置全局状态管理:

import { createStore } from 'vuex'
import { blogApi } from '@/api/blog'export default createStore({// 状态定义state: {posts: [],      // 文章列表loading: false, // 加载状态error: null     // 错误信息},// 修改状态的方法mutations: {SET_POSTS(state, posts) {state.posts = posts},SET_LOADING(state, loading) {state.loading = loading},SET_ERROR(state, error) {state.error = error}},// 异步操作actions: {// 获取文章列表async fetchPosts({ commit }) {try {commit('SET_LOADING', true)const { data } = await blogApi.getPosts()commit('SET_POSTS', data)return data} catch (err) {commit('SET_ERROR', err.message)throw err} finally {commit('SET_LOADING', false)}}}
})
Vuex Store 配置说明:
1. 功能:全局状态管理
2. 主要特点:- 集中管理数据- 异步操作处理- 状态追踪
3. 核心实现:- 状态定义- 同步修改- 异步操作

五、样式系统

1. 全局主题变量

[文件位置: src/assets/styles/main.css]

定义全局样式变量,确保设计的一致性:

:root {/* 颜色系统 - 定义网站配色方案 */--color-primary: #3498db;    /* 主要颜色 */--color-secondary: #2ecc71;  /* 次要颜色 */--color-text: #2c3e50;      /* 文本颜色 */--color-background: #ffffff; /* 背景颜色 */--color-border: #e0e0e0;    /* 边框颜色 *//* 字体系统 - 定义文字样式 */--font-family: 'Inter', system-ui, sans-serif;--font-size-base: 16px;   /* 基础字号 */--font-size-lg: 18px;     /* 大号字体 */--font-size-xl: 24px;     /* 特大号字体 *//* 间距系统 - 统一间距标准 */--spacing-xs: 4px;    /* 超小间距 */--spacing-sm: 8px;    /* 小间距 */--spacing-md: 16px;   /* 中等间距 */--spacing-lg: 24px;   /* 大间距 */--spacing-xl: 32px;   /* 特大间距 *//* 圆角 - 统一圆角大小 */--border-radius: 8px;--border-radius-lg: 12px;/* 阴影 - 统一阴影效果 */--shadow-sm: 0 1px 3px rgba(0,0,0,0.12);--shadow-md: 0 4px 6px rgba(0,0,0,0.1);--shadow-lg: 0 10px 15px rgba(0,0,0,0.1);
}

2. 响应式布局

[文件位置: src/assets/styles/responsive.css]

实现移动端优先的响应式设计:

/* 移动端优先的响应式设计 */
.container {width: 100%;padding: 0 var(--spacing-md);margin: 0 auto;
}/* 平板设备断点 (>= 768px) */
@media (min-width: 768px) {.container {max-width: 720px;  /* 限制容器最大宽度 */}.header__nav {display: flex;  /* 显示导航菜单 */}.header__toggle {display: none;  /* 隐藏菜单按钮 */}
}/* 桌面设备断点 (>= 1024px) */
@media (min-width: 1024px) {.container {max-width: 960px;}.posts-grid {grid-template-columns: repeat(3, 1fr);  /* 三列布局 */}
}/* 大屏设备断点 (>= 1280px) */
@media (min-width: 1280px) {.container {max-width: 1200px;}
}
样式系统说明:
1. 功能:统一的设计系统
2. 主要特点:- 主题变量:统一的颜色和尺寸- 响应式设计:适配不同设备- 组件样式:模块化的样式管理
3. 核心实现:- CSS 变量系统- 媒体查询- 布局系统

六、第一天完成的功能

  1. 项目初始化

    • 使用 Vite 创建 Vue 3 项目
    • 安装必要的依赖包
    • 规划项目目录结构
  2. 基础组件开发

    • 响应式导航栏(TheHeader)
      • 网站标题和 Logo
      • 响应式菜单
      • 移动端适配
    • 滚动进度条(ScrollProgress)
      • 实时显示阅读进度
      • 平滑动画效果
    • 博客卡片(BlogCard)
      • 文章预览展示
      • 图片加载优化
      • 响应式布局
  3. 路由配置

    • 设置基础路由(首页、博客列表)
    • 配置路由历史模式
    • 添加滚动行为控制
  4. 状态管理

    • 配置 Vuex store
    • 实现文章数据管理
    • 添加加载状态控制
  5. 样式系统

    • 定义全局主题变量
    • 实现响应式布局
    • 设置统一的设计标准

http://www.ppmy.cn/news/1557890.html

相关文章

R语言基础| 功效分析

写在前面 R语言在进行统计分析和数据处理方面具有多种优势&#xff0c;在R语言中进行功效分析&#xff08;power analysis&#xff09;同样很方便&#xff0c;R环境中有pwr、powerAnalysis、simr等包可支持功效分析&#xff0c;结合其可视化能力及与其它方法整合的灵活性&…

数据结构:双向循坏链表

目录 1.1双向循环链表的结构 2.双向链表功能的实现 2.1初始化链表 2.2销毁链表 2.3创建结点 2.4打印链表 2.5链表查找 2.6链表在pos的前面进行插入 2.7链表删除pos位置的节点 2.8链表的头插&#xff0c;头删 &#xff0c;尾插&#xff0c;尾删 1.1双向循环链表的结构 …

jsp中的四个域对象(Spring MVC)

在Spring MVC中&#xff0c;Model中的数据会被自动放入到请求域&#xff08;Request Scope&#xff09;中。也就是说&#xff0c;当我们在控制器中使用model.addAttribute()时&#xff0c;这些属性会被放入到HttpServletRequest对象的属性中。 让我们通过代码来详细解释&#…

Cesium-(Primitive)-(EllipseOutlineGeometry)

EllipseOutlineGeometry 以下是 EllipseOutlineGeometry 类的构造函数属性,以表格形式展示: 属性名类型默认值描述centerCartesian3椭圆的中心点在固定坐标系中的坐标。semiMajorAxisnumber椭圆的长半轴长度,单位为米。semiMinorAxisnumber椭圆的短半轴长度,单位为米。elli…

虚幻5 UE5 UNREALED_API d虚幻的

在虚幻引擎的模块化系统中&#xff0c;UNREALED_API 用于声明那些需要被其他模块访问的类和函数。当你在一个模块中标记一个类或函数为 UNREALED_API 时&#xff0c;如果该模块被编译为DLL&#xff0c;那么这个宏会使得该类或函数在DLL边界上被正确地导出。如果其他模块依赖于这…

C语言学习-数组练习

1. 键盘录入一组数列&#xff0c;利用冒泡排序将数据由大到小排序 #include <stdio.h> #include <string.h> #define A_NUM 10int t1 0; int t2 0;/** *键盘录入一组数列&#xff0c;利用冒泡排序将数据由大到小排序 */ //使用常规冒泡完成 void t_1_1() {int i…

前端框架Vue的路由机制

大家好&#xff0c;我是G探险者。 最近在调试前端代码的时候&#xff0c;遇到一个问题。首先我们有一个门户页面&#xff0c;该页面里面有很多的豆腐块&#xff0c;每个豆腐块会配置一个系统的跳转连接。 我的系统就是其中一个豆腐块&#xff0c;我第一次登录进来之后&#xf…

低代码可视化-uniapp进销存销售表单-代码生成器

将低代码理念与Uni-App框架结合&#xff0c;应用到进销存销售表单的开发中&#xff0c;可以显著提升开发效率和代码质量。以下是对低代码可视化-UniApp进销存销售表单-代码生成器的详细分析&#xff1a; 客户信息 选择客户信息&#xff0c;选择客户信息后显示在表单开头信息。…