最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • vuex 我在项目中是这样统一接管请求的

    正文概述 掘金(赖先生)   2021-01-06   639

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

    一、介绍

    1. 请求的统一管理是每个项目不可缺少的重要组成部分;
    2. 该篇文章编写的时间有点久远了 2018 年写的; 针对的是 vue2.x 语法;
    3. 新版 vue3.x + vuex 语法可跳转前段时间文章 juejin.cn/post/688786…;
    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>

    四、结尾

    文章来源: 自己博客文章 https://www.cnblogs.com/ljx20180807/p/9838259.html


    起源地下载网 » vuex 我在项目中是这样统一接管请求的

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元