使用vuepress-theme-reco搭建自己的博客

简介: 你想搭建属于你自己的博客吗?你想将你的笔记可视化吗?快来学些Markdown笔记一键生成网页的方法吧!

使用vuepress-theme-reco搭建自己的博客

vuepress-theme-reco是VuePress的一个主题,大家可以参考VuePress和其他主题,搭建你自己风格的主题,这篇主要讲解vuepress-theme-reco主题的博客。

VuePress是静态网页生成器,通过它,可以迅速的将我们的Markdown笔记变成网页,方便我们翻阅,查找。

一、初始化项目

1、引入vuepress-theme-reco主题

npm install vuepress-theme-reco --save-dev

2、使用官方的模板初始化项目

theme-cli init blogs

按要求输入内容

image-20210712152501859.png

将在你的文件夹下生成你项目名的文件夹,我这里是blog.

3、运行

进到文件夹内,使用cmd执行

npm install
npm run dev

image-20210712133159335.png

至此博客已经可以正常使用了,但是我们打开官方的案例,往往比我们现在的效果要好,我们需要优化的继续往下看。

二、优化页面

1、官方的功能

像评论、时间线、域名的配置、多语言、暗色适配、侧边栏、文档的摘要...官方写的已经很详细,这里就不再介绍,按照官方文档配置即可。如果有疑问,可以在下面评论,咨询我。

2、看板娘

  • 引入依赖:npm i @vuepress-reco/vuepress-plugin-kan-ban-niang
  • 配置

    在config.js下的module.exports加入如下代码,可参考npm

    plugins: [
        [
          '@vuepress-reco/vuepress-plugin-kan-ban-niang',{
            theme: [
              'miku', 'whiteCat', 'haru1', 'haru2', 'haruto', 'koharu', 'izumi', 'shizuku', 'wanko', 'blackCat', 'z16'
            ],
            clean: false,
            messages: { 
              welcome: '欢迎来到我的博客', home: '心里的花,我想要带你回家。', theme: '好吧,希望你能喜欢我的其他小伙伴。', close: '你不喜欢我了吗?痴痴地望着你。' 
            },
            messageStyle: { right: '68px', bottom: '290px' },
            width: 250,
            height: 320
          }
        ],
      ],
  • 效果图

image-20210712154935373.png

3、公告

  • 安装依赖:npm i @vuepress-reco/vuepress-plugin-bulletin-popover
  • 修改配置:在config.js下的module.exports的plugin下加入以下代码:

    ['@vuepress-reco/vuepress-plugin-bulletin-popover', {
          title: '公告',
          body: [
            {
              type: 'title',
              content: '欢迎加我的QQ/vx 🎉🎉🎉',
              style: 'text-aligin: center;',
            },
            {
              type: 'text',
              content: 'QQ/VX:1349320519',
              style: 'text-align: center;'
            },
            {
              type: 'text',
              content: '喜欢的主题特效可以去个人信息',
              style: 'text-align: center;'
            },
            {
              type: 'text',
              content: '友链或疑问均可在留言板给我留言',
              style: 'text-align: center;'
            }
          ],
          footer: [
            {
              type: 'button',
              text: '打赏',
              link: '/blog/donate'
            },
          ]
        }],
      ],

    注意和上一个插件直接有逗号间隔,上述的打赏对应的超链接/blog/donate,你可以在这里定义你自己的打赏页面。

  • 效果图

image-20210712155619808.png

4、音乐播放器

  • 安装依赖:npm i @vuepress-reco/vuepress-plugin-bgm-player
  • 修改配置:在config.js下的module.exports的plugin下加入以下代码,更多配置参考npm

    [
          "@vuepress-reco/vuepress-plugin-bgm-player",{
            audios: [
              // 本地文件示例
              // {
              //   name: '장가갈 수 있을까',
              //   artist: '咖啡少年',
              //   url: '/bgm/1.mp3',
              //   cover: '/bgm/1.jpg'
              // },
              // 网络文件示例
              {
                name: '강남역 4번 출구',
                artist: 'Plastic / Fallin` Dild',
                url: 'https://assets.smallsunnyfox.com/music/2.mp3',
                cover: 'https://assets.smallsunnyfox.com/music/2.jpg'
              },
              {
                name: '用胳膊当枕头',
                artist: '최낙타',
                url: 'https://assets.smallsunnyfox.com/music/3.mp3',
                cover: 'https://assets.smallsunnyfox.com/music/3.jpg'
              }
            ]  
          }
        ],
  • 效果图

image-20210712160324763.png

5、鼠标点击特效

  • 安装依赖:npm i vuepress-plugin-cursor-effects
  • 修改配置:在config.js下的module.exports的plugin下加入以下代码,更多配置参考npm

     [
          "vuepress-plugin-cursor-effects",
          {
            size: 2,                    // size of the particle, default: 2
            shape: 'circle',  // shape of the particle, default: 'star'
            zIndex: 999999999           // z-index property of the canvas, default: 999999999
          }
        ],
  • 效果图

image-20210712160757435.png

6、首页背景整屏显示

  • 修改首页README.md

    在根路径下

    # 原来的配置内容
    # heroImage: /hero.png
    # heroImageStyle: {
    #   maxWidth: '600px',
    #   width: '100%',
    #   display: block,
    #   margin: '9rem auto 2rem',
    #   background: '#fff',
    #   borderRadius: '1rem',
    # }
    bgImageStyle: {
      height: '450px'
    }
    ##############################
    #修改之后
    heroImageStyle: {
      maxWidth: '600px',
      width: '100%',
      display: block,
      margin: '9rem auto 2rem',
      background: '#fff',
      borderRadius: '1rem',
    }
    bgImage: back1.gif
    bgImageStyle: {
      height: '1000px'
    }

    back1.gif文件放在.vuepress下的public下即可,自己找个好看的动图吧。

  • 效果图

image-20210712161440108.png

7、首页气泡

  • 安装依赖: npm install vue-canvas-effect --save
  • 修改源码

    以前的在node_moudles/vuepress-theme-reco/components/Homeblog.vue,现在的在node_moudles/vuepress-theme-reco/components/HomeBlog/index.vue

    在methods方法上加入

      mounted (){
        import('vue-canvas-effect/src/components/bubbles').then(module => {
          this.bubbles=module.default
        })
        this.recoShow = true
        this._setPage(this._getStoragePage())
        },

    在27行加入

    <component v-if="bubbles" :is="bubbles" :options="options"></component>

    在components所在行下一行加入

      data () {
        return {
          recoShow: false,
          currentPage: 1,
          tags: [],
          bubbles: null
        }
      },

    完整的文件内容如下

    <template>
      <div class="home-blog">
        <div class="hero" :style="{ ...bgImageStyle }">
          <div>
            <ModuleTransition>
              <img
                class="hero-img"
                v-if="recoShowModule && $frontmatter.heroImage"
                :style="heroImageStyle || {}"
                :src="$withBase($frontmatter.heroImage)"
                alt="hero"
              />
            </ModuleTransition>
    
            <ModuleTransition delay="0.04">
              <h1 v-if="recoShowModule && $frontmatter.heroText !== null">
                {{ $frontmatter.heroText || $title || 'vuePress-theme-reco' }}
              </h1>
            </ModuleTransition>
    
            <ModuleTransition delay="0.08">
              <p v-if="recoShowModule && $frontmatter.tagline !== null" class="description">
                {{ $frontmatter.tagline || $description || 'Welcome to your vuePress-theme-reco site' }}
              </p>
            </ModuleTransition>
          </div>
          <component v-if="bubbles" :is="bubbles" :options="options"></component>
        </div>
    
        <ModuleTransition delay="0.16">
          <div v-show="recoShowModule" class="home-blog-wrapper">
            <div class="blog-list">
              <!-- 博客列表 -->
              <note-abstract :data="$recoPosts" @paginationChange="paginationChange" />
            </div>
            <div class="info-wrapper">
              <PersonalInfo/>
              <h4><reco-icon icon="reco-category" /> {{$recoLocales.category}}</h4>
              <ul class="category-wrapper">
                <li class="category-item" v-for="(item, index) in this.$categories.list" :key="index">
                  <router-link :to="item.path">
                    <span class="category-name">{{ item.name }}</span>
                    <span class="post-num" :style="{ 'backgroundColor': getOneColor() }">{{ item.pages.length }}</span>
                  </router-link>
                </li>
              </ul>
              <hr>
              <h4 v-if="$tags.list.length !== 0"><reco-icon icon="reco-tag" /> {{$recoLocales.tag}}</h4>
              <TagList @getCurrentTag="getPagesByTags" />
              <h4 v-if="$themeConfig.friendLink && $themeConfig.friendLink.length !== 0"><reco-icon icon="reco-friend" /> {{$recoLocales.friendLink}}</h4>
              <FriendLink />
            </div>
          </div>
        </ModuleTransition>
    
        <ModuleTransition delay="0.24">
          <Content v-show="recoShowModule" class="home-center" custom/>
        </ModuleTransition>
      </div>
    </template>
    
    <script>
    import { defineComponent, toRefs, reactive, computed, getCurrentInstance, onMounted } from 'vue-demi'
    import TagList from '@theme/components/TagList'
    import FriendLink from '@theme/components/FriendLink'
    import NoteAbstract from '@theme/components/NoteAbstract'
    import { ModuleTransition, RecoIcon } from '@vuepress-reco/core/lib/components'
    import PersonalInfo from '@theme/components/PersonalInfo'
    import { getOneColor } from '@theme/helpers/other'
    
    export default defineComponent({
      components: { NoteAbstract, TagList, FriendLink, ModuleTransition, PersonalInfo, RecoIcon },
      data () {
        return {
          recoShow: false,
          currentPage: 1,
          tags: [],
          bubbles: null
        }
      },
      setup (props, ctx) {
        const instance = getCurrentInstance().proxy
    
        const state = reactive({
          recoShow: false,
          heroHeight: 0
        })
    
        const recoShowModule = computed(() => instance && instance.$parent.recoShowModule)
    
        const heroImageStyle = computed(() => instance.$frontmatter.heroImageStyle || {})
    
        const bgImageStyle = computed(() => {
          const url = instance.$frontmatter.bgImage
            ? instance.$withBase(instance.$frontmatter.bgImage)
            : require('../../images/bg.svg')
    
          const initBgImageStyle = {
            textAlign: 'center',
            overflow: 'hidden',
            background: `url(${url}) center/cover no-repeat`
          }
    
          const { bgImageStyle } = instance.$frontmatter
    
          return bgImageStyle ? { ...initBgImageStyle, ...bgImageStyle } : initBgImageStyle
        })
        onMounted(() => {
         
          state.heroHeight = document.querySelector('.hero').clientHeight
          state.recoShow = true
        })
    
        return { recoShowModule, heroImageStyle, bgImageStyle, ...toRefs(state), getOneColor }
      },
      mounted (){
        import('vue-canvas-effect/src/components/bubbles').then(module => {
          this.bubbles=module.default
        })
        this.recoShow = true
        this._setPage(this._getStoragePage())
        },
      methods: {
        paginationChange (page) {
          setTimeout(() => {
            window.scrollTo(0, this.heroHeight)
          }, 100)
        },
        getPagesByTags (tagInfo) {
          this.$router.push({ path: tagInfo.path })
        }
      }
    })
    </script>
    
    <style lang="stylus">
    .home-blog {
      padding: 0;
      margin: 0px auto;
      .hero {
        margin $navbarHeight auto 0
        position relative
        box-sizing border-box
        padding 0 20px
        height 100vh
        display flex
        align-items center
        justify-content center
        .hero-img {
          max-width: 300px;
          margin: 0 auto 1.5rem
        }
    
        h1 {
          display: block;
          margin:0 auto 1.8rem;
          font-size: 2.5rem;
        }
    
        .description {
          margin: 1.8rem auto;
          font-size: 1.6rem;
          line-height: 1.3;
        }
      }
      .home-blog-wrapper {
        display flex
        align-items: flex-start;
        margin 20px auto 0
        padding 0 20px
        max-width $homePageWidth
        .blog-list {
          flex auto
          width 0
          .abstract-wrapper {
            .abstract-item:last-child {
              margin-bottom: 0px;
            }
          }
        }
        .info-wrapper {
          position -webkit-sticky;
          position sticky;
          top 70px
          overflow hidden
          transition all .3s
          margin-left 15px
          flex 0 0 300px
          height auto
          box-shadow var(--box-shadow)
          border-radius $borderRadius
          box-sizing border-box
          padding 0 15px
          background var(--background-color)
          &:hover {
            box-shadow var(--box-shadow-hover)
          }
          h4 {
            color var(--text-color)
          }
          .category-wrapper {
            list-style none
            padding-left 0
            .category-item {
              margin-bottom .4rem
              padding: .4rem .8rem;
              transition: all .5s
              border-radius $borderRadius
              box-shadow var(--box-shadow)
              background-color var(--background-color)
              &:hover {
                transform scale(1.04)
                a {
                  color $accentColor
                }
              }
              a {
                display flex
                justify-content: space-between
                align-items: center
                color var(--text-color)
                .post-num {
                  width 1.6rem;
                  height 1.6rem
                  text-align center
                  line-height 1.6rem
                  border-radius $borderRadius
                  background #eee
                  font-size 13px
                  color #fff
                }
              }
            }
          }
        }
      }
    }
    
    @media (max-width: $MQMobile) {
      .home-blog {
        .hero {
          height 450px
          img {
            max-height: 210px;
            margin: 2rem auto 1.2rem;
          }
    
          h1 {
            margin: 0 auto 1.8rem ;
            font-size: 2rem;
          }
    
          .description {
            font-size: 1.2rem;
          }
    
          .action-button {
            font-size: 1rem;
            padding: 0.6rem 1.2rem;
          }
        }
        .home-blog-wrapper {
          display block!important
          .blog-list {
            width auto
          }
          .info-wrapper {
            // display none!important
            margin-left 0
            .personal-info-wrapper {
              display none
            }
          }
        }
      }
    }
    
    @media (max-width: $MQMobileNarrow) {
      .home-blog {
        .hero {
          height 450px
          img {
            max-height: 210px;
            margin: 2rem auto 1.2rem;
          }
    
          h1 {
            margin: 0 auto 1.8rem ;
            font-size: 2rem;
          }
    
          h1, .description, .action {
            // margin: 1.2rem auto;
          }
    
          .description {
            font-size: 1.2rem;
          }
    
          .action-button {
            font-size: 1rem;
            padding: 0.6rem 1.2rem;
          }
        }
    
        .home-blog-wrapper {
          display block!important
          .blog-list {
            width auto
          }
          .info-wrapper {
            // display none!important
            margin-left 0
            .personal-info-wrapper {
              display none
            }
          }
        }
      }
    }
    </style>
    
  • 效果图

image-20210712165426562.png

8、向下跳转

  • 修改文件

    在首页README.md下加入如下代码

    <style>
    .anchor-down {
      display: block;
      margin: 12rem auto 0;
      bottom: 45px;
      width: 20px;
      height: 20px;
      font-size: 34px;
      text-align: center;
      animation: bounce-in 5s 3s infinite;
      position: absolute;
      left: 50%;
      bottom: 30%;
      margin-left: -10px;
      cursor: pointer;
    }
    @-webkit-keyframes bounce-in{
      0%{transform:translateY(0)}
      20%{transform:translateY(0)}
      50%{transform:translateY(-20px)}
      80%{transform:translateY(0)}
      to{transform:translateY(0)}
    }
    .anchor-down::before {
      content: "";
      width: 20px;
      height: 20px;
      display: block;
      border-right: 3px solid #fff;
      border-top: 3px solid #fff;
      transform: rotate(135deg);
      position: absolute;
      bottom: 10px;
    }
    .anchor-down::after {
      content: "";
      width: 20px;
      height: 20px;
      display: block;
      border-right: 3px solid #fff;
      border-top: 3px solid #fff;
      transform: rotate(135deg);
    }
    </style>
    
    <script>
    export default {
      mounted () {
        const ifJanchor = document.getElementById("JanchorDown"); 
        ifJanchor && ifJanchor.parentNode.removeChild(ifJanchor);
        let a = document.createElement('a');
        a.id = 'JanchorDown';
        a.className = 'anchor-down';
        document.getElementsByClassName('hero')[0].append(a);
        let targetA = document.getElementById("JanchorDown");
        targetA.addEventListener('click', e => { // 添加点击事件
          this.scrollFn();
        })
      },
    
      methods: {
        scrollFn() {
          const windowH = document.getElementsByClassName('hero')[0].clientHeight; // 获取窗口高度
          document.documentElement.scrollTop = windowH; // 滚动条滚动到指定位置
        }
      }
    }
    </script>
    
  • 效果图

image-20210712170119422.png

9、彩带背景

  • 安装依赖:npm i vuepress-plugin-ribbon-animation
  • 修改config.js下的plugins,可参考npm

    ["ribbon-animation", {
          size: 90,   // 默认数据
          opacity: 0.3,  //  透明度
          zIndex: -1,   //  层级
          opt: {
            // 色带HSL饱和度
            colorSaturation: "80%",
            // 色带HSL亮度量
            colorBrightness: "60%",
            // 带状颜色不透明度
            colorAlpha: 0.65,
            // 在HSL颜色空间中循环显示颜色的速度有多快
            colorCycleSpeed: 6,
            // 从哪一侧开始Y轴 (top|min, middle|center, bottom|max, random)
            verticalPosition: "center",
            // 到达屏幕另一侧的速度有多快
            horizontalSpeed: 200,
            // 在任何给定时间,屏幕上会保留多少条带
            ribbonCount: 2,
            // 添加笔划以及色带填充颜色
            strokeSize: 0,
            // 通过页面滚动上的因子垂直移动色带
            parallaxAmount: -0.5,
            // 随着时间的推移,为每个功能区添加动画效果
            animateSections: true
          },
          ribbonShow: false, //  点击彩带  true显示  false为不显示
          ribbonAnimationShow: true  // 滑动彩带
        }]
  • 效果图

image-20210712170647841.png

10、背景图

  • 修改文件

    在首页README.md下的style里设置body的背景图片,完成第8条的向下跳转,写入的style。

    body{
    
      background-image: url(背景图的url);
    
      }
  • 背景图

Ufb771a7d36b046f88b69aff276f000857.gif

  • 效果图如下

image-20210712171642504.png

三、最终的效果图

image-20210712172130703.png

image-20210712172147492.png

如果你在搭建过程中遇到问题,就在下方留言联系我。

目录
相关文章
|
7月前
|
JavaScript 前端开发 Go
8 大博客引擎 jekyll/hugo/Hexo/Pelican/Gatsby/VuePress/Nuxt.js/Middleman 对比
探索各类博客引擎:Jekyll、Hugo、Hexo、Pelican、Gatsby、VuePress、Nuxt.js和Middleman的对比,包括语言、模板引擎、速度、社区活跃度等。了解每种引擎的优缺点,助你选择合适的博客构建工具。查看详细文章以获取更多实战和安装指南。
|
7月前
|
搜索推荐
【卡夫卡的岛上书店】:一个利用 vuepress 的主题 vuepress-theme-reco 以及 vuepress-theme-vdoing 搭建自己的静态博客
【卡夫卡的岛上书店】:一个利用 vuepress 的主题 vuepress-theme-reco 以及 vuepress-theme-vdoing 搭建自己的静态博客
101 0
|
前端开发 Cloud Native 安全
简单使用 Hugo 博客
简单使用 Hugo 博客
133 0
|
前端开发
【Butterfly美化】Hexo Butterfly主题使用阿里巴巴iconfont
Butterfly主题支持 font-awesome v6 但是还是不够用怎么办呢?可以使用阿里巴巴iconfont来拓展啦,今天教大家在Hexo中使用阿里巴巴iconfont矢量图标库。
586 0
|
JavaScript 前端开发 API
VuePress 手摸手教你搭建Vue风格的技术文档/博客
通过阿里云云开发平台 VuePress项目手摸手教你快速搭建Vue风格的技术文档/博客。
771 1
VuePress 手摸手教你搭建Vue风格的技术文档/博客
Hexo + Butterfly 从零开始搭建个人博客系列
Hexo + Butterfly 从零开始搭建个人博客系列 简单漂亮,文章内容美观易读 Material Design 设计 响应式设计,博客在桌面端、平板、手机等设备上均能很好的展现 瀑布流式的博客文章列表(文章无特色图片时会有 24 张漂亮的图片代替) 时间轴式的归档页 丰富的关于我页面(包括关于我、文章统计图、我的项目、我的技能、相册等) 可自定义的数据的友情链接页面 支持文章置顶和文章打赏 支持 MathJax 可设置复制文章内容时追加版权信息 Gitalk、Gitment、Valine 和 Disqus 评论模块 支持在首页的音乐播放和视频播放功能
312 0
Hexo + Butterfly 从零开始搭建个人博客系列
|
弹性计算 JSON JavaScript
安装 VuePress | 学习笔记
快速学习安装 VuePress。
|
JavaScript 开发者 SEO
vuepress入门教程
vuepress入门教程
1489 0