当前位置:朝夕网 » 数码科技 » 从零开始搭建和mybatis

从零开始搭建和mybatis

我是用习惯了idea,所以这里推荐idea进行开发,安装node.js插件,然后就可以本地开发了,没有的话安装一下即可。首先我们先找到head位置进行配置,打开网站的小图标,同样也可以使用URL或者本地引用首先配置目录页,这个是文章的导航界

一、前言

网站主题最初是在开发数据api的时候看到的,当时在学习Mybatis-Plusjs本地打开页面,最初也不知道这是个主题,就觉得Mybatis-Plus官网UI真的不错,直到后面发现另外一个类似的网站,我意识到这是个模板,于是有了自己也搭建一个的想法,不过拖延症相当严重,最初是在宝塔上修改的,效率极低,一度放弃部署,直到最近换成本地开发才好了很多,也就是最近网站搭建初步完成,接下来就是往里面增加文章等等,这里带大家从零开始搭建Vdoing主题网站,算是对过去一个月的知识总结。下图就是mybatis-plus官网,是我们年轻人喜欢的风格(这里随便吐槽一下xx园吧,风格还是20年前的,不知道他们的UI设计师是不是还是兼职的)。

二、准备工作1.github注册

what?你居然没有github账号,建议你放弃网站部署(开玩笑)。作为全球最大的代码托管平台,基本上每个稍微接触过开发的应该都用过,如果你还没注册的话,赶紧注册一个,没听过github太丢人了,注册也很简单(有手就行)。

点击进入github官网,这里需要注意一点,如果是国内访问的话,移动是可以的,其他运营商貌似有屏蔽,如果访问不了,自行百度解决。

2.申请属于自己的域名

这里推荐去国外的Godaddy平台注册一个域名

3.申请注册vercel平台

vercel平台是一个可以免费托管个人网站的自动化部署平台,只要你的代码托管平台(类似github,gitlab,gitee等)commit发生变化,它就会自动更新和重新部署,解放生产力。

点击vercel官网sign up注册一个账号,当然也可以选择github直接登录,会更方便一点,可以直接导入自己的仓库,包括私有仓库。

4.下载node和yarnnode

进入node的官网,选择LTS即长期稳定版本下载。会得到一个msi后缀的文件,即开箱即用的版本,不用自己手动配置环境变量啥的,会配置好的,注意安装位置改一下就行,放在除c盘外的盘即可,其他就一步步点击确认即可,最后cmd中输入node有welcome提示即为成功,不成功按照相应提示浏览器搜索即可。

yarn

这个是个包管理工具,和npm差不多,听说更快一点,这里安装是由于主题更新采用的是这个命令,所以这里安装一下。

yarn官网,如果不想配置环境变量的话,还是可以采用msi后缀安装。

5.图床配置CDN + COS配置图床

有了图床,你就可以随时随地采用URL引用你的图片,非常方便,可以参考我写的这篇搭建博客CDN+COS搭建图床超详细步骤,有个缺点就是需要备案才能使用自定义域名和CDN服务,不过如果想要白嫖的话,搜索国外的图床也是可以的,国内也有一些提供图床配置的,使用它们的域名上传图片也可以。这里采用的是pic-go图床管理工具,强烈安利,真的太方便了。

路径引用

如果你没有自己的图床也没关系,主题博客还提供本地引用的功能,不过这个更改图片的时候比较麻烦,虽然有时候它可能更快一点点。

6.开发IDE下载

我是用习惯了idea,所以这里推荐idea进行开发js本地打开页面,安装node.js插件,然后就可以本地开发了,没有的话安装一下即可。

idea官网

安装node.js插件

至此,准备工作已经完成,接下来就进入今天的主题。

三、本地开发1.github fork项目

Vdoing主题项目地址,这里建议fork整个仓库,然后自己做一些修改即可,作者大大真的太强了。

2.基础网站配置主页配置

打开以下目录的index.md,你可能会问咋是md格式的,不应该是html格式的吗?别着急,这个是开发中的,打包之后是index.html

以下字段对应相关的图,可以自行体会一下,对应导航栏下面的几个字段,其中涉及使用URL引入的,可以替换成路径引用,具体字段帮助请自行查看fork过来的仓库介绍,也可以到Vdoing官方文档查阅.

home: true
heroImage: https://img.de7v.com/img/new_logo_2.png
# heroImage:/img/web.png
# 这个路径在public下的img目录中
heroText: IT七剑客
tagline: 互联网中的持剑者
actionText: 立刻进入 →
actionLink: /wresource/
bannerBg: none

通过路径引用的图片目录,把你想要的图片全放进去然后就可以引用了。

config.ts配置

从零开始搭建和mybatis

进入config.ts界面

首先我们先找到head位置进行配置,打开网站的小图标,同样也可以使用URL或者本地引用

找到location开头的这段代码,网站的标题和描述写一下,这个会在百度搜索的快照中展示。

locales: {
    '/': {//代表baseurl,即网站所有的引用的根路径,默认是没有的,如果文件夹有需要可以修改
        lang: 'zh-CN',
        title: "IT七剑客",
        description: '互联网中的持剑者,七剑客带你斩断一切bug',
    }
},

下面这些代码主要是配置导航栏和其他全局功能,其中logo是最左侧显示的图片,repro是自己的github名,用于直接跳转github主页,其他的取默认即可。

sidebarDepth: 2, // 侧边栏显示深度,默认1,最大2(显示到h3标题)
logo: 'https://img.de7v.com/img/new_logo_2.png', // 导航栏logo
repo: 'xyh-fu', // 导航栏右侧生成Github链接
searchMaxSuggestions: 10, // 搜索结果显示最大数
lastUpdated: '上次更新', // 开启更新时间,并配置前缀文字   string | boolean (取值为git提交时间)
docsDir: 'docs', // 编辑的文件夹
// docsBranch: 'master', // 编辑的文件所在分支,默认master。 注意:如果你的分支是main则修改为main
editLinks: true, // 启用编辑
editLinkText: '编辑',

footer:{ // 页脚信息
    createYear: 2022, // 博客创建年份
        //博客版权信息,支持a标签
        copyrightInfo:'IT七剑客 | MIT License
  • 闽ICP备2021006579号-4
  • 闽公网安备 35012102500470号
  • ' },

    至此基本配置已经大功告成,接下来我们谈谈文章是怎么配置和主页路由的规则。

    文章誊写和路由设置

    首先配置目录页,这个是文章的导航界面,可以分别查看各个目录下的文章列表

    ---
    pageComponent: 
      name: Catalogue
      data: 
        path: 01.wresource  安卓
        imgUrl: https://img.de7v.com/img/wresource.png
        description:  Android,Kotlin,Jetpack等技术
    title: wresource  安卓
    date: 2020-03-11 21:50:53
    permalink: /wresource
    sidebar: false
    article: false
    comment: false
    editLink: false
    author:
      name: wresource
      link: https://github.com/xyh-fu
    ---

    在这里设置目录的路由以及一些基础的配置,放图自行体会,这里需要注意一点,path要和docs下面的相应文章目录路径名一致,这里仅仅只是配置一下界面,真正的文章是放在docs下面的目录中。

    关于文章誊写和命名规则具体查看作者的这篇文章关于目录和文章名称约定(这里偷懒一波)。

    接下来再次回到之前得index.md中,可以配置主界面相关信息了

    features: # 可选的
      - title: wresource  安卓
        details: Android,Kotlin,Jetpack等技术
        link: /wresource/ # 可选
        imgUrl: https://img.de7v.com/img/wresource.png # 可选

    配置效果如下图所示

    3.插件配置

    这部分就属于网站的内部配置了,与外观没有多大关系,如果觉得可以了,就不用配置了

    站点信息页面

    主要用于统计网站相关信息的功能同时也增加文章字数统计以及阅读量统计等等,这个配置参考kbt大大的博客,这里提醒一下readfile文件在博客中失效,建议去kbt大大的github项目主页获取最新的代码。站点信息搭建

    这里给出当时踩坑的那个readfile文件代码,如果有不同,以作者的为主。

    import fs from 'fs'; // 文件模块
    import path from 'path'; // 路径模块
    import matter from 'gray-matter'; // FrontMatter解析器 https://github.com/jonschlinkert/gray-matter
    import chalk from 'chalk' // 命令行打印美化
    const log = console.log
    const docsRoot = path.join(__dirname, '..', '..', '..', 'docs'); // docs文件路径
    /**
     * 获取本站的文章数据
     * 获取所有的 md 文档,可以排除指定目录下的文档
     */
    function readFileList(excludeFiles: Array = [''], dir: string = docsRoot, filesList: Array = []) {
      const files = fs.readdirSync(dir);
      files.forEach((item, index) => {
        let filePath = path.join(dir, item);
        const stat = fs.statSync(filePath);
        if (!(excludeFiles instanceof Array)) {
          log(chalk.yellow(`error: 传入的参数不是一个数组。`))
        }
        excludeFiles.forEach((excludeFile) => {
          if (stat.isDirectory() && item !== '.vuepress' && item !== '@pages' && item !== excludeFile) {
            readFileList(excludeFiles, path.join(dir, item), filesList);  //递归读取文件
          } else {
            if (path.basename(dir) !== 'docs') { // 过滤 docs目录级下的文件
              const fileNameArr = path.basename(filePath).split('.')
              let name = null, type = null;
              if (fileNameArr.length === 2) { // 没有序号的文件
                name = fileNameArr[0]
                type = fileNameArr[1]
              } else if (fileNameArr.length === 3) { // 有序号的文件
                name = fileNameArr[1]
                type = fileNameArr[2]
              } else { // 超过两个‘.’的
                log(chalk.yellow(`warning: 该文件 "${filePath}" 没有按照约定命名,将忽略生成相应数据。`))
                return
              }
              if (type === 'md') { // 过滤非 md 文件
                filesList.push({
                  name,
                  filePath
                });
              }
            }
          }
        });
      });
      return filesList;
    }
    /**
     * 获取本站的文章总字数
     * 可以排除某个目录下的 md 文档字数
     */
    function readTotalFileWords(excludeFiles = ['']) {
      const filesList = readFileList(excludeFiles);
      let wordCount = 0;
      filesList.forEach((item: any) => {
        const content = getContent(item.filePath);
        let len = counter(content);
        wordCount += len[0] + len[1];
      });
      if (wordCount < 1000) {
        return wordCount;
      }
      return Math.round(wordCount / 100) / 10 + 'k';
    }
    /**
     * 获取每一个文章的字数
     * 可以排除某个目录下的 md 文档字数
     */
    function readEachFileWords(excludeFiles: Array = [''], cn: number, en: number) {
      const filesListWords = [];
      const filesList = readFileList(excludeFiles);
      filesList.forEach((item: any) => {
        const content = getContent(item.filePath);
        let len = counter(content);
        // 计算预计的阅读时间
        let readingTime = readTime(len, cn, en);
        let wordsCount: any = 0;
        wordsCount = len[0] + len[1];
        if (wordsCount >= 1000) {
          wordsCount = Math.round(wordsCount / 100) / 10 + 'k';
        }
        // fileMatterObj => {content:'剔除frontmatter后的文件内容字符串', data:{}, ...}
        const fileMatterObj = matter(content, {});
        const matterData = fileMatterObj.data;
        filesListWords.push({ ...item, wordsCount, readingTime, ...matterData });
      });
      return filesListWords;
    }
    /**
     * 计算预计的阅读时间
     */
    function readTime(len: Array, cn: number = 300, en: number = 160) {
      let readingTime = len[0] / cn + len[1] / en;
      if (readingTime > 60 && readingTime  60 * 24) {      // 大于一天
        let day = Math.trunc(readingTime / (60 * 24));
        let hour = Math.trunc((readingTime - day * 24 * 60) / 60);
        if (hour === 0) {
          return day + 'd';
        }
        return day + 'd' + hour + 'h';
      }
      return readingTime < 1 ? '1' : Math.trunc(readingTime * 10) / 10 + 'm';   // 取一位小数
    }
    /**
     * 读取文件内容
     */
    function getContent(filePath: string) {
      return fs.readFileSync(filePath, 'utf8');
    }
    /**
     * 获取文件内容的字数
     * cn:中文
     * en:一整句英文(没有空格隔开的英文为 1 个)
     */
    function counter(content: string) {
      const cn = (content.match(/[u4E00-u9FA5]/g) || []).length;
      const en = (content.replace(/[u4E00-u9FA5]/g, '').match(/[a-zA-Z0-9_u0392-u03c9u0400-u04FF]+|[u4E00-u9FFFu3400-u4dbfuf900-ufaffu3040-u309fuac00-ud7afu0400-u04FF]+|[u00E4u00C4u00E5u00C5u00F6u00D6]+|w+/g) || []).length;
      return [cn, en];
    }
    export {
      readFileList,
      readTotalFileWords,
      readEachFileWords,
    }
    

    下面给出效果图

    这里有一点比较坑,就是当时这个模块默认挂载到热门标签下面,然而我没有设置标签。最后给挂在了页面底部。请务必仔细阅读作者的博客。

    广告配置

    首先在config.ts的head中引入下列代码,这里是谷歌广告配置。

    [
        'script',
        {
            'data-ad-client': '自己的广告id',
            async: 'async',
            src: 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js',
        },
    ], // 网站关联Google AdSense 与 html格式广告支持(你可以去掉)

    然后在themeConfig中添加下列字段

    在下列目录中完成html广告的配置

    我的配置,在全局右下角添加广告。

    windowRB:
          ` 
            
            
                (adsbygoogle = window.adsbygoogle || []).push({});
            `,

    复制

    百度统计

    这部分比较简单,在head中加入以下字段即可(谁说比较简单的,这个我鼓捣了一周,插件用不了,不知道是啥原因,最后采用这个比较简单的方法配置),至于百度统计码,百度一下百度统计即可。它最重要的作用就是分析网站的来访数量以及搜索量等等,站长必备工具之一。

    [
        'script',
        { 
            src: 'https://hm.baidu.com/hm.js?百度统计码',
        },
    ],

    复制

    本文到此结束,希望对大家有所帮助!

    免责声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如有侵权行为,请第一时间联系我们修改或删除,多谢。朝夕网 » 从零开始搭建和mybatis