To do a good job, you must first sharpen your tools. – Continue to polish the front-end architecture

Sorry for being sick and dragging more, 1024 happy

This article updates the address permanently

Fill in the pit

Last time, some students really mentioned this problem. Thank you for your carefulness. @_noob

There’s nothing wrong with it, but it seems to violate the usual structure, like there’s something wrong. In fact, in order to take care of beginners, I am afraid that everyone will give up because of the trouble, and it is not “it looks so complicated”. Let’s fill in the hole.

In order to take care of the students who did not follow my serialization in real time, the code of each chapter was published separately on my Github blog, without updating the coverage [unless the code was modified with mistakes], so as to avoid students Xiaoming staring at the first two chapters and Github final version of the code in 2019 (release is not particularly friendly).

As a matter of programming habit, we changed renderer/ SRC to the more understandable SRC /renderer.

Renderer/SRC problem above

Eslint-config-alloy: Use this rule to write more formal code

Now enter the main topic of this chapter


axios

You use VUE and realize that Vue can’t send requests, so you Google it and realize you can use vue-resource. You ask someone about vue-Resource and he says don’t use vue-resource because vue-Resource has officially stopped maintenance, you should use Axios or fetch. But we want to embrace ES6 without ES5 fetch (and of course es6-FETCH), here we use Axios!

Tips

When do you need to put dependencies in dependencies? When do you need to put dependencies in devDependencies?

DevDependencies: devDependencies only in dev mode (such as webpack. Loader, esLint, Babel) < span style = “box-like: box-like: box-like; box-like: box-like

But basically don’t worry, the official website will provide start instructions, but we should generally understand the meaning, not mechanical copy.

The introduction of Axios

  • Go straight to the latest

The 2018-09-28 capture npmjs.com

  • Add the dependent
"dependencies": {    
    "axios": "^ 0.18.0." "
 }
Copy the code

Based on the previous chapter, don’t forget to download NPM I again

Remember the vue homepage script main.js that we automatically generated?

Encapsulation axios

SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils Handles some common HTTP status codes.

  • Interceptors document

I wrote as detailed a note as I could for you.

// src/renderer/utils/request.js
import axios from 'axios'

/ / here generally refers to the backend API prefix, such as/baidu / * / * / 1. API/mi / * / * / 2. API
const BASE_API = ""

export function axiosIntercept(Vue, router) {
    const axiosIntercept = axios.create({
        baseURL: BASE_API
    })

    // HTTP request interceptors are usually used to plug in some global configuration before the request, or to enable some CSS loading animation
    axiosIntercept.interceptors.request.use(
        (config) = > {
            // Determine whether a token exists, and if so, add a token to each HTTP header
            // if (store.getters.accessToken) {
            // console.log(store.getters.accessToken)
            // config.headers.Authorization = `token ${store.getters.accessToken}`;
            // }

            //todo: load the animation

            // If necessary, you can handle the POST or change the POST transmission format
            if (config.method === 'post') {};return config;
        }, function (err) {
            return Promise.reject(err);
        });


    // HTTP response interceptors are usually used to do some processing based on some back-end protocol specific return values, such as permission aspect, 404... Or turn off some CSS loading animations
    axiosIntercept.interceptors.response.use(function (response) {
        // todo: Pause loading animation
        return response;
    }, function (err) {
        // Catch an exception
        if (err.response) {
            switch (err.response.status) {
                case 401:
                    // Do something here we write back end to do constraints and then improve}}return Promise.reject(err);
    });
    return axiosIntercept;
}


Copy the code

Remember that we used the vue home page script main.js generated by vue-CLI. Here we need to couple Axios and Vue.

// src/renderer/main.js
import axios from 'axios'
import { axiosIntercept } from './utils/request'

// Extend Axios to the Vue prototype chain
Vue.prototype.$http = axiosIntercept(Vue)
Copy the code

So we’re writing the business logic to send the request directly in the Vue context using this.$HTTP. Both interception and state sharing are realized.

Know what it is and why

  • What’s the point of this?

Save the amount of code, make the code more readable

  • Why is that?

Extending to the stereotype chain enables the Axios runtime to share the contents of the Vue stereotype chain, reducing the number of temporary variables that refer to the Vue

  • Take a chestnut

Traditional situation

import axios from 'axios'


new Vue({
  data: {
    user: ""
  },
  created: function () {
    // Now the scope is on Vue, cached and depends on this variable
    let _this = this;
    axios.get("/user/getUserInfo/" + userName).then(res= > {
            if (res.data.code === 200) {
                // The value of the vue binding is not available in axios, so we can only use the _this context that was cached_this.data.user = res.data.user } }); }})Copy the code

After the agent

 


new Vue({
  data: {
    user: ""
  },
  created: function () {
    // Axios becomes part of the vUE prototype chain, sharing vUE state.
    
    this.$http.get("/user/getUserInfo/" + userName).then(res= > {
            if (res.data.code === 200) {
                // Note that axios callbacks should use arrow functions as much as possible, which can inherit the parent context, otherwise it will be similar to closures, and still cannot share variables.
                // More elegant
                this.data.user = res.data.user } }); }})Copy the code

If you don’t understand Prototype, check out my previous articles

proxy

I’m just going to do it a little bit, just to set up a little bit of separation

webPack

  • WebPack alias
resolve: {
    extensions: ['.js'.'.vue'.'.json'].alias: {
      The '@': resolve('src/renderer'),}},Copy the code

For more elegant use, you can create aliases for each commonly used directory

resolve: {
   extensions: ['.js'.'.vue'.'.json'].alias: {
     'vue$': 'vue/dist/vue.esm.js'.The '@': resolve('src/renderer'),
     'assets': resolve('src/renderer/assets'),
     'components': resolve('src/renderer/components'),
     'container': resolve('src/renderer/container'),
     'utils': resolve('src/renderer/utils')}},Copy the code

Cross-domain issues in production and development

Dev is the directive launched at development time and build is the directive packaged by webPack at pre-release

Assuming that the author is just a front-end, usually, in the process of development and debugging, it is unavoidable to need API docking with students at the back-end, which will inevitably lead to cross-domain problems. Of course, traditional javaWeb does not need cross-domain, (IP domain port any difference is cross-domain) in DEV mode debugging, we try to choose the front-end environment to avoid cross-domain problems, rather than to build additional Nginx or change the back-end code.

Cross-domain is only for JavaScript, because developers consider scripting on browsers to be insecure.

Since our VUE project is a node family bucket, we rely on Node and webPack compilation to directly configure node’s proxyTable as a proxy for development, which is the simplest, one after another configuration, the team benefits.

Cnode mining community API example

cnodejs.org/api The CNode API above is free to call because the back end does the processing.

Xiaoce-timeline-api-ms.juejin. Im /v1/getListB… Please, the browser did a cross-domain alarm.

Oh, let’s adapt the Node agent

Official example in this: vuejs – templates. Making. IO/webpack/pro…

ProxyTable extension:


proxyTable: [{
      // Intercept all XHR requests starting with v1
      context: ['/v1'].target: "https://xiaoce-timeline-api-ms.juejin.im".cookieDomainRewrite: {
        / / without the cookie
      },
      changeOrigin: true.// A virtual service will accept or forward requests on our behalf
      secure: false}].Copy the code

Send the request again.

  • Happy to get the data

This way, separated projects can use the Swagger testing interface in this way without bothering anyone. Implementation of their own business logic, simple implementation point.

Code:

// blog/index.vue <template> <div class="Blog"> <h1>{{ msg }}</h1> <div v-for="(blog,index) in blogList" v-bind:key="index"> <h3 > <a :href="`https://juejin.cn/book/`+blog.id" > <span>{{blog.title}}</span> </a> </h3> </div> </div> </template> <script> export default {name: "Blog", data() {return {MSG: "blogList ", blogList: []}; }, created() { this.getBlog(); }, methods: { getBlog() { this.$http.get("/v1/getListByLastTime? src=web&pageNum=1").then(res => { this.blogList = res.data.d; }); }}}; </script>Copy the code

release

  • literacy

After the code is written and deployed online, it will not clone the code online after the Npm run dev 😆, which will have too many garbage dependencies, bringing users disastrous network requests, usually with the help of webPack packaged and published to the server’s Web services.

run

 npm run build
Copy the code

The package directory is the previously configured Webpack

Well, a lot of people won’t be able to just double-click index.html.

Tip: built files are meant to be served over an HTTP server. Opening index.html over file:// won’t work.

I usually use Python to start an HTTP service to run (script address). Of course, my IDE can also support HTTP start.

Cross-domain in production

In production, because the front-end and back-end are bound to have different ports, cross-domain is avoided. Nginx’s forward/reverse proxy is usually used as a means of cross-domain. (Not load balancing, two concepts)

server {
        listen       80;
        server_name  localhost;
 
        location ^~ /v1 {
        proxy_pass              https://xiaoce-timeline-api-ms.juejin.im;# agent.
        proxy_set_header        X-Real-IP $remote_addr;# Forward the real IP address of the client
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        Host $http_host; }}Copy the code

Nginx can do a lot of things.

Normalization of apis

Are you still using global search to find your own interface? Are you using global search to find your own interface?

Create an API folder under /renderer

Webpack.base.conf.js adds an API alias to make it easier to call a lot later

'api': resolve('src/renderer/api')
Copy the code

We created /renderer/ API /juejin.js


import axios from 'axios'

let Api = Function()

Api.prototype = {
    getBlog(page, fn) {
        axios.get(`/v1/getListByLastTime? src=web&pageNum=${page}`).then(res= > {
            // if (res.data.code === 200) {
            fn(res.data)
            // }
        }).error()
    }
}
export default new Api()


Copy the code

Modify the Axios request we just made in /blog/index.vue:

  • First introduced the API
import juejin from "@/api/juejin";
Copy the code

Annotate the previously discrete AXIOS and request the data using the XHR defined from the API.

getBlog() {
      // this.$http.get("/v1/getListByLastTime? src=web&pageNum=1").then(res => {
      // this.blogList = res.data.d;
      // });
      juejin.getBlog("1", response => {
        this.blogList = response.d;
      });
    }
Copy the code

OK, many students do not understand, originally simple things why complicated? In fact, it is not complicated, and it seems very clear. If a large project has thousands of requests, it not only results in low code coverage, but also looks messy and not good for teamwork. This series of articles will provide you with more team-friendly ways to develop good habits on the basis of leading you to separate before and after.

The entire code for this chapter is here

About me

  • I am currently writing the “Before and after Separating Projects from Zero” series for revision and supplement

  • Continually updated practice address for Separating projects before and after Building from Zero

The articles

Introduction to Separating WEB Projects before and after Building from Zero – The Meaning of Open Source

Separating Web Projects before and after Building from Zero: The Beginning – A look at the history of the Web

Split Web Projects before and after Building from Zero – an in-depth talk about split architecture before and after

“Separating Web Projects before and after Building from Zero” Preparation – Front End Understanding pass? Front-end infrastructure and technology introduction

Separating Web Projects before and after Building from Scratch – 5 minutes to quickly build a standard front-end project skeleton

“Before and after Building a Separate Web Project from Zero” practice – Continue to polish the front-end architecture by getting it right in advance