Vue.js+Github build personal website GithubPages

I. Introduction

github.io is a domain name that each Github account can own for free. The pages deployed on this domain name are called Github Pages . Users have a high degree of autonomy to DIY their own "personal website".

Usually, users will use it as their own blog website to store some blogs, collections, resumes, etc. The industry's more mature personal blog website template is Hexo, which is based on Node.js and can quickly generate a set of blog pages that can be run The code, the user adds his own article and configures the relevant information, then compiles and pushes it to the github.io warehouse, and Github will automatically deploy the page to the server. Not only that, Hexo provides a variety of template themes to choose from.

If you use such a theme, you may "bump your shirt" with others. After all, many people often see pages with the same template. In order to have a unique website, the blogger once implemented a blog website — universezy.github.io , which can also achieve good results with the open source UI library. Later, some colleagues were interested in this and wanted to try it, so I decided to introduce how to create a unique GithubPages by myself through this article.


2. Preparation

Before that, you need to have the following knowledge:

  • H5+ES6+CSS3: Because it is a web page, it needs a foundation for front-end development.
  • Vue.js: This article is based on the development of Vue.js among the three mainstream front-end frameworks. Because of its easy-to-learn and quick-to-use characteristics, it is suitable for instant beginners.
  • Node.js: The construction of the project is based on Node.js, so a certain Node foundation is required to be able to configure parameters and compile and debug the project.
  • Http/Https: Resource requests, page routing, etc. involved in web pages require a basic network programming foundation.
  • Github: Finally, and the most important link, you need a Github account and some experience in using it.

In addition to the above preparations, you also need some knowledge to complete several core functions, which will be mentioned in the follow-up function implementation.

The entire development cycle may take a week to more than a month, and various difficult problems will be encountered in the middle, so sufficient patience and learning ability are required.


3. Create a warehouse

Create a warehouse in Github, the name has a fixed format: account name + ".github.io":

insert image description here

Github will recognize this as your personal web page and deploy it to the server:

insert image description here

By accessing your domain name: account name + ".github.io", you can see the currently deployed page. Due to the lack of index.htmlfiles, the contents of the files are displayed README.md:

insert image description here

Next, the front-end page will be formally developed.


4. Architecture design

4.1 Technology selection

First of all, it is necessary to select the main technologies that the entire project relies on:

  • Based on Vue.js development, then I use Vue-CLI scaffolding to create projects
  • If you want to have a beautiful interface, you have to rely on a three-party UI library. Here I recommend iView (now called View UI)
  • Use Json for data interaction
  • It is recommended to use Google Analytics for statistical reporting , which is not introduced in the article, and readers can learn by themselves

4.2 Core Functions

Refer to the Hexo template and several mainstream open source blogging website platforms, which mainly include the following functional modules:

  • Navigation bar: used to switch between different modules
  • Homepage: Show recently updated content, notification announcements, etc.
  • Personal information: display some personal information, and you can also put a resume so that interested people can extend an olive branch
  • Blogging: blogs written, content shared, etc.
  • Favorites: recommended books, websites, etc.
  • Friend Chain: One of the channels for mutual promotion among friends
  • About: Some information about this page

4.3 B/S Architecture

Our blog resources, pictures, etc. are ultimately stored in the Github warehouse, so when the network requests these resources, we need to know the request address of the resources.

Even if we don't know the warehouse architecture on Github's server, we can infer a reasonable architecture through experience:
insert image description here

(1) Resource request

A git repository is considered a folder:

  • For the inside of the project, based on the directory structure, relative paths are used for access.
  • For external networks, based on url, use absolute addresses for access.

(2) Project location

The background server loads the index.html file in the root directory of the warehouse, so the project we initialize needs to use the root directory of the warehouse as the root directory, otherwise we need to handle the redirection by ourselves.


4.4 Engineering Architecture

insert image description here

The entire webpage project includes three top-level structures:

  • Base: the part loaded directly by the server
  • Component&Data: Web UI components and local configuration data
  • Service: The service that supports the basic functions of the entire web page

It will be described in detail below.


1. Base

This layer is centered on the index.html required by the server to load the page. js can handle redirection related logic, page event monitoring, etc., and css can do some global background effects.

According to the default structure of the Vue.js project, the block with id in index.html appis the top-level parent layout of all subsequent UI components.

Therefore, this layer is understood as the top-level container .


2. Component&Data

According to the idea of ​​Vue.js modular design, the above core functions correspond to a module, that is, a vue file, which is assembled or replaced to achieve the UI effect we need.

Since some local data will be involved, such as: blog configuration (title, abstract, classification, tags, date, etc.), banners, notices, etc., these can be saved in files in Json format.

In addition, some local image resources also need to be saved in the resource directory.

Therefore, this layer is mainly responsible for the content of the page .


3. Service

An interactive webpage, the essential basic capabilities include: routing management, status management, network requests, etc. In addition, it usually supports three-party sharing and statistical reporting.

  • Routing management: switching before core functions, or sub-page tab switching, all need to use routing
  • State management: It is equivalent to a global variable management of a temporary cache, such as the expansion-collapse state of the navigation bar, and the closing event of the advertising space
  • Network request: Every blog Markdown file and image resource needs to be pulled through a network request
  • Three-party sharing: share blogs to mainstream social platforms, or generate QR codes for dissemination
  • Statistical reporting: In order to better know how many people browse our webpage and the visit status of each subpage, you can access the js library for statistical reporting

It can be seen that this layer belongs to the basic capability .


5. Function realization

According to the above function points and architecture, the core technical solution is explained below.

5.1 Routing Management

(1) Page Routing

Using the default Router library, each module corresponds to a page, for example:

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) Fault tolerance mechanism

Considering that there is no route under the default url address, and the routing address cannot be matched, it is necessary to add the default and exception conditions:

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

redirect it to the correct route.

(3) carry parameters

For example, if we want to splice the id of the blog in the url, and then directly open the corresponding page, we can first process the parameters in the route:

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

In this way, /blog/display/the string immediately following the url will be recognized as a parameter, and the parameter needs to be obtained in the Vue file:

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

this.$route.params.xxxGet route parameters by .


5.2 State Management

Using the officially recommended Vuex , in addition to saving some global variables, you can also cache resources requested by the network to avoid the overhead caused by repeated requests. For example, I defined a js named GlobalDtata, which can cache bio files for network requests. The page title constant is also defined:

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
}

Then where to get the bio file:

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 Network Request

The official recommendation is the promise-based HTTP client axios , which is very simple to use. First, it encapsulates the general request method:

import axios from 'axios'

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

Then call and handle the callback:

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 Three-party sharing

Taking the commonly used QQ, QZone, WeChat, and Weibo as examples, except WeChat can only be opened in the form of a QR code, the rest can support web sharing:

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 QR code generation

The blogger recommends the open source library qrcodejs .

First introduce project dependencies ( npm version information ) through npm:

npm install qrcodejs2 --save

Provide a display area:

<div id="qrcode"></div>

Then dynamically generate in 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 display

There is no doubt that the blog page uses the Markdown format, and the open source library mavonEditor is recommended here .

It is still introduced through npm first ( npm version information ):

npm install mavon-editor --save

Use the component in the page:

<mavon-editor
  class="markdown"
  v-model="blogData"
  :subfield="settingsMd.subfield"
  :defaultOpen="settingsMd.defaultOpen"
  :navigation="settingsMd.navigation"
  :codeStyle="settingsMd.codeStyle"
  :boxShadow="settingsMd.boxShadow"
  :previewBackground="settingsMd.previewBackground"
  :toolbarsFlag="settingsMd.toolbarsFlag"
  :toolbars="settingsMd.toolbars"/>

Set related properties in 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 Responsive layout

In order to make our web pages better displayed on different devices (PC, Phone, etc.), we need to consider the implementation of layout during development, and responsive layout is to solve this problem.

Usually there are two directions to implement responsive layout:

  • Flexible layout flex: Use flex-related H5 components and css attributes to passively change the style when the page is displayed. No examples are given here, and readers can refer to the information by themselves.
  • Media query media: Set various threshold monitoring to make the page actively change the style. The following is a simple example.

Set the style in 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;
  }
}

This code indicates that the component with the id app has the following effects:

  • When the screen width is 1200-1500 pixels, the left and right margins are 100 pixels
  • When the screen width is 1000-1200 pixels, its left and right margins are 50 pixels
  • When the screen width is within 1000 pixels, its left and right margins are 0 pixels

5.8 Data configuration

Whether it is Hexo or a custom blog, the configuration of blog data is inevitable, that is, the id, category, title, tag, abstract, timestamp, etc. of each blog.

Taking blogger's personal homepage as an example, create a blogs.jsfile dedicated to configuring all blog information:

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
}

On the page displaying the blog, obtain the blog id through routing, and then make a network request to obtain the corresponding Markdown resource and display it.

On the overview page, when it is necessary to display all blog items, first define the style of each item so that the list can be reused, and the layout display is omitted here.

Then get the blog js data in the parent container and load it into a list:

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])
      }
    }
  }
}

Some filtering operations may be performed in the middle, and finally propsthe item is passed to the child component through attributes:

<div class="div_microblog" v-for="item in displayBlogs" :key="item.id">
  <comMicroBlog :microblog="item" wide :showIcon="propShowIcon"></comMicroBlog>
</div>

6. Release

When we are all developed, compile the Vue.js project, and then push the entire github.io warehouse to the remote warehouse, and the github server will automatically replace the new resources later.

So far, our personal webpage Github Pages developed based on Vue.js has been completed.


Seven. Summary

The workload of completing a blog website independently is really heavy, and there will be a lot of pitfalls during the period, so enough patience and perseverance are required. In addition, there are quite a lot of technology stacks involved, which can also play a role in the growth of knowledge. Finally, I hope that interested readers can also develop their own satisfactory websites. If you have any questions, please contact me by email. I am happy to communicate with you!

Guess you like

Origin blog.csdn.net/zy13608089849/article/details/108165564