zoukankan      html  css  js  c++  java
  • vuex 我在项目中是这样统一接管请求的

    关注公众号: 微信搜索 web全栈进阶 ; 收货更多的干货

    一、介绍

    1. 请求的统一管理是每个项目不可缺少的重要组成部分;
    2. 该篇文章编写的时间有点久远了 2018 年写的; 针对的是 vue2.x 语法;
    3. 新版 vue3.x + vuex 语法可跳转前段时间文章 https://juejin.cn/post/6887867687897301006;
    4. 最近在把博客园那边的文章渐渐的搬过来,所以没太多的新东西...
    5. vue3.x、 Flutter、 SSR、 Node、 数据可视化可查看前段时间文章;
    6. 最近在把原有项目使用微前端 qiankun 重构(vue3+TSUmi3.x+react16+TS); 踩坑中... ; 后面分享出来

    二、async/await

    先看看 async/await 的语法

    async 函数返回一个 Promise 对象

    async 函数内部 return 返回的值。会成为 then 方法回调函数的参数。

    async function fn() {
        return 'hello world'
    };
    fn().then( res => console.log(res))
    // hello world
    

    如果 async 函数内部抛出异常,则会导致返回的 Promise 对象状态变为 reject 状态。

    抛出的错误而会被 catch 方法回调函数接收到。

    async function fn(){
        throw new Error('error');
    }
    fn()
      .then(res => console.log(resd))
      .catch( err => console.log(err));
    

    async 函数返回的 Promise 对象,必须等到内部所有的 await 命令的 Promise 对象执行完,才会发生状态改变

    也就是说,只有当 async 函数内部的异步操作都执行完,才会执行 then 方法的回调。

    const delay = timeout => new Promise(resolve=> setTimeout(resolve, timeout));
    async function fn(){
        await delay(1000);
        await delay(2000);
        await delay(3000);
        return 'done';
    }
    fn().then(res => console.log(res));
    // 等待6s后才输出 'done'
    

    正常情况下,await 命令后面跟着的是 Promise ,如果不是的话,也会被转换成一个 立即 resolvePromise
    如下面这个例子:

    async function  fn() {
        return await 1
    };
    fn().then( res => console.log(res))
    // 1
    

    如果返回的是 reject 的状态,则会被 catch 方法捕获。

    Async 函数的错误处理

    async 函数的语法不难,难在错误处理上。
    先来看下面的例子:

    let a;
    async function fn() {
        await Promise.reject('error');
        a = await 1; // 这段 await 并没有执行
    }
    fn().then(res => console.log(res));
    

    如上面所示,当 async 函数中只要一个 await 出现 reject 状态,则后面的 await 都不会被执行。
    解决办法:可以添加 try/catch

    // 正确的写法
    let a;
    async function correct() {
        try {
            await Promise.reject('error')
        } catch (error) {
            console.log(error);
        }
        a = await 1;
        return a;
    }
    
    correct().then(res => console.log(res)); // 1
    

    如果有多个 await 则可以将其都放在 try/catch 中。

    三、项目中结合Vuex

    如何引入Vuex 以及编写

    stroe.js

    // stroe.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    import actions from './actions'
    
    Vue.use(Vuex)
    
    export const name = 'contract'
    
    const state = {
      // 数据字典
      initData: [],
      number: ''
    }
    
    const mutations = {
      // 获取数据字典
      SET_INIT_DATA (_state, obj) {
        _state.initData = obj
      },
      // 获取分单申请ID集合
      SET_NUMBER(_state, data) {
        _state.number = data
        console.log(_state)
      }
    }
    
    // 向外暴露store 对象
    const store = new Vuex.Store({
      namespaced: true,
      name,
      state,
      actions,
      mutations,
    })
    
    // 模块动态注册   项目庞大接口数量很大是便于管理  有疑惑 直戳 https://vuex.vuejs.org/zh/guide/modules.html 去vuex官网看看解释的更详细
    store.registerModule(name, {
      namespaced: true,
      name,
      state,
      actions,
      mutations,
    })
    
    export default store
    

    actions.js 文件

    // actions.js
    import axios from 'axios';
    
    const ajax = {
      // 获取数据字典
      GET_INIT_DATA: `agreement/init?`,
      // 获取编号
      GET_CONTRACT_NUMBER: `agreement/archive?`,
      // 保存基本信息
      SUBMIT_INFO: `agreement/submit/basic?`
    }
    // 提取公共部分
    const API_URL = 'product/v1/middle/';
    
    // 增加前缀
    let INTERFACE = {};
    for (let key in ajax) {
      INTERFACE[key] = API_URL + ajax[key];
    }
    
    // 获取编号
    function getContractNumber({commit}) {
      return new Promise((resolve, reject) => {
        axios.get(INTERFACE.GET_CONTRACT_NUMBER).then(data => {
          commit('SET_NUMBER', {data})   // 改变state.number
          resolve(data.data)
        }).catch((err) => {
          window.Alert(err)
        })
      })
    }
    // 获取数据字典
    async function getInitData({commit, state}, params) {
     const num = await getContractNumber()
      return new Promise((resolve, reject) => {
        axios.get(INTERFACE.GET_INIT_DATA).then((data) => {
        commit('SET_INIT_DATA', {data})   // 改变state.initData
          resolve(data.data)
        }).catch((err) => {
          window.Alert(err)  // 全局错误提示
        })
      })
    }
    
    // 获取详情
    function getInfo(id) {
      return new Promise((resolve, reject) => {
        // 写法2 模板字符串语法
        axios.get(`apply/v1/${id}/input?`).then(data => {
          resolve(data.data)
        }).catch((err) => {
          window.Alert(err) // 全局错误提示
        })
      })
    }
    
    // 提交
    async function onSubmit({commit}, params) {
      const result = await getInfo()
      console.log(result)
      return new Promise((resolve, reject) => {
        axios.post(`${INTERFACE.SUBMIT_INFO}/${result.num}/products`, {...params}).then(data => {
          resolve(data)
        }).catch((err) => {
          window.Alert(err)  // 全局错误提示
        })
      })
    }
    
    export default {
      saveContrantInfo,
      getContractNumber,
      getInitData,
      getInfo,
      onSubmit
    }
    

    index.vue文件调用

    <script>
      import { name as moduleName } from '@/store'
      export default {
        data() {
          return {
             // 基本信息
             contractInfo: {},
             // 数据字典
             baseData: []
          }
        },
        created() {
          // 获取基本信息 若要then有返回值  actions 必须 resolve() 不然 then 方法没用
          this.$store.dispatch(`${moduleName}/getInfo`).then(data => {
            console.log(data)
          })
          // 获取数据字典
          this.$store.dispatch(`${moduleName}/getInitData`).then(data => {
            Object.assign(this.baseData, data)
          })
        },
        methods: {
          // 获取编号
          async getNumber() {
            // 在 actions 函数里 await 也行 看具体需求   此例只作为演示 await 调用
            const obj = await this.$store.dispatch(`${moduleName}/getContractNumber`)
            this.contractInfo.fileNo = obj.fileNo
          },
          // 提交
          submit() {
            this.$store.dispatch(`${moduleName}/onSubmit`, this.contractInfo).then(data => {
              console.log(data)
            })
          }
        }
      }
    </script>
    
  • 相关阅读:
    起名
    用超级巡警批量清除被挂马的网页
    我在csdn回复的帖子
    多线程与socket编程
    NET面试汇总
    第5 章: Windows Message Mapping 20080111 09:04 207人阅读 评论(0) 收藏
    oo的开始 分类: VC++ 20071228 14:31 176人阅读 评论(0) 收藏
    Cstring 截获数据 20080110 11:22 234人阅读 评论(0) 收藏
    截取字符串 20080110 08:18 188人阅读 评论(0) 收藏
    CString DOWRD互转 20080110 08:26 378人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/ljx20180807/p/9838259.html
Copyright © 2011-2022 走看看