Vue + Node + MongoDB 前后端分离搭建一款简约的个人博客系统

vue-node-mongodb-blog

一款简约版本的 PC 博客。前端项目主要是采用 Vue2 和 Element-UI 来搭建的;采用 Webpack5 来构建、打包。后端项目主要采用 Node 框架 Koa2 以及 MongoDB 数据库来设计的。

  1. PC 端博客线上预览地址:http://www.rasblog.com
  2. PC 端博客仓库地址:https://github.com/Sujb-sus/vue-node-mongodb-blog
  3. H5 端博客仓库地址:https://github.com/Sujb-sus/vue3-vite2-ts-blog-h5

主要功能

客户端

  1. 文章功能:文章内容支持Markdown语法且代码高亮展示;
  2. 标签功能:通过标签分类来检索文章数据;
  3. 侧边栏功能:点击排行、站长推荐和标签分类等;
  4. 搜索功能:通过关键词检索文章的标题和摘要,并支持搜索高亮;
  5. 留言功能:可点赞、回复评论,统计评论以及回复总数,支持Emoji表情;
  6. 其他功能:图片懒加载、分页、侧边栏吸顶以及一键置顶等;

管理端

  1. 权限管理:CRUD 管理员,可分配权限;
  2. 文章管理:CRUD 文章,文章封面支持本地上传、文章内容支持Markdown语法编辑;
  3. 标签管理:CRUD 标签,标签背景色支持用Vue-Color插件自定义选择;
  4. 留言管理:RD 评论以及回复;

项目结构

project-structure.png

技术运用

一. 自动化导入大量公共组件

  1. components/common/index.js文件下通过require.context('文件路径', '是否遍历文件子目录', '匹配文件的正则')方法导入所有公共vue组件
// components/common/index.js
import Vue from "vue";
// 检索当前目录的vue文件且遍历子文件夹目录
const componentsContext = require.context("./", true, /.vue$/);
componentsContext.keys().forEach((component) => {
  // 获取文件中的 default 模块
  const componentConfig = componentsContext(component).default;
  componentConfig.name && Vue.component(componentConfig.name, componentConfig);
});
  1. main.js导入components/common/index.js即可
import "src/components/common/index.js";
  1. 这样所有components/common文件下的 vue 组件都被自动导入了,可在模板直接用组件,不需要在额外导入

二. 图片懒加载

原理:其实就是利用了img标签的src属性,我们先把所有图片的url置空,这样浏览器就不会去请求了;然后写个事件去监听可视区的范围;在进入该范围前拿到图片的url,在把它放到src属性中显示出来。

  1. 安装vue-lazyload插件
yarn add vue-lazyload -S
  1. main.js导入vue-lazyload
import VueLazyload from "vue-lazyload";
const loadimage = require("./images/loading.gif");
const errorimage = require("./images/load-error.jpeg");
Vue.use(VueLazyload, {
  preLoad: 1.3, // 提前加载高度(1 表示 1 屏的高度)
  error: errorimage, // 加载失败时显示的图片
  loading: loadimage, // 加载状态中显示的图片
  attempt: 1, // 加载错误后最大尝试次数
});
  1. img标签的src属性直接替换为v-lazy即可
<img v-lazy="item.fileCoverImgUrl" @click="goto(item._id)" />

三. Vue-Color 自定义选择颜色

  1. 安装vue-color插件
yarn add vue-color -S
  1. 在组件内导入、解构出Sketch,并注册为组件便可运用
<sketch-picker v-model="currentColor" @input="colorValueChange"></sketch-picker>
import { Sketch } from "vue-color";
export default {
  name: "permissionAdd",
  components: {
    "sketch-picker": Sketch,
  },
  data() {
    return {
      currentColor: "rgba(70, 70, 70, 0.9)",
    };
  },
  methods: {
    // 颜色值改变事件处理,fmtObj可返回16进制、rgba等格式
    colorValueChange(fmtObj) {
      // 取颜色对象的 rgba 值
      const { r, g, b, a } = fmtObj.rgba;
      this.currentColor = `rgba(${r}, ${g}, ${b}, ${a})`;
    },
  },
};

四. less 全局变量导入

  1. 安装style-resources-loader插件
yarn add style-resources-loader -D
  1. webpackmodule模块对后缀名为less的文件进行配置
module.exports = {
  module: {
    rules: [
      // 开发环境使用vue-style-loader可以重载样式模块
      {
        test: /\.less$/,
        use: [
          !isProd
            ? { loader: "vue-style-loader" }
            : MiniCssExtractPlugin.loader,
          { loader: "css-loader" },
          { loader: "less-loader" },
          {
            loader: "style-resources-loader",
            options: {
              patterns: path.resolve(__dirname, "../styles/theme.less"),
            },
          },
        ],
      },
    ],
  },
};
  1. 这里有个缺点就是,修改了样式需要手动刷新页面,所以开发环境可以配合vue-style-loader使用,就可以重载样式模块

五. 支持 markdown 语法

  1. 安装markedhighlightJs插件
yarn add marked highlightJs -S
  1. 在组件内导入,通过计算属性将输入的文本格式转化为markdown语法
<textarea v-model="val"></textarea>
<div v-html="renderHtml"></div>
import marked from "marked";
import highlightJs from "highlight.js";

export default {
  computed: {
    renderHtml() {
      marked.setOptions({
        renderer: new marked.Renderer(),
        gfm: true, //允许 Git Hub标准的markdown.
        tables: true, //允许支持表格语法。该选项要求 gfm 为true。
        breaks: true, //允许回车换行。该选项要求 gfm 为true。
        pedantic: false, //尽可能地兼容 markdown.pl的晦涩部分。不纠正原始模型任何的不良行为和错误。
        sanitize: true, //对输出进行过滤(清理),将忽略任何已经输入的html代码(标签)
        smartLists: true, //使用比原生markdown更时髦的列表。 旧的列表将可能被作为pedantic的处理内容过滤掉.
        smartypants: false, //使用更为时髦的标点,比如在引用语法中加入破折号。
        highlight: function(code) {
          return highlightJs.highlightAuto(code).value;
        },
      });
      return marked(this.val);
    },
  },
  data() {
    return {
      val: this.value,
    };
  },
};

注意事项:

  1. 项目启动前,需要在本地安装好 MongoDB 数据库
  2. code/server/config.js文件配置数据库名、用户以及密码等一些必要的信息;这些信息都可以自定义,但是需要跟步骤 3同步起来
// code/server/config.js
export default {
  env: process.env.NODE_ENV,
  port,
  auth,
  log,
  mongodb: {
    username: "wall", // 数据库用户
    pwd: 123456, // 数据库密码
    address: "localhost:27017",
    db: "wallBlog", // 数据库名
  },
};
  1. 启动本地的mongo服务,给数据库初始化在code/server/config.js配置的一些必要信息
> mongo // 开启mongo服务
> show dbs // 显示数据库列表
> use wallBlog // 新建一个wallBlog数据库
> db.createUser({user:"wall",pwd:"123456",roles:[{role:"readWrite",db:'wallBlog'}]}) // 在wallBlog数据库创建一个wall用户,密码为123456
> show users // 展示该库有哪些用户
> db.auth("wall", "123456"); // 数据库认证一下用户、密码,返回 1 认证成功
  1. 登录管理后台时,需要给数据库创建users集合,并注册一个账号进行登录
> mongo // 开启mongo服务
> show dbs // 显示数据库列表
> use wallBlog // 进入到wallBlog数据库
> db.users.insert({  // 往该库的users集合插入一条数据,账号:admin  密码:123456
    "pwd" : "e10adc3949ba59abbe56e057f20f883e",
    "username" : "admin",
    "roles" : [
        "admin"
    ]
})
> show collections // 查询该库下的集合(类似于mysql的表)
> db.users.find() // 查询users集合下的所有数据
  1. 初始化好了数据库就可以开启后台接口服务yarn server,数据库如果连接成功会在控制台打印提示
  2. yarn dev:admin启动管理后台界面,用上面注册的账号密码登录,就可以添加数据了
  3. yarn dev:client启动客户端页面预览

脚本命令

  • yarn dev:admin // 本地开发管理端页面
  • yarn dev:client // 本地开发客户端页面
  • yarn build:admin // 项目打包 - 管理端
  • yarn build:client // 项目打包 - 客户端
  • yarn analyz // 查看打包信息
  • yarn server // 启动后台接口服务

参考目录

  1. vue-node-blog 开源项目:https://github.com/cd-dongzi/vue-node-blog
  2. vue-color文档:https://www.npmjs.com/package/vue-color
  3. vue-lazyload文档:https://www.npmjs.com/package/vue-lazyload
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容