Vue: vue2.0 family bucket to build element-ui+axios+vuex+mockjs

As a front-end person, and as a front-end person who has used the vue framework, I believe I have heard of the vue family bucket (1. project construction tool vue-cli, 2. routing vue-router: http: //router.vuejs .org , 3. State management vuex: http://vuex.vuejs.org , 4. HTTP request tool axios: http://www.axios-js.com/zh-cn/docs/ , 5. Style element- ui: https://element.eleme.cn/#/zh-CN/component/installation , 6. And sometimes the background does not provide an interface and you need to simulate the data request yourself, I often use mockjs). In order to facilitate communication with everyone, I will record the method of building my own project.

  • Initialize the vue2.0 project
  • use elment-ui
  • use axios
  • use mockjs
  • use vuex

1. Initialize the project

I have shared how to install vue-cli 2.0 and build the project before . If you forget, you can check the previous blog. Here I will directly use the scaffolding to install the project;

vue init webpack vue_all  //默认安装即可,vue-router就已经安装整合到项目中
cd vue_all
npm run dev  //运行项目即可

If you want to encapsulate components and register them as global components, create a base folder under components to store components that need to be registered globally, and write the following code in the mian.js file:

// 引用公共组件
let componentFiles = require.context('./components/base', false, /\.vue$/)
componentFiles.keys().map((item, index) => {
  let componentFile = item.replace(/^\.\/(.*)\.\w+$/, '$1');
  let value = componentFiles(item)
  Vue.component(`cui${componentFile}`, value.default)
})

Two, element-ui

1.	npm i element-ui –save   //安装element-ui插件
2.	在main.js文件中输入以下代码:
	import ElementUI from 'element-ui'
	import 'element-ui/lib/theme-chalk/index.css'
	Vue.use(ElementUI)
3. 若想按需引入组件,则可以按照element-ui官网进行相关插件安装,官网地址:https://element.eleme.cn/#/zh-CN/component/quickstart
4. 这里只是介绍简单项目搭建,若想更加深入的了解可去官网查看

insert image description here
The above completes the installation of element-ui. Refer to the components and usage methods given on the official website, and call them where needed on the page.
insert image description here

3. Axios

Axios is implemented by promise. When mentioning promise, you should first think that IE does not support it, so you should add a spacer first to do compatibility processing for IE:

npm install --save babel-polyfill  //安装es6转译组件
然后再main.js中引入 :
import 'babel-polyfill'
  1. install axios
npm i axios --save
  1. In order to facilitate the management of interfaces in the project, I often package axios twice: the
    package directory structure is:
    insert image description here
    The code in index.js is as follows:
const context = require.context('./modules', false, /\.js$/);
const path=require("path")
let Api = {}
context.keys().map((m, k) => {
  let strFileName = m.replace(/(.*\/)*([^.]+).*/ig,"$2");
  let data=context(m).default;
  Api[strFileName]=data
}, {})

export default Api;

The code in config.js is as follows:

import axios from 'axios';
// 使用element-ui Message做消息提醒
import {Message} from 'element-ui';

// 创建实例时设置配置的默认值

/**
 * 自定义实例默认值
 */
var instance = axios.create({
//   baseURL: "/api", // 因为我本地做了反向代理
  timeout: 10000,
  // responseType: "json",
  // withCredentials: true, // 是否允许带cookie这些
  // headers: {
  //   "Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
  // }
});
// /api/getUserById


// 请求拦截器, 进行一个全局loading  加载,这种情况下所有的接口请求前 都会加载一个loading

/**
 * 添加请求拦截器 ,意思就是发起请求接口之前做什么事,一般都会发起加载一个loading
 * */

//  如果不想每个接口都加载loading ,就注释掉请求前拦截器,在http这个类中处理

instance.interceptors.request.use(
  config => {
    // 在发送请求之前做些什么(... 这里写你的展示loading的逻辑代码 )
    isShowLoading(false);
    // 获取token,配置请求头
    // const TOKEN = localStorage.getItem('Token')
    // 演示的token(注意配置请求头,需要后端做cros跨域处理,我这里自己前端配的跨域)
    const TOKEN = '1fd399bdd9774831baf555ae5979c66b'
    if (TOKEN) {
      // 配置请求头 token
      config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
      config.headers['Authorization'] = TOKEN;
    }
    return config;
  },
  error => {
    // 对请求错误做些什么,处理这个错误

    // 可以直接处理或者展示出去,toast show()
    console.warn(error);
    // Message({
    //     //  饿了么的消息弹窗组件,类似toast
    //     showClose: true,
    //     message: error && error.data.error.message,
    //     type: 'error'
    //   });
    Message.error(err.message)
    return Promise.reject(error);
  }
);

/**
 * 添加响应拦截器,意思就是发起接口请求之后做什么事,此时只有两种情况,
 * 要么成功,要么失败,但是不管成功,还是失败,我们都需要关闭请求之前的
 * 发起的loading,那既然要处理loading,就把loading做成全局的了,
 * 这里自定义一个处理加载loding 和关闭loading的方法,而且这个loading
 * 要不要加载,会根据外部传入的布尔值来决定,默认是false:不展示
 * */

instance.interceptors.response.use(
  function (response) {
    // 对响应数据做点什么
    isShowLoading(false);
    console.log(response)
    // 根据你们家的后端定义请求过期后返回的参数,处理token过期问题
    // 我这个接口木有token啊,这里演示下
    // 判断
    const {
      status
    } = response.data;
    // 判断状态码401或者其它条件,不知道判断哪个的去问你家后台
    // if (Object.is(status, 401)) {
    // token过期后处理
    // 1.删除你本地存储的那个过期的token

    // 2. 跳转到登陆页(因为没有装路由,不写了,重新登陆赋值)

    //  todo...
    // }
    // 根据后端接口code执行操作
    // switch(response.data.code) {
    //处理共有的操作
    // }
    return response.data;
  },
  function (error) {
    // 对响应错误做点什么
    isShowLoading(false);
    if (error && err.response) {
      switch (err.response.status) {
        case 400:
          err.message = '错误请求'
          break;
        case 401:
          err.message = '未授权,请重新登录'
          break;
        case 403:
          err.message = '拒绝访问'
          break;
        case 404:
          err.message = '请求错误,未找到该资源'
          break;
        case 405:
          err.message = '请求方法未允许'
          break;
        case 408:
          err.message = '请求超时'
          break;
        case 500:
          err.message = '服务器端出错'
          break;
        case 501:
          err.message = '网络未实现'
          break;
        case 502:
          err.message = '网络错误'
          break;
        case 503:
          err.message = '服务不可用'
          break;
        case 504:
          err.message = '网络超时'
          break;
        case 505:
          err.message = 'http版本不支持该请求'
          break;
        default:
          err.message = `连接错误${err.response.status}`
      }
    } else {
      err.message = "连接到服务器失败"
    }
    Message.error(err.message)
    return Promise.reject(error);
  }
);

// 如果与你配合的ui中,有loading组件的话,你直接用它的就可以了

// to do...
/**
 * 是否开启loading
 * @param {*} payload { type:Boolean }
 */

function isShowLoading(payload) {
  // 获取dom节点
  const loading = document.getElementById('loading');
  payload ? loading.style.display = 'block' : loading.style.display = 'none';

}

/**
 * 使用es6中的类,进行简单封装
 */

let http = {
  // 使用async ... await
  //   static async get(url, params, isShow = false) {
  //     console.log(params)
  //     isShowLoading(isShow)
  //     return await instance.get(url, {
  //       params
  //     })
  //   }
  //   static async post(url, params, isShow = false) {
  //     console.log(params)
  //     isShowLoading(isShow)
  //     return await instance.post(url, params);
  //   }
  // get请求
  get(url, param = {}, isShow = false) {
    isShowLoading(isShow)
    return new Promise((resolve, reject) => {
      instance.get(url, {
          params: param
        })
        .then(res => {
          resolve(res)
        }, err => {
          reject(err)
        })
    })
  },
  // post请求
  post(url, param = {}, isShow = false) {
    isShowLoading(isShow)
    return new Promise((resolve, reject) => {
      instance.post(
        url,
        param
      ).then(res => {
        resolve(res)
      }, err => {
        reject(err)
      })
    })
  },
  // put请求
  put(url, param = {}, isShow = false) {
    isShowLoading(isShow)
    return new Promise((resolve, reject) => {
      instance.put(url, param)
        .then(response => {
          resolve(response)
        }, err => {
          reject(err)
        })
    })
  },
  // delete
  delete(url, param = {}, isShow = false) {
    isShowLoading(isShow)
    return new Promise((resolve, reject) => {
      instance.delete(url, param)
        .then(response => {
          resolve(response)
        }, err => {
          reject(err)
        })
    })
  }
}


export default http;

The modules folder is the interface file of each module. The goods.js file is a demo file written by me. The content is as follows:

import http from "../config";
export default {
    getGoods(params={}){
        return http.get("/goods/getGoods",params)  
    }
}

After the secondary encapsulation is completed, introduce it in the main.js file and mount the interface on the prototype method of vue:

insert image description here
Just call the prototype method of vue on the page that needs to send the request:
insert image description here

4. MockJs

  1. npm install mockjs --save-dev //install mock;
  2. Create a mock folder under the src folder, create an index.js file, and the content of the file is as follows:
const Mock = require('mockjs');
Mock.mock('/goods/getGoods', 'get', () => {
  return {
    status: '0',
    msg: '',
    data: [{
      _id:1,
      productId: "201710003",
      productName: "平衡车",
      salePrice: 1999,
      productImage: "pingheng.jpg",
      productUrl: ""
    }]
  }
});

  1. Introduced in the main.js file
    insert image description here

Five, vuex

Vuex is an essential part of using vue. Based on parent-child and brother components, it may be convenient for us to pass values, but if the same set of data is used between unrelated components, it seems very powerless, then vuex is very good It solves our problem. It is equivalent to a public warehouse, which stores data that can be shared by all components. Under normal circumstances, vuex is written in a file, but when the project is relatively large, it is easy to cause data coupling. In order to facilitate maintenance, the data needs to be modularized. Here I introduce the modular package:

The directory structure is as follows:
insert image description here
The content of the index.js file is as follows:

import Vue from 'vue';
import Vuex from 'vuex';
import getters from './getters'

Vue.use(Vuex);

const modulesFiles = require.context('./modules', false, /\.js$/)

const modules = modulesFiles.keys().reduce((modules, modulePath) => {
 
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})


const store = new Vuex.Store({
  modules,
  getters
});


export default store;

The content of the getters.js file is as follows:

const getters = {
    //getters 文件为导出state里面的数据,导出格式state => state.Login.userCode ,
    //表示store/modules/Login/Login.js里面的state里的变量userCode
    //如果不是很懂,下面会介绍在state存数据
    goodsList : state => state.goods.goodsList ,
  }
  export default getters

The contents of the mutations_type.js file are as follows:


export const GOODS_GET = 'GOODS_GET';
export const GOODS_ADD = 'GOODS_ADD';

The modules folder is the relevant state of each module stored in vuex:

import * as mutationTypes from "../mutation_types.js"
const state={
    goodsLength:0,
    goodsList:[],  //初始化一个userCode变量
};
// 赋值方法    
const mutations={
     [mutationTypes.GOODS_GET]: (state, device) => {//如何变化userCode,插入device
        state.goodsList = device;
        state.goodsLength=device.length?device.length:0;
      },
 };
 //调用方法
const actions={
    getGoods({ commit }, {$net,params}) {//触发mutations里面的userCodeChang ,传入数据形参device 对应到device
        return new Promise((resolve,reject)=>{
            $net(params).then(res=>{
                commit(mutationTypes.GOODS_GET, res.data)
                resolve(res)
            }).catch(err=>{
                reject(err)
            })
        })
      },
};
export default {
     namespaced:true,//用于在全局引用此文件里的方法时标识这一个的文件名
     state,
     mutations,
     actions
}

Introduced in mian.js file

// vuex的引入
import store from './store'
new Vue({
  el: '#app',
  router,
  store,
  components: {
    App
  },
  template: '<App/>'
})

Where it needs to be called in the page, make a call:

this.$store
      .dispatch("goods/getGoods", {
        $net: this.$api.goods.getGoods,
        params: []
      })
      .then(res => {
        debugger;
      });

Note:
[vuex] vuex requires a Promise polyfill in this browser. To report this error, you
need to install babel-polyfill,
and then configure the entry in webpack.base.conf.js ['babel-polyfill','./ src/main.js']

The above is just a unified integration of the vue family bucket, which is convenient for the development of vue projects. One person has a short skill, and everyone has a strong skill. Welcome to communicate with each other. If you encounter problems later, I will continue to modify this document!

Guess you like

Origin blog.csdn.net/weixin_44599809/article/details/104145173