zoukankan      html  css  js  c++  java
  • 状态管理器和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 }) { // 参数解构 commit= context.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 // ++++++++++++++++++ // home = state.home
        })
      },
      created () {
        // 触发状态管理器中的actions
        this.$store.dispatch('getBannerlist')
        this.$store.dispatch('getProlist') // ++++++++++
      }
    }
    </script>
    
    <Prolist :prolist="prolist" />
    
    • 上拉加载下拉刷新 ---

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

  • 相关阅读:
    保护个人劳动成果----------代码混淆 (war/jar)
    获取计算机所有属性硬件信息
    得到某个文件夹下所有的文件名称
    下载的方法
    shell停止/启动/重启tomcat
    线程超时
    2020 0508 开通博客
    spring mvc 的一些状态码
    restful接口设计规范总结 转发的 第一次接触时候发现的文章(个人觉得不错)
    spring mvc常用注解
  • 原文地址:https://www.cnblogs.com/hy96/p/12063954.html
Copyright © 2011-2022 走看看