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