Single page application built with vue+webpack-the birth of private blog MintloG

  php, spa, vue.js, webpack

Introduction

Project address:https://github.com/jrainlau/MintloG(especially messy, just refer to-_-| |)
图片描述
MintloG is a private blog that I completely developed by myself within five days. The front-end technical scheme adopts the construction scheme of Vue+Vue-Router+Vue-Resource+Web Pack, while the back-end technology adopts native PHP+MySQL. Blog is completely realized by ajax and communicates with the background. The background only provides one interface and realizes different functions of adding, deleting, modifying and checking by passing in different parameters. At the same time, the blog realizes route management through vue-router, switches functions through route switching, has no page refresh and jump, and is 100% single-page application.

The inspiration for the design comes from the fresh mint green, because the recent southerly days are disgusting, “freshness” is the most urgent demand, so the brighter mint green is used as the main color. But because my notebook is an old machine bought in 12 years, the screen is relatively poor, and the colors seen from different angles will be different, so I don’t know exactly what the mint green looks like here …

Let’s look at what MintloG looks like-

home page

图片描述
The first page mainly has three parts, namely navigation bar, article list and classification panel.

  • Navigation bar: the “home page” button on the left allows you to quickly return to the home page. Logo; with MintloG in the middle; On the right is the writing button. Click to switch to the writing function.

  • Article list: click on the article title to enter and view the article details, click on the time or label to quickly filter; The delete button can directly delete the article.

  • Classification panel: You can classify the list of articles by entering title keywords, clicking labels or time.


Details of the article

图片描述
Click “edit” and you will enter the editing page.
图片描述
The article can be modified.


Write an article

Click the write button in the upper right corner to enter the write page. The input window on the left supports markdown syntax and will output the compiled text in real time in the window on the right.
图片描述
Submit and Prompt for Success
图片描述
When you click OK, you will jump back to the front page and see the newly written article.
图片描述


look-up function

You can query through the title, label and modification time of the article.
图片描述
图片描述
图片描述
What is the difference between the routes on the address bar?


Delete function

Click the delete button and confirm that the corresponding article will be deleted and the list will be re-rendered. (I am too lazy to show the picture here)


Backstage construction

After introducing MintloG’s function of adding, deleting, modifying and checking, let’s take a look at how the backstage is built.
I use native PHP to write the background, because I feel that the function of adding, deleting, modifying and checking is very simple, so I don’t bother to use the framework (actually I won’t).

I am hereconn_sql.phpA new class has been created to link the database and provide the function of operating the database:

<?  php
 //Connect to Database (singleton pattern)
 class ConnMySQL {
 protected static $_connect = null;
 protected $dbName;
 protected $dsn;
 protected $pdoObj;
 
 //initialization
 private function __construct($host, $user, $pwd, $dbName) {
 try {
 $this->dsn = 'mysql:host='.$host.';  dbname='.$dbName;
 $this->pdoObj = new PDO($this->dsn, $user, $pwd);
 $this->pdoObj->query("set names utf8");
 } catch (PDOException $e) {
 echo $e->getMessage();
 }
 }
 
 //Prevent cloning
 private function __clone(){}
 
 //Returns an instantiated PDO object
 public static function makeConnect($host, $user, $pwd, $dbName) {
 if (self::$_connect === null) {
 self::$_connect = new self($host, $user, $pwd, $dbName);
 }
 return self::$_connect;
 }
 
 //Define Query Methods
 public function query($db, $sqlState = null, $sqlVal=null) {
 if(!  $sqlState) {
 $_result = $this->pdoObj->query("select * from $db");
 } else {
 $_result = $this->pdoObj->query("select * from $db where $sqlState like '%".trim($sqlVal)."%'");
 }
 return $_result;
 }
 
 //Define Add Method
 public function insert($db, $where, $what) {
 $_result = $this->pdoObj->exec("insert into $db ($where) values ($what)");
 return $_result;
 }
 
 //Define deletion method
 public function delete($db, $where) {
 $_result = $this->pdoObj->exec("delete from $db where $where");
 return $_result;
 }
 
 //Define Update Methods
 public function updata($db, $what, $where) {
 $_result = $this->pdoObj->exec("update $db set $what where $where");
 return $_result;
 }
 
 //disconnect from the database
 public function destruct()
 {
 $this->pdoObj = null;
 }
 }
 ?  >

The difficulty actually lies in how “singleton pattern” should instantiate a PDO, I guess … and then inoption.phpThe above class is introduced into the file and is retrieved by$_POST[]Get parameters andechoThe corresponding return information. Because it is an ajax application and involves cross-domain issues, I added this sentence at the beginning of the file.header("Access-Control-Allow-Origin:*");The cross-domain problem has been properly solved.

After the backstage was finished, phpMyAdmin set up a MySQL database and a table to store all kinds of information of articles. The basic function of blog is actually tossing about on this table.
图片描述
Well, it’s just casual.


Ui design

“The front end that does not understand design is not a good boss”.
Don’t understand can learn ~
So I did my first UI design while learning and doing … so if the reader thinks MintloG looks ugly, please hit the brick at me directly! I’ll pick up all your bricks and sell them …
In fact, it was even uglier when it was first designed …
图片描述
There are still some UI specifications: unified to15pxAs the spacing of similar elements,30pxSpacing as a non-homogeneous element. There are no more than 5 colors on the page, and the elements are distinguished by shading.
I really love google’s MD style, so the trace of imitation is quite heavy. Although not very like.
Because of laziness, I didn’t use css framework and didn’t make response style.


Front-end construction

Because vuejs is planned to be adopted, the official vue-cli is adopted to generate the project, and vue-router and vue-resource are installed as routing management and resource request tools.
The file directory is as follows:

--- /MintloG project home directory
 |
 --- /bower_component third-party library
 |
 --- /src
 |
 --- /components components *.vue folder
 |       |
 --- blog-article.vue article details
 |
 --- blog-head.vue navigation bar
 |
 --- blog-list.vue article list
 |
 --- blog-search.vue search box
 |
 --- blog-tags.vue tag bar
 |
 --- blog-timeline.vue timeline
 |
 --- browse-mode.vue browse mode parent component
 |
 --- toolbox.vue edit page toolbar
 |
 --- write-panel.vue edit page
 |
 --- main.js entry js file (route control)
 |
 --- App.vue main program file
 |
 --- /lib third party files
 |
 --- /image Picture Resources

It can be seen that MintloG is formed by combining different components, which conforms to the idea of componentization and is more convenient to maintain and modify in the future. Because the project is relatively simple, vuex is not used as state management, but “sub-component-parent component-sub-component” is adopted to realize state sharing. For specific implementation, please refer to one of my demohttps://github.com/jrainlau/vuejs-demo

The key part ismain.jsFile, as an entry file, defines the meaning of different routes:

router.map({
 '/': {
 component: browseMode,
 subRoutes: {
 '/': {
 component: blogList
 },
 '/details/:artId': {
 component: blogArticle
 }
 }
 },
 '/edit/:mode': {
 component: writePanel
 },
 '/search/tag/:tag': {
 component: browseMode,
 subRoutes: {
 '/': {
 component: blogList
 }
 }
 },
 '/search/time/:time': {
 component: browseMode,
 subRoutes: {
 '/': {
 component: blogList
 }
 }
 },
 '/search/title/:title': {
 component: browseMode,
 subRoutes: {
 '/': {
 component: blogList
 }
 }
 },
 })

AndApp.vueAs a parent component:
图片描述
It’s loadedblog-head.vueAs a navigation bar, through<router-view>Switch between browse mode and edit mode.

  • Browse modebrowseMode.vue
    图片描述

It also has one<router-view>, used to switch between “article list” and “article details”, that isblog-list.vueAndblog-article.vue

  • Edit mode
    图片描述

It’s loadedtoolbox.vueAs a toolbar, you can then write and modify articles. This editing page reuses Markcook, a former project of mine, and can be seen here ~
https://github.com/jrainlau/markcook

The comparison needs to be carried out in terms of the switching of nested corresponding components of routes and the state update required for each switching of routes. However, vue-router has considered these issues very carefully, and a careful study of official documents can solve most of the problems. Specific component nesting and combination forms are shown in the figure:
图片描述

In ajax communication, vue-resource is used for the first time, which is a bit more complicated than jquery. Especially for configuration items, the json format of the requestor needs to be configured globally in order to normally send the requested parameters:

import VueRouter from 'vue-router'
 Vue.use(VueRouter)
 Vue.http.options.emulateJSON = true;

Of course, we pay more and get more. The response object returned by vue-resource will also have status code, status description, request header, etc. for more complicated use.
图片描述

In the aspect of content update, since it is a single-page application, refresh operation is not recommended, because unnecessary resource requests will be generated and resources will be wasted, so content update is realized through “re-rendering”. For example, inbrowseMode.vueI have defined agetList()Method for obtaining data:
图片描述
I can pass any time I need to “refresh”this.$emit('getList')To trigger this method, the content is re-rendered to the page to realize the function of content update.


Postscript

After writing so much, I finally introduced the birth of MintloG. In fact, the main purpose is to be a record of my growth. In a week, from completely not knowing the background development to mastering the use of PHP and MySQL, I completed the background construction, UI design, front-end construction in 5 days. A MintloG gave me much more than the knowledge itself, and my graduation design was finally completed! The best way to learn is to apply what you have learned, continue to cheer up ~