preface

I used Vue to develop background and mid-stage projects, as well as mobile TERMINAL H5 and a small front-end architecture. I gained different experience and understanding from each project. Below, I sum up the experience of these dribs and drabs to make a series of articles to share and periodic summary.

General operation, first click “like” after watching oh! Your praise is one of the motivations for my creation!

An overview of


The problem

I will discuss some of the techniques and principles of vUE development from 16 aspects. Of course, due to the limited space, the first 8 questions will be discussed first, and the next section will complete the whole series.

This article will focus on the following issues:

  • How to standardize your Git commit and automatically generate and commit logs?
  • How can you configure and use Sass and PUG to improve your coding efficiency?
  • How to deal with your code style issues, and how to use PertTier and ESLint to solve the efficient style dilemma?
  • How to manage page routing, how to write asynchronous routing?
  • How do you write components and import component libraries?
  • How do you manage your resources, how do you introduce ICONS, styles?
  • How to encapsulate your AXIos and manage your API?
  • How can YOU mock your data to achieve real separation of front and back ends?

practice

Before you practice: I hope you have the following preparation, or knowledge.

  • To understandnpm/yarn/git/sass/pug/vue/vuex/vue-router/axios/mock/ssr/jestThe use and principle of.
  • Of course, the above knowledge does not matter ha ha ha, the article will mention the general usage and role.

How to regulate Git commit

The code commit log is a good code change log. Regular code submission records are extremely important in the maintenance and development of code, as well as in locating bugs or rolling back versions.

The principle of

Two ways:

  • Standardize git’s commit principles manually or as a team. This depends on self-awareness, good habits after the formation of no problem
  • Use plug-in specifications, such as the one below

To standardize submission, I use the following plug-ins:

  • commitizen
  • conventional-changelog
  • cz-conventional-changelog
  • conventional-changelog-cli

The solution

Install a series of plug-in dependencies

yarn add -D commitizen conventional-changelog cz-conventional-changelog

Copy the code

When installing dependencies, be careful if they are required by the production environment. Apparently commitizen is only used in development environments. -d is used only in the Dev environment

Configuring dependent Paths

Add configuration in package.json

{

/ /...

"config": {

"commitizen": {

"path": "./node_modules/cz-conventional-changelog"

}

}

}

Copy the code

Enter it on the command line

git add -A

git-cz

Copy the code

There are interactive input methods, standardize yourcommitInput format

Generate the CHANGELOG

npm i -g conventional-changelog-cli

Copy the code

Added a NPM command to quickly generate logs

"genlog": "conventional-changelog -p angular -i .github/CHANGELOG.md -s"

Copy the code

Run the yarn command to generate logs

yarn genlog

Copy the code

Automatically generated logs

# 0.1.0 from (2019-12-27)



### Features



*
**git:**Added commitizen tool specification submission ([58e3937] (https://github.com/suoyuesmile/suo-design-pro/commit/58e39370aa838fd99312f73b37d092ffadc85990))

Copy the code

How do you manage code style

A more uniform code style facilitates reading and collaboration.

Principles and solutions

Use esLint to constrain basic style and syntax, while prettier automatically formats your code.

practice

Install esLint dependencies

{

"eslint": "^ 5.16.0".

"eslint-config-standard": "^ 6.2.1." ".

"eslint-friendly-formatter": "^ 2.0.7." ".

"eslint-loader": "^ 2.1.2".

"eslint-plugin-html": "^ 2.0.1." ".

"eslint-plugin-promise": "^ 3.5.0." ".

"eslint-plugin-standard": "^ 2.3.1." ".

"eslint-plugin-vue": "^ 5.0.0"

}

Copy the code

Use two plugins, one plugin:vue/essential and one is Standard. Vue /essential to work in vue as well. The other is Standard. Standard Standard documents

You can also use Recommend, use Lint, and be more lightweight

module.exports = {

root: true.

env: {

node: true

},

extends: ['plugin:vue/essential'.'standard'].

rules: {

quotes: ['error'.'single'].

indent: ['error'.2, { MemberExpression: 'off'}].

'arrow-parens': 0.

'no-loop-func': 2.

'space-before-function-paren': ['error'.'never'].

indent: ['error'.2, { SwitchCase: 1 }]

},

parserOptions: {

parser: require.resolve('babel-eslint'),

ecmaVersion: 2018.

sourceType: 'module'

}

}

Copy the code

Rules rules that can be customized

Rules {Rule name: [Disable/rule level, configured value, only partially configured]} indent: [‘error’, 2, {SwitchCase: 1}] compatible with Prettier, where prettier formats code into an esLint error. Rule level: 0 Disable 1 Warning 2 Error

Using a prettier

Example Configure the prettier file

{

"printWidth": 150.

"singleQuote": true.

"trailingComma": "none".

"semi": false.

"tabWidth": 2.

"useTabs": false.

"bracketSpacing": true.

"jsxBracketSameLine": false.

"arrowParens": "always".

"proseWrap": "preserve".

"overrides": [

{

"files": ["*.json".".eslintrc".".tslintrc".".prettierrc".".tern-project"].

"options": {

"parser": "json".

"tabWidth": 2

}

},

{

"files": "*.{css,sass,scss,less}".

"options": {

"parser": "css".

"tabWidth": 2

}

},

{

"files": "*.ts".

"options": {

"parser": "typescript"

}

},

{

"files": "*.vue".

"options": {

"parser": "vue"

}

},

{

"files": "*.md".

"options": {

"parser": "markdown"

}

}

]

}

Copy the code

Enable vscode automatic formatting

{

// prettier

"prettier.singleQuote": true,

"prettier.semi": false,

"prettier.tabWidth": 2,

"[javascript]": {

"editor.formatOnSave": true,

"editor.defaultFormatter": "esbenp.prettier-vscode"

}

}

Copy the code

How to improve coding efficiency

Principles and solutions

I will improve the coding efficiency mainly from three aspects

  • Upgrade your VUE-CLI to reduce the cost of webpack configuration
  • Use SASS to reuse CSS files using functions, mixins, and variables
  • Use PUG to reduce the amount of HTML code

practice

Vue-cli3 +, VUe-CLI4 + compared with vue-CLI2 +, the biggest change is that the convention commonly known as the configuration, all the public, that is, to do a secondary encapsulation. The advantage of this is that we don’t have to search through a lot of configuration code to find the configuration we need.

Most of the functions we want can be handled by simply creating a new configuration entry. Create a vue.config.js file in the root directory as our webpack configuration file.

Initialize the VUE configuration

const autoprefixer = require('autoprefixer')



module.exports = {

publicPath: process.env === 'production' ? '' : '/',

outputDir: 'dist',

assetsDir: 'static',

filenameHashing: true,

lintOnSave: true,

runtimeCompiler: false,

transpileDependencies: [/\/node_modules\/vue-echarts\//, /\/node_modules\/resize-detector\//],

productionSourceMap: false

}

Copy the code

After the simple configuration, we introduce a sASS tool for writing SASS files

See sASS Resources for usage!

Using Sass

Installation and use

yarn add -D sass sass-loader

Copy the code

How to deal with styles

Create a styles file in assets for style files, add an entry index. SCSS file for JavaScript import, add utils. SCSS, reset. SCSS, varibles files.

These style tools are designed to improve our SCSS development efficiency and have a smooth development experience!

Use varibles variable files

To improve the readability and reusability of our code. Using the sass variable is essential.

Another point is to facilitate the global modification style, if you need to change the skin function, we just need to change the global theme color, you can change the theme, that is more convenient.

/ / theme color

$color-red: #ff3333;

$color-purple: #ff33a9;

$color-orange: #ff8833;

$color-blue: #3377ff;



/ / text color

$color-black: #000;

$color-dark: #333;

$color-deep: #555;

$color-pl: #999999;

$color-weak: #B3B3B3;

$color-white: #fff;



/ / the background color

$bg-bar: #F9F9F9;

$bg-page: #F3F3F3;

$bg-page-light: #F9F9F9;

Copy the code

After using variables, sass files do not take effect directly, at least not in vue files. You need to add the following configuration in vue.config.js.

module.exports = {

// ...

css: {

sourceMap: true.

loaderOptions: {

sass: {

prependData: `

@import "@/assets/styles/variable.scss";

`


}

}

}

}

Copy the code

Override default styles

As a general operation, reset.scss is introduced to override the default styles

/* http://meyerweb.com/eric/tools/css/reset/

V2.0 | 20110126

License: none (public domain)

* /



html, body, div, span, applet, object, iframe,

h1, h2, h3, h4, h5, h6, p, blockquote, pre,

a, abbr, acronym, address, big, cite, code,

del, dfn, em, img, ins, kbd, q, s, samp,

small, strike, strong, sub, sup, tt, var,

b, u, i, center,

dl, dt, dd, ol, ul, li,

fieldset, form, label, legend,

table, caption, tbody, tfoot, thead, tr, th, td,

article, aside, canvas, details, embed,

figure, figcaption, footer, header, hgroup,

menu, nav, output, ruby, section, summary,

time, mark, audio, video {

margin: 0;

padding: 0;

border: 0;

font-size: 100%;

font: inherit;

vertical-align: baseline;

}

/* HTML5 display-role reset for older browsers */

article, aside, details, figcaption, figure,

footer, header, hgroup, menu, nav, section {

display: block;

}

body {

line-height: 1;

}

ol, ul {

list-style: none;

}

blockquote, q {

quotes: none;

}

blockquote:before, blockquote:after,

q:before, q:after {

content: '';

content: none;

}

table {

border-collapse: collapse;

border-spacing: 0;

}



html, body {

width: 100%;

height: 100%;

overflow: auto;

margin: 0;

scroll-behavior: smooth;

-webkit-overflow-scrolling: touch;

}

Copy the code

Use the style toolset

Sometimes we find that introducing variables is not enough, and the variable tools only allow us to use them in CSS class files. If I want to use styles directly in a template, is there a faster solution?

Sure, we can customize a set of common style tools. Set some background colors, font colors, and general actions in the box model.

If there is a design specification oh, I also often put forward requirements to the designer, must develop a set of product design specifications.

/ / utils tools

/ / color

.bg-red {background-color: $color-red! important; }

.bg-purple {background-color: $color-purple! important; }

.bg-orange {background-color: $color-orange! important; }

.bg-blue {background-color: $color-blue! important; }

.color-red {color: $color-red! important; }

.color-purple {color: $color-purple! important; }

.color-orange {color: $color-orange! important; }

.color-blue {color: $color-blue! important; }

.text-black {color: #000; }

.text-dark {color: #333; }

.text-deep {color: #555; }

.text-weak {color: #B3B3B3; }

.text-white {color: #fff; }



/ / font

.f10 {font-size: 10px; }

.f12 {font-size: 12px; }

.f14 {font-size: 14px; }

.f15 {font-size: 15px; }

.f17 {font-size: 17px; }

.f20 {font-size: 20px; }

.f24 {font-size: 24px; }



// Text alignment

.tl {text-align: left; }

.tc {text-align: center; }

.tr {text-align: right; }



// Float and clear float

.fl {float: left; }

.fr {float: right; }

.fix {*zoom: 1; }

.fix:after{display:table; content:''; clear:both; }



/ / show

.dn{display:none; }

.di{display:inline; }

.db{display:block; }

.dib{display:inline-block; }

.dt{display:table; }

div.dib{*display:inline; *zoom:1; }

.vm {vertical-align: middle; }

.vib {display:inline-block; vertical-align: middle; }



/ / position

.pr {position: relative; }

.pa {position: absolute; }

.pf {position: fixed; }



// Box model

.ml4 {margin-left: 4px; }

.mr4 {margin-right: 4px; }

.mt4 {margin-top: 4px; }

.mb4 {margin-bottom: 4px; }

.ml8 {margin-left: 8px; }

.mr8 {margin-right: 8px; }

.mt8 {margin-top: 8px; }

.mb8 {margin-bottom: 8px; }

.ml12 {margin-left: 12px; }

.mr12 {margin-right: 12px; }

.mt12 {margin-top: 12px; }

.mb12 {margin-bottom: 12px; }

.ml16 {margin-left: 16px; }

.mr16 {margin-right: 16px; }

.mt16 {margin-top: 16px; }

.mb16 {margin-bottom: 16px; }

.ml20 {margin-left: 20px; }

.mr20 {margin-right: 20px; }

.mt20 {margin-top: 20px; }

.mb20 {margin-bottom: 20px; }

.ml24 {margin-left: 24px; }

.mr24 {margin-right: 24px; }

.mt24 {margin-top: 24px; }

.mb24 {margin-bottom: 24px; }



.ml10 {margin-left: 10px; }

.mr10 {margin-right: 10px; }

.mt10 {margin-top: 10px; }

.mb10 {margin-bottom: 10px; }

.ml15 {margin-left: 15px; }

.mr15 {margin-right: 15px; }

.mt15 {margin-top: 15px; }

.mb15 {margin-bottom: 15px; }



// Button is disabled

.disabled{outline:0 none; cursor:default! important; opacity:.4; filter:alpha(opacity=40); -ms-pointer-events:none; pointer-events:none; }

Copy the code

Add style entry file

Finally, create an entry file and import all the style utility classes for the main program to import.

/ / index. SCSS document

// @import './varibles.scss'

@import './reset.scss';

@import './utils.scss';

Copy the code

Introduced in the varibles. SCSS vue configuration, not required here

Add index.scss directly to main.js

import '@/assets/styles/index.scss'

Copy the code

What are the techniques and aspects of writing styles in VUE?

Avoid global pollution

Write CSS/SCSS and scoped on a page. Scoped keeps the style of the page local and does not affect the style of other pages.

Bem specification

The problem that most of us have is we have too many nested styles what do we call them

BEM, short for Block, Element, modifier, is a front-end CSS naming methodology proposed by Yandex team.

The name is too long and legible

.cardbox {

.cardbox-card {

.cardbox-card-wrapper

.cardbox-card-wrapper-header {

.cardbox-card-wrapper-header-title {

// ...

}

}

.cardbox-card-wrapper-body{

.cardbox-card-item {

.cardbox-card-item-title {

// ...

}

}

}

}

}

}

Copy the code

Bem usage mode

block-name__element-name--color

  • Discriminating blocks, child elements, modifier elements
  • Block, a separate unit in a page
  • Child element, the child of the blockcard__itemuse__The connection
  • Child elements are named using – concatenation
  • Modify (changeable)card__item--warninguse--

We use BEM to transform styles

.cardbox {

&__header {

&__title {

/ /...

}

}

&__body {

&__item {

&__title {

/ /...

}

}

}

}

Copy the code

Bem generally recommends that child elements be nested within 2-3 levels

However, we found that style child elements were a little too nested, using bibarychild element nesting.

The general idea is to try to separate the parent-child relationship and treat the card itself as a block.

Let’s try to reduce nesting:

.cardbox {

&__header {

&__title {

/ /...

}

}

&__body {

.card {

&__title {

/ /...

}

}

}

}

Copy the code

Now that style writing is more efficient and more formal, HTML writing is a lot of cumbersome code.

For example, most labels open front and close back. With puG we can omit many character strokes. Let’s talk about how to write templates using PUG.

Which HTML style you prefer is anyone’s guess, but I prefer PUG, with its indentation and simplicity, to feel like WRITING SCSS.

How do I use PUG

Similar to SASS, install puG and loader of PUG first

yarn add -D pug pug-html-loader pug-plain-loader

Copy the code

Complete the configuration

module.exports = {

// ...

chainWebpack: (config) = > {

config.module

.rule('pug')

.test(/\.pug$/)

.use('pug-html-loader')

.loader('pug-html-loader')

.end()

}

}

Copy the code

Write puG code

Use SCSS tools to work perfectly with PUG and write a lot less code

/ / login

<template lang="pug">

.login

H1.login__title. ml15 Register/login

.login__form.mt15.ml15

Van-field. login__form__input(placeholder=" input "V-model ="phone")

.login__form__protocol.mt15

.login__form__protocol__tips.dib. Text-weak Consent is given by registering or logging in

.login__form__protocol__name.dib. Color -orange User Protocol

app-button.mt15(size="large"

theme="orange"

:disabled="phone.length ! 11 = ="

@click="handleSubmit"

) the next step

</template>

Copy the code

Now that we’ve introduced styles, I’ll talk about the introduction of other resources

How do you manage your resources

Principles and solutions

I temporarily divide resources into the following categories

  • The font
  • ICON
  • The picture
  • styleCreate a new directory for each of them and place them under Assets in separate categories for use elsewhere. Use alias for better rename, making it easier to access.

Add the vue.config.js configuration and set the assets alias

const path = require('path')

function resolve(dir) {

return path.join(__dirname, dir)

}

module.exports = {

/ /...

chainWebpack: (config) = > {

config.resolve.alias.set(The '@', resolve('src')).set('@assets', resolve('src/assets'))

}

}

Copy the code

ICON

The introduction of iconfont

  1. Iconfont Ali icon project download, the whole project icon package download down

  1. The following four files are required to introduce the iconFONT style
  • iconfont.eot
  • iconfont.ttf
  • iconfont.woff
  • iconfont.woff2
  1. Iconfont is introduced into the projecticoncomponentization
<template>

<i class="iconfont" v-on="$listeners" :class="name"></i>

</template>



<script>

export default {

props: {

name: String

}

}

</script>



<style lang="scss" scoped>

.iconfont {

font-size: 16px;

color: $color-icon;

}

</style>

Copy the code

Introduce images as ICONS

To componentize the image, let’s write an IMG component

<template lang="pug">

img(

:src="require(`@/assets/images/${name}.png`)"

v-bind="$attrs"

v-on="$listeners"

:style="{'width': width ? width + 'px' : size + 'px', 'height': height ? height + 'px' : size + 'px' }")

</template>

<script>

export default {

name: 'app-img',

props: {

name: {

type: String,

default: ''

},

size: {

type: Number,

default: 16

},

width: {

type: Number,

default: 0

},

height: {

type: Number,

default: 0

}

}

}

</script>

Copy the code

How do you manage your routes

Principles and solutions

With vue-router, use import() to generate an asynchronous route and load the module only when it is accessed.

Why does using import() load modules asynchronously?

MDN: Dynamic import() is useful when you want to load modules under certain conditions or on demand. While static imports are the best choice for initializing load dependencies, using static imports is easier to benefit from code static analysis tools and tree shaking.

To put it bluntly, it is for the purpose of loading on demand. Most implementations now rely on the import() method for loading on demand.

Install the vue – the router

yarn add vue-router

Copy the code

After installing the Router, create a page before writing the router

Create a new empty page

The views directory under the SRC directory is added to store page files. Create the Index directory and the home page

<template lang="pug">

The home page

</template>



<script>

export default {



}

</script>

<style lang="scss" scoped>

</style>

Copy the code

Write the routing

const routes = [

{

/ / home page

path: '/'.

name: 'index'.

redirect: '/home'.

component: App,

children: [

{

/ / home page

path: 'home'.

name: 'home'.

// Route lazy loading

component: (a)= >

import(

/* webpackChunkName: "index" */ '.. /views/index/home.vue'

)

}

]

}

]

Vue.use(VueRouter)



const router = new VueRouter({

mode: 'history'.

routes: routes,

base: process.env.BASE_URL,

props: true

})



export default router

Copy the code

In order to eliminate # and make the path more beautiful and concise, we use history mode, but the problem with history mode is that the asynchronous route is not cached in the page, so it will not be found on the first time you enter the page

Add the configuration in vue.config.js. The development environment can access it

module.exports = {

// ...

devServer: {

historyApiFallback: true

}

}

Copy the code

There are a lot of routing can be studied to the place, you can study oh!

Componentized development

Principles and solutions

In general, we divide between base (common) components and business components based on their reuse.

To save time and speed up development, most of the base components here reference open source components. Of course, you can’t just use it.

Secondary encapsulation, or high-level component development, is typically required.

  1. Modify styles by modifying and overwriting the styles of the current component.
  2. Change the JS logic by intercepting events.

Let’s start with the Vant component

practice

The introduction of vant

yarn add vant

Copy the code

Secondary packaging and transformation of basic components

Here are 7 steps to write a common component

  1. Create a newcomponentsDirectory to hold the base components
  2. The base component is namedapp-xxxappXxx, create a new oneapp-buttonDirectory, Newindex.vue
  3. Design and write components according to the design draft

Design components before writing them, and write them according to their invariability and variability. Invariance is the core of a component, which can adjust the related parts of the component according to parameters to achieve optional functions.

  1. Implementation component
<template lang="pug">

div.dib

van-button.btn(

@click="$emit('click')"

:class="getClass" v-bind="$attrs"

:style="{'width': size === 'large' ? '345px': '', 'backgroundColor': getBgColor, borderColor: getBgColor, color: getBgColor}")

slot

</template>



<script>

import { Button } from 'vant'

import Vue from 'vue'

import { getColor } from '@/utils'

Vue.use(Button)



export default {

name: 'app-button'.

props: {

type: {

type: String.

default: 'primary'

},

theme: {

type: String.

default: 'blue'

},

size: {

type: String.

default: ' '

}

},

computed: {

getClass() {

if (!this.type) {

return ' '

}

return `app-btn--The ${this.type}`

},

getBgColor() {

if (!this.theme) {

return ' '

}

return getColor(this.theme)

}

}

}

</script>



<style lang="scss" scoped>

.app-btn {

::v-deep &--primary {

padding: 8px 30px;

height: 40px;

border-radius: 4px;

font-size: 15px;

font-weight: 400;

line-height: 19px;

color: white! important;

}

::v-deep &--minor {

padding: 5px 10px;

height: 26px;

border-radius: 14px;

font-size: 12px;

font-weight: 400;

line-height: 16px;

background-color: #fff! important;

}

::v-deep &--rect {

padding: 5px px;

height: 49px;

font-size: 14px;

color: white! important;

}

}

</style>

Copy the code

:: V-deep style overwrites the component style in scoped case without changing its style

  1. Once you’ve written the basic component README, why document it? If multiple people are working on the same project, the underlying components will be referenced by others. Make it easy for others to use, so document it.

In short: comments or documentation are important as long as public methods and components are likely to be used by others. Take responsibility for your own code.

For other uses, see Vant

  1. Global reference: The underlying component is used in many pages. If you set it to global, you don’t need to reference it anywhere else.

Create a new file, global, to hold the global component registry and import it in main.js

import Vue from 'vue'

import appButton from '@/components/app-button'

Vue.component('app-button', appButton)

Copy the code
  1. To write gooddemoWrite unit tests, even if you don’t write them yetdemoSo that it can run normally

Add demo pages and routes

<template lang="pug">

div(class="base")

// Button component

App-button.mt4 (theme="blue") confirm payment

App-button (theme="orange") confirm payment

App-button (theme=" Purple ") confirm payment

App-button.mt4 (theme="red") confirm payment

App-button (theme="grey") confirm payment

App-button. mt4(theme="blue" size="large") modify the address

App-button.mt4 (theme="orange" size="large") modify the address

App-button. mt4(theme="purple" size="large") modify the address

App-button. mt4(theme="red" size="large") modify the address

App-button. mt4(theme="grey" size="large") modify the address

App-button. mt4(theme="blue" type="minor"

App-button (theme="orange" type="minor") confirms receipt

App-button (theme="purple" type="minor"

App-button (theme="red" type="minor") Change the address

App-button (theme="grey" type="minor") Change the address

App-button.mt4 (theme="blue" type="rect"

App-button (theme="orange" type="rect") confirms receipt

App-button (theme="purple" type="rect"

App-button (theme="red" type="rect") Change the address

App-button (theme="grey" type="rect") Change the address

</template>

<script>

export default {

}

</script>

<style lang="scss">

</style>

Copy the code

Implementation effect


How to encapsulate a request

Principles and solutions

It’s basically a wrapper around Axios, and the wrapper serves two main purposes.

  • Modify some basic configuration: address request, timeout, other miscellaneous
  • Unified operation: unified handling of errors, unified handling of request parameters and formats, unified response parameters and formats. Unified processing of messages, unified interception of mounts, and so on.

There are many similar articles on the web, but here are my common encapsulation schemes.

practice

Set the request address based on the environment

/ / env - default. Js file

// Different environments access different paths

const api = {

develop: 'http://xxxx:8080'.

mock: 'http://xxxx'.

feature: 'http://xxxx'.

test: 'http://xxxx'.

production: 'http://xxxx'

}



export const baseURL = api[process.env.NODE_ENV || 'dev']

Copy the code

Since mock environments are not necessarily the same for everyone who develops them, this file suggests gitignore ignore them. Templates can be written in a readme document and added to the file when the project is started.

Create a newutilstool

We now wrap AXIos into our own configuration, and then define four common request methods to call

/ / utils/HTTP js file

import axios from 'axios'

import { baseURL } from '.. /.. /.env-defalut.js'



/ / axios configuration

const defaultBaseUrl = 'http://localhost:8080/'

// Default timeout period

axios.defaults.timeout = 15000

// Unified configuration of data interface domain name. env

axios.defaults.baseURL = baseURL || defaultBaseUrl



// HTTP request interceptor

axios.interceptors.request.use(

(config) = > {

config.headers = {

}

return config

},

(err) => {

return Promise.reject(err)

}

)



// HTTP Response interceptor

axios.interceptors.response.use(

(response) = > {

return response

},

(error) => {

const data = error.response.data

return Promise.reject(data || error)

}

)



export default axios



/ * *

* Fetch request method

* @param {*} url

* @param {*} params

* /


export function fetch(url, params = {}) {

return new Promise((resolve, reject) = > {

axios

.get(url, {

params: params

})

.then((response) = > {

resolve(response.data)

})

.catch((err) = > {

reject(err)

})

})

}



/ * *

* POST request method, send data format JSON

* @param {*} url

* @param {*} data

* /


export function post(

url,

data = {},

config = {

transformRequest: [

function(fData, headers
)
{

headers['Content-Type'] = 'application/json'

return JSON.stringify(fData)

}

]

}

) {

return new Promise((resolve, reject) = > {

axios.post(url, data, config).then(

(response) = > {

resolve(response.data)

},

(err) => {

reject(err)

}

)

})

}



/ * *

* Patch request method, send data format JSON

* @param {*} url

* @param {*} data

* /


export function patch(url, data = {}) {

return new Promise((resolve, reject) = > {

axios

.patch(url, data, {

transformRequest: [

function(fData, headers) {

headers['Content-Type'] = 'application/json'

return JSON.stringify(fData)

}

]

})

.then(

(response) = > {

resolve(response.data)

},

(err) => {

reject(err)

}

)

})

}



export function del(url, data) {

return new Promise((resolve, reject) = > {

axios.delete(url, { data }).then(

(response) = > {

resolve(response.data)

},

(err) => {

reject(err)

}

)

})

}

Copy the code

How to manage apis

The principle of

The first thing to do is to lay out the principles of an API. My principles are generally these:

  • Clean and pure
  • Try not to deal with data
  • Don’t rely on each other

The advantage is that you don’t process data in the API, the interface in the API is the same as the interface documentation. To avoid people referring to my API and looking at the code, just look at the documentation.

Example: Imagine a situation where someone references my API and suddenly realizes that the response data is wrong. First it checks to see that the page data has not changed. After reading the API document, I found that there was no problem with the data. Finally, I found that I had processed the API when I was writing it, but the API could not be changed, which affected my own module. It’s just rewriting an API, which is messy and not clean and elegant.

import { fetch, post } from '@/utils/http'



// The user logs in

export const login = data= > post('/user/login', data)



// Get user information

export const getUserInfo = (data) = > fetch('/api/user/info', data)

Copy the code

If you need to process data, either use an intermediate tool or process it inside the page. Of course, it’s a practical problem.

How to usemockSimulated data

Principles and solutions

Generally, there are two solutions: one is to simulate the back end and use a remote online JSON server. Another option is to build native JSON or use an off-the-shelf Node server to intercept requests.

Each of these two ways has its strengths and weaknesses. There is no superior or inferior.

The remote onlinemock

Remote online mock I’ve used

  • Apizza: Easy to use, fully featured, like his file expansion directoryapiThe free version only supports 2 co-editors
  • Swagger: Open source and free,apiManagement is too messy,
  • Rap/RAP2: Open source, free, can build localapi, you need to build your own

Advantages of using remote Mocks:

  • It does not need to be added within the projectmock
  • Function more comprehensive improvement
  • Can be based on the interface documentationmock, together with the interface document for easier viewing.

Disadvantages: You need to build your own server, only supports static mocks, cannot be used with unit tests

Local JSON mock

  • usewebpackInternal Mock configuration
devServer: {

// Mock if the interface is not implemented

before: require('./mock')

}

Copy the code

Basic principle: Basically, node reads the file, converts it to JSON format, mocks the data using mock.js, and finally Webpack intercepts the request to generate JSON response data

const Mock = require('mockjs')



module.exports = (app) = > {

function getJsonFile (filePath) {

var json = fs.readFileSync(path.resolve(__dirname, filePath), 'utf-8')

return JSON.parse(json)

},

const returnMock = (datafile, res, req) = > {

setTimeout((a)= > {

var json

if (/\.json$/.test(datafile)) {

// Json files expose mock templates

json = getJsonFile(datafile)

} else if (/\.js$/.test(datafile)) {

json = require(datafile)(req.query)

}

res.json(Mock.mock(json))

}, 500)

}

}

Copy the code
  • usejson-serverThe construction is mainly divided into the following steps
  1. npmThe installationjson-server
  2. writenpmScript command, importmockThe configuration file
  3. writemockRoute matching rule

Relatively simple here do not describe in detail!

The disadvantage of being local is the need

  • The front-end needs to be based onapiDocument writingmockThe data format
  • No remote functionmockSo perfect, supportrestfulIt needs to be researched
  • Also need configuration relatedmocktool

Advantage is that

  • You don’t have to look at the editapiThe document
  • It can be changed and viewed in the codemockdata
  • Support the use ofJavaSciptDynamic placemockCan be used in conjunction with unit tests

conclusion

This article cost the author more than a week of spare time, save hand typing 6000+ words, at the same time collect, sort out many previous skills and writing while thinking and summary. If it helps you, that’s its greatest value. I can’t get over it if I don’t like it! 😄

Due to the limited technical level, if there is any mistake in the article, please point out in the comment area, thank you!

Most of the code in this article will be updated in Suo-Design-Pro

The project will be perfected as much as possible

Writing practical summaries is really time consuming. How to share the place that helps you in the article, let more people see!

The next section is a preview

  • How to write native components, and the thinking and principles of component writing?
  • How to use VUEX and its application scenarios and principles
  • How to use filters and write your own filters
  • How to use Jest to test your code? Comparison of TDD and BDD

Click to jump to the next section

The resources

  • commitizen
  • MDN import()
  • Vant document
  • Eslint document
  • Vue – the router documentation
  • Sass document
  • Axios document

The open source project

The above function configuration will be implemented in SUO-Design-Pro, hope you can continue to pay attention to!

This article is formatted using MDNICE