状态管理器和promise all

1、回顾

2、优化查看购物车接口

问题: 刷新购物车页面,列表请求不完整

算法: 异步中嵌套了 循环的异步---请求不完整

优化: promise.all() --- 把循环异步 ---- 等待所有的异步操作都介绍之后才会调用then

day06/myapp/routes/cart.js

router.get('/', function(req, res, next) {
  // 1、获取用户id
  let { userid } = req.query;
  let cartarr = [] // 用来记录 购物车的数据
  // 2、依据用户id查询购物车的数据
  sql.find(Cart, { userid }, { _id: 0 }).then(data => {
    // 如果没有数据,告诉用户没有数据
    if (data.length === 0) {
      // 2.1 没有数据
      res.send(utils.cartnull)
    } else {
      cartarr = data // 给购物车数据赋值 ---- 因为用到了promise
      let promise1 = data.map(item => {
        return sql.find(Pro, { proid: item.proid}, { _id: 0})
      })
      return Promise.all(promise1)
    }
  }).then(list => {
    console.log('list', list)
    console.log('cartarr', cartarr)
    let arr = []
    list.map((item, index) => {
      arr.push({
        proid: item[0].proid,
        proname: item[0].proname,
        proimg: item[0].proimg,
        price: item[0].price,
        cartid: cartarr[index].cartid,
        userid: cartarr[index].userid,
        num: cartarr[index].num
      })
    })
    res.send({
      code: '200',
      data: arr
    })
  })
});
  • 评论算法也需要使用promise.all

3、将token信息放入头信息中

  • 每次请求都要携带token,token可以get/post,还可以是 头信息

  • axios.get('/ ?token=' + token)

  • axios.post('/', {token: token})

封装axios http://www.axios-js.com/docs/

utils/request.js

import axios from 'axios'

let request = axios.create()

request.defaults.headers['token'] = localStorage.getItem('token')

export default request

使用时 直接 使用 import axios from '@/utils/reqest'代替 import axios form 'axios',然后把涉及到 token信息的地方全部取出即可

4、状态管理器

符合单向数据流,有效解决组件间的耦合问题

4.1 修改首页 --- 使用状态管理器管理状态

  • views/home/index.vue + views/home/store.js
// store.js
export default {
  state: {},
  getters: {},
  actions: {},
  mutations: {}
}

// ==>
import axios from '@/utils/request'
export default {
  state: { // 首页需要的初始化数据
    bannerlist: []
  },
  getters: { // state的计算属性
  },
  actions: { // 当前页面需要的异步操作
    getBannerlist (context) { // 请求轮播图数据,context上下文对象
      axios.get('/banner').then(res => {
        context.commit({ // 唯一改变状态管理器的方式就是显示的提交mutation
          type: 'changeBannerlist',
          data: res.data.data
        })
      })
    }
  },
  mutations: {
    changeBannerlist (state, data) {
      state.bannerlist = data.data
    }
  }
}
  • src/store/index.js 这里 划分 状态管理器模块
import Vue from 'vue'
import Vuex from 'vuex'
import home from '@/views/home/store' // ++++++++++++++

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    home // +++++++++++++++++++++
  }
})
  • 页面中使用状态管理器的状态以及触发相应的函数
// views/home/index.vue
<script>
import Vue from 'vue'
import { Swipe, SwipeItem } from 'vant'
import { mapState } from 'vuex'
Vue.use(Swipe).use(SwipeItem)
export default {
  data () {
    return {
    }
  },
  computed: { // 使用组件的计算属性获取状态管理器中的数据,具有依赖性
    ...mapState({ // 获取状态管理器中的数据
      bannerlist: (state) => { // 默认参数为state ---- 所有的状态state
        console.log(state) // { home: {}, kind: {}, cart: {}}
        return state.home.bannerlist
      }
    })
  },
  mounted () {
    // 触发状态管理器中的actions
    this.$store.dispatch('getBannerlist')
  }
}
</script>
  • 产品列表
// store.js
import axios from '@/utils/request'
export default {
  state: { // 首页需要的初始化数据
    bannerlist: [],
    prolist: [] // +++++++++++++++
  },
  getters: { // state的计算属性
  },
  actions: { // 当前页面需要的异步操作
    getBannerlist (context) { // 请求轮播图数据,context上下文对象
      axios.get('/banner').then(res => {
        context.commit({ // 唯一改变状态管理器的方式就是显示的提交mutation
          type: 'changeBannerlist',
          data: res.data.data
        })
      })
    },
    // ++++++++++++++++
    getProlist ({ commit }) { // 参数解构
      axios.get('/pro').then(res => {
        commit({
          type: 'changeProlist',
          data: res.data.data
        })
      })
    }
  },
  mutations: {
    changeBannerlist (state, data) {
      state.bannerlist = data.data
    },
    // +++++++++++++++++++++
    changeProlist (state, data) {
      state.prolist = data.data
    }
  }
}

// index.vue
<script>
import Vue from 'vue'
import { Swipe, SwipeItem } from 'vant'
import { mapState } from 'vuex'
import Prolist from '@/components/Prolist' // +++++++++
Vue.use(Swipe).use(SwipeItem)
export default {
  // ++++++++++++
  components: {
    Prolist
  },
  computed: { // 使用组件的计算属性获取状态管理器中的数据,具有依赖性
    ...mapState({ // 获取状态管理器中的数据
      bannerlist: (state) => { // 默认参数为state ---- 所有的状态state
        console.log(state) // { home: {}, kind: {}, cart: {}}
        return state.home.bannerlist
      },
      prolist: ({ home }) => home.prolist // ++++++++++++++++++
    })
  },
  created () {
    // 触发状态管理器中的actions
    this.$store.dispatch('getBannerlist')
    this.$store.dispatch('getProlist') // ++++++++++
  }
}
</script>

<Prolist :prolist="prolist" />
  • 上拉加载下拉刷新 ---

action 如果需要参数 ,必须传递对象,如果组件需要后续操作,必须使用promise

猜你喜欢

转载自www.cnblogs.com/hy96/p/12063954.html