1. Project infrastructure

The technology stack used in the project: Vue family bucket, background interface line up-linking, Sass precompilation, ElementUI, front-end optimization, wechat Alipay payment….

1.1 Project Infrastructure

Basic structure of the project:

VueProject └ ─ mistore ├ ─ Babel. Config. Js ├ ─ package - lock. Json ├ ─ package. The json ├ ─ public │ ├ ─ the favicon. Ico │ └ ─ index. The HTML ├─ ├─ exercises, ├─ exercises, exercises, exercises, exercises, exercises, exercises, exercises NavHeader. Vue ├─ main.js ├─ Pages │ ├─ Alipay. Vue │ ├─ Cart. Vue │ ├─ detail Vue │ ├─ Bass School. Vue │ ├─ Bass School. Vue │ ├─ bass School. Vue │ ├─ bass School. Vue │ ├─ bass School ├─ ├─ sci-sci-sci-sci-sci-sci.jsCopy the code

First of all, I will post some rough implementation renderings of our project

1.2 Main Plug-ins

“Axios” : “^ 0.21.1”

“Element – UI”, “^ 2.15.1”,

“The node – sass” : “^ 5.0.0”,

“Sass – loader”, “^ 11.0.1”,

“Vue – awesome – swiper” : “^ 4.4.1”,

“Vue – cookie”, “^ 1.1.4”,

“Vue – the lazyload” : “^ 1.3.3”,

.

1.3 Route Encapsulation

Route Settings are carried out using the lazy route loading method, and routes are encapsulated according to our project design draft

The pseudocode is as follows:

import vue from 'vue'; import Router from "vue-router" vue.use(Router); Var cart = () => import('./pages/cart.vue'); . Var router=new router ({routes: [// routes: home) {children: }, // shopping cart route // order children: [/ / order list / / / / order confirmation of the order payment]}, / / login], mode: 'history'}); export default routerCopy the code

1.4 Encapsulation of sessionStorage

Why encapsulate storage:

  1. Storage itself has apis, but only in the form of simple key-value pairs
  2. Storage can only store strings, which need to be manually converted into JSON objects
  3. A Storage can be emptied only at a time

We usually store JSON objects in Storage, so we need to wrap the Storage methods ourselves.

/* Storage package */
const STORAGE_KEY = 'mall';
export default {
  / / stored value
  setItem(key, value, modules_name) {
    if (modules_name) {
      var all = this.getItem(modules_name)
      all[key] = value;
      Modules_name is used as the key(already exists), and all that is currently added is put into the module_name. Val contains all values
      this.setItem(modules_name, all)
    } else {
      // Only two arguments are passed:
      let val = this.getStorage();
      console.log(val);
      val[key] = value;
      window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify(val)); }},/* Get a value (can pass a value or two values) one argument: no moudle directly single object one argument: get the object under the moudle key */
  getItem(key, modules_name) {
    if (modules_name) {
      let val = this.getItem(modules_name);
      if (val) return val[key]
    }
    return this.getStorage()[key];
  },
  // Get the entire data (to JSON format): Convert the data to JSON format.
  getStorage() {
    return JSON.parse(window.sessionStorage.getItem(STORAGE_KEY) || '{}')},// Delete a value
  clear(key, modules_name) {
    let val = this.getStorage();
    if (modules_name) {
      delete val[modules_name][key]
    } else {
      delete val[key]
    }
    window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify(val)); }}Copy the code

Usage:

// console.log(storage.getStorage());
// storage.setItem('a',1);
// storage.setitem ('address',' Beijing ','person');
// storage.setItem('abc',{data:88},'person');
storage.clear('a')
Copy the code

In this way, we can put all storages used in the whole project into one key/value, and store all data in value in json form

1.5 Interface Error Interception

  1. Unified error
  2. Unified interception without login
  3. Request value, return value unified processing

We use axios interception to unify the case handling of the request and the corresponding return value. And processing is not logged in when the jump login interface and so on. There is also unifying the handling of request values and return values (form formatting, etc.).

1.6 Interface Environment Settings

Generally, please specify that we have different interfaces for different phases of the project

That is to say, when we use jSONP or CORS to request interfaces across domains, and we have different request interfaces by environment, we should follow the idea of ES6 modularity, we extract all environment variables uniformly. To avoid the inevitable errors of modifying our code in business code.

  1. Different phases of development require different configurations (that is, we need different interfaces for different phases).
  2. The configuration varies according to the cross-domain mode
  3. When packaging by injecting environment parameters, unified management environment, output different versions of the package

What if we use different environment interfaces in the proxy so that we can directly modify the vue.config.js baseurl

Normally we have three environments: development, test, and production. When we need to add the environment, we need to create a.dev. Environment name file to set the value of NODE_DEV. Then you configure the response.

Here’s an example:

Package. Under the json

"scripts": {
    "serve": "vue-cli-service serve --mode=development"."test": "vue-cli-service serve --mode=test"."haha": "vue-cli-service serve --mode=haha"."build": "vue-cli-service build --mode=production",},Copy the code

Dev.js module (configuration of different interfaces for different environments) :

/* This is the baseURL address module that can be used when our cross-domain mode is jSONp or CORS. Process.env.node_env
let baseURL;
switch (process.env.NODE_ENV) {
  case 'development':
    baseURL = 'http://dev-mall-pre.springboot.cn/api'
    break;
  case 'test':
    baseURL = 'http://test-mall-pre.springboot.cn/api'
    break;
  case 'haha':
    baseURL = 'http://haha-mall-pre.springboot.cn/api'
    break;
  case 'production':
    baseURL = 'http://mall-pre.springboot.cn/api'
    break;
  default:
    baseURL = 'http://mall-pre.springboot.cn/api'
    break;
}
export default { baseURL }
Copy the code

User-defined environment configuration (haha).env.haha file:

NODE_ENV='haha'
Copy the code

1.7 the MOCK set

Why MOCK:

  1. During the development phase, mocks are needed in advance for efficiency
  2. Reduce code redundancy, flexible plug – in
  3. Reduce communication and reduce the time of interface joint adjustment

There are three main MOCK Settings:

  1. Create JSON locally
  2. Easy-mock platform (easyMock platform is recommended)
  3. Inherit the Mock API (recommend mock.js)

What we need to note is that the first method is the simplest and does not require any learning cost. At that time, the disadvantage is that the interface cannot be unified, which means that we need to change a lot. The second is to send a real request, and the third is to intercept the request and simulate data locally. The latter two have some learning costs and are also recommended.

2. Homepage function development

  1. NavHeader development

  2. HeaderFooter

  3. Home Page Rotation map (Swiper)

  4. advertising

  5. Product display (Axios request)

  6. Encapsulation of the tool Model (using the Vue animation component)

  7. Image lazy loading using vue-lazyload plugin

3. Login function development

  1. Login registration interface implementation

  2. Logon logic (setting the Cookie cache user login state)

  3. Registration logic (error blocking small pit, unable to get MSG message, processed)

Question:

What is the function of pulling user information and shopping cart quantity to Vuex? All data may be cleared when the user interface refreshes Vuex. What is the essential function of pulling these two data?

Answer:

Vuex only transmits these two data (so it needs to be pulled out again). I think too much, thinking that the user information in Vuex is related to the subsequent interface request. In fact, Vuex here saves these two data for display in the homepage.

And the Cookie’s cycle. That is to say, we are using this pull premise when our state is logged in, so there is data. So what this solves is that a page refresh might cause States data in Vuex to be wiped clean.

  1. Add Vuex to manage user names and shopping carts on the home page

  2. Exit the implementation of the login function

  3. Register login status using VUEX status hosting

Note: Pull the data from Vuex during index refresh and pull the data again during index declaration cycle. Pull the data during index declaration cycle because we are using SPA mode, so shopping cart data changes do not refresh, so we pull the shopping cart data again every time the component enters (I think it is necessary), Username does not need to do this

4. Product site function development

  1. Top suction top plug and its functions
  2. Product site layout (including swiper at the bottom, and video presentation)
  3. The animation of the video
  4. Interface for request rendering

5. Product details page

  1. Complete the interface
  2. Request data for interaction
  3. Adding a shopping cart jumps to the shopping cart interface

Note:

Adding to the shopping cart must be done in the login state, and there is a pit left when wrapping axios. So when the state is 10, you should return a reject promise,

So when we’re not logged in, clicking Add to cart will execute our code in then (Promise defaults to resolve if it doesn’t return the specified state). Cause some unnecessary bugs

6. Shopping cart page

  1. Wrapper of the ORder-nav component
  2. Shopping cart interface
  3. Shopping cart interface requests with some judgment

Summary: In the actual development, in order to prevent some security problems, the logic of shopping cart is completed by the back end, our front end only needs the attribute interface document, will be corresponding to each operation

7. ElementUI integration

Combined with official documents, Message and other plug-ins were loaded on demand, which improved the development efficiency

8. Order confirmation function

  1. Complete the layout
  2. Initialize the interaction, render the current ID of the shipping address, shopping cart selected item information, etc
  3. The receiving address is deleted, changed, or added
  4. The v-distpicker provincial and municipal linkage plug-in is used, and the usage method is available online
  5. The settlement of the order is completed and the order number is generated

9. Order payment function

  1. To complete the layout

  2. Implementing data interaction

  3. Alipay payment (back-end HTML from form code) for integration

  4. Wechat Pay, change the payment address of the back end into two-dimensional code display (Native payment)

  5. Wechat Pay polling to determine whether to pay (If the user has paid, jump to the order list page, close, the polling stops)

Wechat Pay: The content is a payment link, which can be converted to qr code for payment

Alipay payment: Content is HTML source code, after rendering to the page automatically jump to the payment page

Convert urls to QR codes using the QRCode plugin.

10. Order list function realization

  1. Interface implementation
  2. interaction
  3. Introduce the elementUI pager component and implement paging on demand
  4. Troubleshoot some backend interface errors, such as the personal address information interfacereceiverPhoneAnd the payment interfacereceiverPhoneOut of sync

There are three common paging functions: 1. Pager

2. Button loads more

3. Scroll to load more

11. Source code address

Project source address: GitHub portal

Welcome to learning and welcome to Star!