vuex实现购物车功能
购物车功能描述:
1. 点击+,-按钮,“已选:xx件”随之增减
2. checkbox选中时,当前项的已选数量增加到头部“已选择xx件”中,未选中时数量不计入
代码:
服务端 node+koa+koa-router
server.js
1 const koa = require('koa') 2 const router = require('koa-router') 3 4 let server = new koa() 5 server.listen(8081) 6 7 server.use(async (ctx, next) => { 8 ctx.set('Access-Control-Allow-Origin', '*') 9 10 await next() 11 }) 12 13 let r = router() 14 15 r.get('/list', async ctx => { 16 ctx.body = [{ 17 name: 'aa', 18 price: 358, 19 sales: 8531 20 }, 21 { 22 name: 'bb', 23 price: 18, 24 sales: 915 25 }, 26 { 27 name: 'cc', 28 price: 857, 29 sales: 28732 30 }, 31 { 32 name: 'dd', 33 price: 3, 34 sales: 5 35 }, 36 { 37 name: 'ee', 38 price: 67, 39 sales: 900 40 } 41 ] 42 }) 43 44 server.use(r.routes())
web端 vue+vuex+fetch
src/components/List.vue
1 <template> 2 <div class="list"> 3 <div>已选择 {{state.count}} 件</div> 4 <ul> 5 <ListItem v-for="(item,index) in items" :key="index" :data="item"/> 6 </ul> 7 </div> 8 </template> 9 <script> 10 import ListItem from 'components/ListItem' 11 export default { 12 name: 'List', 13 data() { 14 return { 15 items: [], 16 state: this.$store.state 17 } 18 }, 19 components: { 20 ListItem 21 }, 22 mounted() { 23 this.getData() 24 }, 25 methods: { 26 async getData() { 27 this.items = await (await fetch('http://localhost:8081/list')).json() 28 } 29 } 30 } 31 32 </script>
src/components/ListItem.vue
1 <template> 2 <div class="list-item"> 3 <li> 4 <span style="width: 80px;display: inline-block;"><input type="checkbox" v-model="isChecked"> {{data.name}}</span> 5 <span style="width: 120px;display: inline-block;">¥: {{data.price}}元</span> 6 <span style="width: 120px;display: inline-block;">销量: {{data.sales}}件</span> 7 <span style="width: 120px;display: inline-block;">已选: {{currentCount}}件</span> 8 <button @click="addOne">+</button> 9 <button @click="minusOne">-</button> 10 </li> 11 </div> 12 </template> 13 <script> 14 export default { 15 name: 'ListItem', 16 data() { 17 return { 18 data: {}, 19 isChecked: false, 20 currentCount: 1 21 } 22 }, 23 created() { 24 this.data = this.$attrs.data 25 }, 26 methods: { 27 addOne() { 28 this.currentCount++ 29 if (this.isChecked) { 30 this.$store.dispatch('add', 1) 31 } 32 }, 33 minusOne() { 34 if (this.currentCount <= 0) return 35 this.currentCount-- 36 if (this.isChecked) { 37 this.$store.dispatch('minus', 1) 38 } 39 } 40 }, 41 watch: { 42 isChecked() { 43 if (this.isChecked) { 44 this.$store.dispatch('add', this.currentCount) 45 } else { 46 this.$store.dispatch('minus', this.currentCount) 47 } 48 } 49 } 50 } 51 52 </script>
src/store/index.js
1 import Vue from 'vue' 2 import Vuex from 'vuex' 3 4 Vue.use(Vuex) 5 6 export default new Vuex.Store({ 7 strict: true, 8 state: { 9 count: 0 10 }, 11 mutations: { 12 add(state, arg) { 13 state.count += arg 14 }, 15 minus(state, arg) { 16 if (state.count <= 0) { 17 return false 18 } 19 state.count -= arg 20 } 21 }, 22 actions: { 23 add({ commit }, arg) { 24 commit('add', arg) 25 }, 26 minus({ commit }, arg) { 27 commit('minus', arg) 28 } 29 } 30 31 })