Vue.js+Github打造个人网站GithubPages 您所在的位置:网站首页 instagram个人网站 Vue.js+Github打造个人网站GithubPages

Vue.js+Github打造个人网站GithubPages

2023-07-14 05:17| 来源: 网络整理| 查看: 265

一、 前言

github.io是每个Github账号可以免费拥有的一个域名,这个域名上部署的页面,称之为Github Pages,用户有高度自主权去DIY自己的“个人网站”。

通常,用户会将其用来作为自己的博客网站,存放一些博客、收藏、简历等,业界比较成熟的个人博客网站模板是Hexo,它基于Node.js,能快速生成一套可运行成博客页面的代码,用户将自己的文章加入并配置好相关信息,然后编译,推送到github.io仓库中,Github会自动将页面部署到服务器。不仅如此,Hexo上提供丰富多样的模板主题,可供选择。

如果使用这样的主题,可能和别人“撞衫”,毕竟很多人经常看到模板一样的页面。为了有独一无二的网站,博主曾经自己实现了一个博客网站——universezy.github.io,配合开源的UI库,也能达到不错的效果。之后也有同事对此感兴趣,想尝试,所以决定通过本文介绍如何自己打造一个独一无二的GithubPages。

二、 准备工作

在此之前,你需要具备以下知识:

H5+ES6+CSS3: 由于是web页面,需要有前端开发的基础。Vue.js: 本文基于三大主流前端框架中的Vue.js进行开发,因为其易学上手快的特点,适合速成新人。Node.js: 工程的构建基于Node.js,因此需要有一定的Node基础,能配置参数和编译调试工程。Http/Https: 网页中涉及到的资源请求、页面路由等,需要有基本的网络编程基础。Github: 最后,也是最重要的环节,需要一个Github账号,以及有一定的使用经验。

在以上准备工作之外,你还需要一些知识,用以完成几个核心功能,这将在后续功能实现中提到。

整个开发周期可能需要一周到一个月以上,中间会遇到各种疑难问题,因此需要有足够的耐心和学习能力。

三、 创建仓库

在Github中创建一个仓库,名字有固定格式:帐号名+“.github.io”:

在这里插入图片描述

Github会将其识别为你的个人网页,并将其部署到服务器:

在这里插入图片描述

通过访问你的域名:帐号名+“.github.io”,可以看到当前部署的页面,由于缺少index.html文件,所以显示的是README.md文件的内容:

在这里插入图片描述

接下来便正式开发前端页面。

四、 架构设计 4.1 技术选型

首先,需要对整个工程所依赖的主要技术进行选型:

基于Vue.js开发,那么我使用Vue-CLI脚手架来创建工程要想有漂亮的界面,还得依靠三方UI库,这里推荐iView(现叫View UI)数据交互选用Json统计上报推荐使用Google Analytics,文中不作介绍,读者可自行学习 4.2 核心功能

参考Hexo的模板、几个主流开源博客网站平台,主要包括了以下几个功能模块:

导航栏:用来在不同模块之间切换主页:展示近期更新的内容、通知公告等个人资料:展示一些个人信息简介,也可以放简历,以便感兴趣的人伸出橄榄枝博客:写的博客,分享的内容等收藏:推荐的好书、网站等友链:好友间相互推广的渠道之一关于:该网页的一些信息 4.3 B/S架构

我们的博客资源、图片等,最终是存放在Github仓库上,那么网络请求这些资源时,就需要清楚资源的请求地址。

即便我们不清楚Github的服务器上的仓库架构,我们通过经验也能推测出来一个合理的架构: 在这里插入图片描述

(1) 资源请求

一个git仓库看做是一个文件夹:

对于工程内部,基于目录结构,使用相对路径进行访问。对于外部网络,基于url,使用绝对地址进行访问。

(2) 工程位置

后台服务器加载的是仓库根目录下的index.html文件,那么我们初始化的工程需要以仓库根目录为根目录,否则需要自己处理重定向。

4.4 工程架构

在这里插入图片描述

整个网页工程,包括三大顶层结构:

Base:服务器直接加载的部分Component&Data:网页UI组件和本地配置数据Service:支撑整个网页基础功能的服务

下面将详细介绍。

1. Base

这一层以服务器加载页面所需的index.html为中心,js中可以处理重定向相关逻辑,页面事件监听等,而css可以做一些全局的背景效果。

按照Vue.js工程默认结构,index.html中的id为app的块,便是后面所有UI组件的顶层父布局。

因此这一层理解为顶层容器。

2. Component&Data

按照Vue.js模块化设计的思想,上面的核心功能分别对应一个模块,即vue文件,进行组装或替换,以实现我们需要的UI效果。

由于会涉及到一些本地数据,例如:博客配置(标题,摘要,分类,标签,日期等),横幅,通知告示等,这些可以以Json格式保存于文件中。

除此之外,一些本地图片资源也需要保存于资源目录下。

所以,这一层主要是负责页面内容。

3. Service

一个可交互的网页,必不可少的基础能力包括:路由管理、状态管理、网络请求等,除此之外,通常还会支持三方分享和统计上报。

路由管理:核心功能之前切换,或者子页面tab切换,均需要使用路由状态管理:相当于一个临时缓存的全局变量管理,比如导航栏的展开-收起状态,广告位的关闭事件网络请求:每一篇博客Markdown文件、图片资源,都需要通过网络请求拉取三方分享:将博客分享到主流社交平台,或生成二维码进行传播统计上报:为了更好地知道我们的网页有多少人浏览,每个子页面的访问情况,可以接入统计上报的js库

由此可见,该层属于基础能力。

五、 功能实现

依照上面的功能点和架构,下面对核心技术方案进行讲解。

5.1 路由管理

(1) 页面路由

使用默认的Router库,每一个模块对应一个页面,例:

import Vue from 'vue' import Router from 'vue-router' import home from '@/components/home' import blog from '@/components/blog' Vue.use(Router) export default new Router({ routes: [ { path: '/home', name: 'home', component: home }, { path: '/blog', name: 'blog', component: blog } ] })

(2) 容错机制

考虑到默认url地址下没有路由,以及无法匹配的路由地址,需要加入默认情况和异常情况:

[ { path: '*', name: 'error', redirect: '/home', component: home }, { path: '/', name: 'home-default', redirect: '/home', component: home } ]

将其重定向到正确的路由。

(3) 携带参数

比如我们想在url中拼接博客的id,然后直接打开对应页面,则可以先在路由中处理参数:

[ { path: '/blog/display/:id', name: '/blog/display', component: display } ]

这样一来,url中/blog/display/后面紧跟的字符串将被识别为参数,同时还需要在Vue文件中获取参数:

export default { data () { return { id: 0 } }, created () { this.init() } methods: { init: function () { this.id = this.$route.params.id } } }

通过this.$route.params.xxx的方式获取路由参数。

5.2 状态管理

使用官方推荐的Vuex,除了可以保存一些全局变量,还可以缓存网络请求的资源,避免重复请求带来的开销,例如,我定义了一个名为GlobalDtata的js,其中可以缓存网络请求的bio文件,也定义了网页标题常量:

import * as types from '../mutation-types' const state = { bio: null, title: '进击的小宇宙' } const mutations = { [types.SAVE_BIO] (state, bio) { state.bio = bio } } const actions = { saveBio ({commit}, bio) { commit(types.SAVE_BIO, bio) } } export default { state, mutations, actions }

那么在获取该bio文件的地方:

export default { data () { return { bio: 'Loading...' } }, created () { this.load() } methods: { load: function () { if (this.$store.state.GlobalData.bio !== null) { this.bio = this.$store.state.GlobalData.bio } else { // request source } } } } 5.3 网络请求

官方推荐的是基于promise的HTTP客户端axios,其使用非常简单,首先是封装通用请求方法:

import axios from 'axios' export default { fetch (url) { return axios({ method: 'get', url: url, timeout: 10000, withCredentials: false }) } }

然后调用并处理回调:

requestApi.fetch(markdownApi.getBioUrl()) .then((response) => { if (response.status === 200) { _this.bio = response.data _this.$store.dispatch('saveBio', response.data) } else { _this.requestFailed() console.log('response status: ' + response.status) } }) .catch(error => { console.log(error) }) } 5.4 三方分享

以常用的QQ、QQ空间、微信、微博分享为例介绍,除了微信只能以二维码形式打开,其余均可以支持web分享方式:

const baseQQShareUrl = 'http://connect.qq.com/widget/shareqq/index.html' const baseQZoneShareUrl = 'http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey' const baseWeiboShareUrl = 'http://service.weibo.com/share/share.php' export const shareBlogApi = { getQQUrl: (blog) => { var url = baseQQShareUrl + '?url=' + blog.url + '&pics=' + blog.pic + '&title=' + blog.title + '&summary=' + blog.abstract return encodeURI(url) }, getQZoneUrl: (blog) => { var url = baseQZoneShareUrl + '?url=' + blog.url + '&pics=' + blog.pic + '&title=' + blog.title + '&summary=' + blog.abstract return encodeURI(url) }, getWeiboUrl: (blog) => { var url = baseWeiboShareUrl + '?url=' + blog.url + '&pic=' + blog.pic + '&title=' + blog.title + '&content=' + 'utf-8' return encodeURI(url) } } 5.5 二维码生成

博主推荐开源库qrcodejs。

首先通过npm引入至工程依赖(npm版本信息):

npm install qrcodejs2 --save

提供一块显示区域:

然后在js中动态生成:

import QRCode from 'qrcodejs2' var qrcode = null export default { methods: { createQrcode: function () { qrcode = new QRCode('qrcode', { text: this.getValidUrl(), width: 100, height: 100, colorDark: '#17233d', colorLight: '#f8f8f9', correctLevel: QRCode.CorrectLevel.H }) }, updateQrcode: function () { if (qrcode === null) { this.createQrcode() } else { qrcode.clear() qrcode.makeCode(this.getValidUrl()) } } } } 5.6 Markdown展示

博客页面毫无疑问选用Markdown格式,这里推荐开源库mavonEditor。

仍然是先通过npm引入(npm版本信息):

npm install mavon-editor --save

在页面中使用组件:

在js中置相关属性:

export default { data () { return { settingsMd: { subfield: false, // 单双栏模式 defaultOpen: 'preview', // 默认展示 navigation: false, // 导航目录 codeStyle: 'xcode', // 配色方案 boxShadow: false, // 开启边框阴影 previewBackground: '#f9f5f9', // 预览框背景颜色 toolbarsFlag: false, // 工具栏是否显示 toolbars: { fullscreen: true, // 全屏编辑 readmodel: true, // 沉浸式阅读 help: true, // 帮助 navigation: true // 导航目录 } }, blogData: 'Loading...' } } } 5.7 响应式布局

为了让我们的网页能较好地展示在不同设备(PC,Phone等)上,需要在开发时考虑布局的实现方式,而响应式布局便是为了解决这个问题。

通常实现响应式布局有两个方向:

弹性布局flex:使用flex相关的H5组件和css属性,使得页面展示时被动改变样式,这里不举例,读者可自行查阅资料。媒体查询media:设置各种阈值监听,使得页面主动改变样式,下面以一个简单例子为介绍。

在App.vue中设置样式:

@media screen and (max-width: 1500px) { #app { margin: 0 100px; -webkit-transition: all 0.5s; -moz-transition: all 0.5s; transition: all 0.5s; } } @media screen and (max-width: 1200px) { #app { margin: 0 50px; -webkit-transition: all 0.5s; -moz-transition: all 0.5s; transition: all 0.5s; } } @media screen and (max-width: 1000px) { #app { margin: 0; -webkit-transition: all 0.5s; -moz-transition: all 0.5s; transition: all 0.5s; } }

这段代码表示,对id为app的组件有以下效果:

当屏幕宽度在1200-1500像素时,其左右外边距为100像素当屏幕宽度在1000-1200像素时,其左右外边距为50像素当屏幕宽度在1000像素以内时,其左右外边距为0像素 5.8 数据配置

不管是Hexo还是自定义博客,都免不了对博客数据的配置,即每篇博客的id、类别、标题、标签、摘要、时间戳等。

以博主的个人主页为例,创建一个blogs.js的文件,专用于配置所有博客信息:

const blogs = [ { id: 'AndroidPerformanceOfMemory1', category: 'Android', title: 'Android性能优化之内存优化', tags: [ {tag: '性能优化'}, {tag: '内存优化'} ], abstract: '本章内容基于Android Q,介绍Android性能优化中的内存优化方面,通过排查、检测、规避和表现等四个方面的讲解,让更多的开发者有能力去改善或设计出更优质的程序。', timestamp: 1578310912658 }, { id: 'AndroidPerformanceOfMemory2', category: 'Android', title: 'Android性能优化之内存优化——内存泄漏篇', tags: [ {tag: '性能优化'}, {tag: '内存优化'}, {tag: '内存泄漏'} ], abstract: '本文介绍Android开发中的常见内存泄漏场景和解决方案。', timestamp: 1578311006725 } ] export default { blogs }

在展示博客的页面,通过路由获取博客id,然后网络请求获取对应Markdown资源并展示。

而在总览页面,需要显示所有博客Item时,先定义每个Item的样式,以便列表复用,这里省略布局展示。

然后在父容器中获取博客js数据,并加载到列表中:

import mBlogs from '../data/blogs' export default { data () { return { originBlogs: [] } } methods: { loadOriginBlogs: function () { this.originBlogs = [] for (var i = mBlogs.blogs.length - 1; i >= 0; i--) { this.originBlogs.push(mBlogs.blogs[i]) } } } }

中间可能会经过一些过滤操作,最后通过props属性将item传给子组件:

六、 发布

当我们全部开发完后,对Vue.js工程进行编译,然后将整个github.io仓库push到远程仓库,稍后github服务器将自动替换新的资源。

至此,我们的基于Vue.js开发的个人网页Github Pages便大功告成。

七、 总结

独立完成一个博客网站的工作量确实较重,期间还会踩非常多的坑,因此需要足够的耐心和毅力,除此之外,涉及的技术栈也是蛮多的,对知识的成长也能起到较大的帮助,最后,希望感兴趣的读者也能开发出自己满意的网站,如果有问题,可通过邮件与我联系,很乐意与你交流!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有