关于vuex购物车实现的原理
1、模拟购物车功能 创建store/cart.jsexport default { state:{ cartlist: [] }, getters: { }, actions: { }, mutations: { }}2、添加该模块到状态管理器import Vue from 'vue...
1、模拟购物车功能
创建store/cart.js
export default {
state:{
cartlist: []
},
getters: {
},
actions: {
},
mutations: {
}
}
2、添加该模块到状态管理器
import Vue from 'vue'
import Vuex from 'vuex'
import cart from './cart.js'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
cart
}
})
export default store
3、cart组件中script.js
import {mapState} from 'vuex'
export default {
computed: {
...mapState({
'cartlist': ({cart}) => cart.cartlist
})
}
}
4、在store/cart.js中请求购物车数据
export default {
state:{
cartlist: []
},
getters: {
},
actions: {
getCartlist ({commit}) {
cartapi.getCartlist((data) => {commit('changeCartlist', data)})
}
},
mutations: {
}
}
5、实现请求数据的方法api/cart.js
import axios from 'axios'
export default {
getCartlist (cb) {
// axios请求数据,请求成功调用回调函数cb ---- 模拟数据data
var data = [
{id:1,name:'pro1',num:1,price:10},
{id:2,name:'pro2',num:2,price:20},
{id:3,name:'pro3',num:3,price:30},
{id:4,name:'pro4',num:4,price:40}
]
cb(data)
}
}
6、实现提交mutation改变cartlist----store/cart.js
export default {
state:{
cartlist: []
},
getters: {
},
actions: {
getCartlist ({commit}) {
cartapi.getCartlist((data) => {commit('changeCartlist', data)})
}
},
mutations: {
changeCartlist (state, data) {
state.cartlist = data
},
}
}
7、触发请求数据----cart组件中分发action----script.js
import {mapState} from 'vuex'
export default {
computed: {
...mapState({
'cartlist': ({cart}) => cart.cartlist
})
},
mounted () {
this.$store.dispatch('getCartlist')
}
}
8、计算商品的总数量和总价
8.1 store/cart.js中添加选项getters
export default {
state:{
cartlist: []
},
getters: {
totalCount(state){
let totalNum = 0
let totalPrice = 0
state.cartlist.filter((item) => {
totalNum += item.num * 1
totalPrice += item.num * item.price
})
return {
totalNum,
totalPrice
}
}
},
actions: {
getCartlist ({commit}) {
cartapi.getCartlist((data) => {commit('changeCartlist', data)})
}
},
mutations: {
changeCartlist (state, data) {
state.cartlist = data
},
}
}
8.2 cart组件中index.vue使用即可
8.2.1 直接获取store中的getters
<div>总量:{{this.$store.getters.totalCount.totalNum}}</div>
<div>总价:{{this.$store.getters.totalCount.totalPrice}}</div
8.2.2 使用mapGetters辅助函数减少代码量
script.js
import {mapState,mapGetters} from 'vuex'
export default {
computed: {
...mapState({
'cartlist': ({cart}) => cart.cartlist
}),
mapGetters(['totalCount'])
},
mounted () {
this.$store.dispatch('getCartlist')
}
}
index.vue
<div>总量:{{totalCount.totalNum}}</div>
<div>总价:{{totalCount.totalPrice}}</div
9、选择商品计算价格和数量
9.1 index.vue布局
<template>
<div>
<ul>
<li v-for='(item, index) in cartlist' :key="item.id">
<input type='checkbox' v-model='item.flag' />
{{ item.name}} ---- {{item.num}} ---- {{item.price}} -
</li>
</ul>
<div>总量:{{totalCount.totalNum}}</div>
<div>总价:{{totalCount.totalPrice}}</div>
</div>
</template>
<script src='./script.js'></script>
<style src="./style.scss"></style>
9.2 改造源数据 api/cart.js
import axios from 'axios'
export default {
getCartlist (cb) {
// axios请求数据,请求成功调用回调函数cb ---- 模拟数据data
var data = [
{id:1,name:'pro1',num:1,price:10},
{id:2,name:'pro2',num:2,price:20},
{id:3,name:'pro3',num:3,price:30},
{id:4,name:'pro4',num:4,price:40}
]
data.map((item) => {
item.flag = false
})
cb(data)
}
}
10、 实现全选和反选功能
10.1 index.vue布局
<template>
<div>
全选<input type='checkbox' @change="selectFn(cartlist)" v-model='allSelected' />
<ul>
<li v-for='(item, index) in cartlist' :key="item.id">
<input type='checkbox' v-model='item.flag' />
{{ item.name}} ---- {{item.num}} ---- {{item.price}} -
</li>
</ul>
<div>总量:{{totalCount.totalNum}}</div>
<div>总价:{{totalCount.totalPrice}}</div>
</div>
</template>
<script src='./script.js'></script>
<style src="./style.scss"></style>
10.2 store/cart.js添加新的初始值 allSelected
export default {
state:{
cartlist: [],
allSelected: false
},
getters: {
totalCount(state){
let totalNum = 0
let totalPrice = 0
state.cartlist.filter((item) => {
totalNum += item.num * 1
totalPrice += item.num * item.price
})
return {
totalNum,
totalPrice
}
}
},
actions: {
getCartlist ({commit}) {
cartapi.getCartlist((data) => {commit('changeCartlist', data)})
}
},
mutations: {
changeCartlist (state, data) {
state.cartlist = data
},
}
}
10.3 cart组件中添加全选事件
//index.vue
全选<input type='checkbox' @change="selectFn(cartlist)" v-model='allSelected' />
// script.js 中的methods
selectFn (cartlist) {
this.$store.commit('changeAllSelect') // 切换真假
//改变store中数据后立马请求其值
if(this.$store.state.cart.allSelected){ // 如果为真,表示全部要被选中
const flag = true // 标志为真
this.$store.dispatch('getAllSelectCartlist', {cartlist, flag} ) // action中设置所有元素为真
}else{
const flag = false
this.$store.dispatch('getAllSelectCartlist', {cartlist, flag} )
}
},
10.4 实现changeAllSelect mutation 和 getAllSelectCartlist action
store/cart.js
export default {
state:{
cartlist: [],
allSelected: false
},
getters: {
totalCount(state){
let totalNum = 0
let totalPrice = 0
state.cartlist.filter((item) => {
totalNum += item.num * 1
totalPrice += item.num * item.price
})
return {
totalNum,
totalPrice
}
}
},
actions: {
getCartlist ({commit}) {
cartapi.getCartlist((data) => {commit('changeCartlist', data)})
},
getAllSelectCartlist ({commit}, {cartlist, flag}) {
cartlist.map((item) => {
item.flag = flag
})
commit('changeCartlist', cartlist)
},},
mutations: {
changeCartlist (state, data) {
state.cartlist = data
},
changeAllSelect (state) {
state.allSelected = !state.allSelected
},}
}
11、点击列表选择实现全选和反选
<ul>
<li v-for='(item, index) in cartlist' :key="item.id">
<input type='checkbox' @change='selectItem(cartlist, item, index)' v-model='item.flag' />
{{ item.name}} ---- {{item.num}} ---- {{item.price}} -- <button @click="deleteItem(cartlist, index)">删除</button>
</li>
</ul>
script.js
selectItem (cartlist, item, index) {
if(item.flag){
const flag = true
this.$store.dispatch('selectItem', {cartlist, index, flag}) // cartlist[index].flag = flag
}else {
const flag = false
this.$store.dispatch('selectItem', {cartlist, index, flag})
}
// console.log("cartlist",this.$store.state.cart.cartlist)
var cartlist = this.$store.state.cart.cartlist
this.$store.dispatch('checkItem',cartlist) // 每做出一次选择就去检测要不要全选
}
实现action selectItem 和checkItem store/cart.js
export default {
state:{
cartlist: [],
allSelected: false
},
getters: {
totalCount(state){
let totalNum = 0
let totalPrice = 0
state.cartlist.filter((item) => {
totalNum += item.num * 1
totalPrice += item.num * item.price
})
return {
totalNum,
totalPrice
}
}
},
actions: {
getCartlist ({commit}) {
cartapi.getCartlist((data) => {commit('changeCartlist', data)})
},
getAllSelectCartlist ({commit}, {cartlist, flag}) {
cartlist.map((item) => {
item.flag = flag
})
commit('changeCartlist', cartlist)
},
selectItem ({commit}, {cartlist, index, flag}) {
cartlist[index].flag = flag
commit('changeCartlist', cartlist)
},
checkItem ({commit}, cartlist){
let all = true
cartlist.map((item) => {
if(!item.flag) {
all = false
}
})
commit('checkCartlist', all)
}
},
mutations: {
changeCartlist (state, data) {
state.cartlist = data
},
changeAllSelect (state) {
state.allSelected = !state.allSelected
},
}
}
实现mutation checkCartlist
export default {
state:{
cartlist: [],
allSelected: false
},
getters: {
totalCount(state){
let totalNum = 0
let totalPrice = 0
state.cartlist.filter((item) => {
totalNum += item.num * 1
totalPrice += item.num * item.price
})
return {
totalNum,
totalPrice
}
}
},
actions: {
getCartlist ({commit}) {
cartapi.getCartlist((data) => {commit('changeCartlist', data)})
},
getAllSelectCartlist ({commit}, {cartlist, flag}) {
cartlist.map((item) => {
item.flag = flag
})
commit('changeCartlist', cartlist)
},
selectItem ({commit}, {cartlist, index, flag}) {
cartlist[index].flag = flag
commit('changeCartlist', cartlist)
},
checkItem ({commit}, cartlist){
let all = true
cartlist.map((item) => {
if(!item.flag) {
all = false
}
})
commit('checkCartlist', all)
}
},
mutations: {
changeCartlist (state, data) {
state.cartlist = data
},
changeAllSelect (state) {
state.allSelected = !state.allSelected
},
checkCartlist (state, data) {
state.allSelected = data
}
}
}
12、删除操作
<ul>
<li v-for='(item, index) in cartlist' :key="item.id">
<input type='checkbox' @change='selectItem(cartlist, item, index)' v-model='item.flag' />
{{ item.name}} ---- {{item.num}} ---- {{item.price}} -- <button @click="deleteItem(cartlist, index)">删除</button>
</li>
</ul>
deleteItem (cartlist, index) {
this.$store.dispatch('deleteItem', {cartlist, index})
},
store/cart.js
export default {
state:{
cartlist: [],
allSelected: false
},
getters: {
totalCount(state){
let totalNum = 0
let totalPrice = 0
state.cartlist.filter((item) => {
totalNum += item.num * 1
totalPrice += item.num * item.price
})
return {
totalNum,
totalPrice
}
}
},
actions: {
getCartlist ({commit}) {
cartapi.getCartlist((data) => {commit('changeCartlist', data)})
},
getAllSelectCartlist ({commit}, {cartlist, flag}) {
cartlist.map((item) => {
item.flag = flag
})
commit('changeCartlist', cartlist)
},
selectItem ({commit}, {cartlist, index, flag}) {
cartlist[index].flag = flag
commit('changeCartlist', cartlist)
},
checkItem ({commit}, cartlist){
let all = true
cartlist.map((item) => {
if(!item.flag) {
all = false
}
})
commit('checkCartlist', all)
},
deleteItem ({commit}, {cartlist, index}) {
cartapi.deleteItem({cartlist, index}, (data) => {commit('changeCartlist', data)})
},
},
mutations: {
changeCartlist (state, data) {
state.cartlist = data
},
changeAllSelect (state) {
state.allSelected = !state.allSelected
},
checkCartlist (state, data) {
state.allSelected = data
}
}
}
api/cart.js
import axios from 'axios'
export default {
getCartlist (cb) {
// axios请求数据,请求成功调用回调函数cb ---- 模拟数据data
var data = [
{id:1,name:'pro1',num:1,price:10},
{id:2,name:'pro2',num:2,price:20},
{id:3,name:'pro3',num:3,price:30},
{id:4,name:'pro4',num:4,price:40}
]
data.map((item) => {
item.flag = false
})
cb(data)
},
deleteItem ({cartlist, index}, cb) {
cartlist.splice(index, 1)
cb(cartlist)
}
}
编辑:千锋HTML5
更多推荐
所有评论(0)