一、项目截图
二、主要知识点
三、需要注意的点
json-server 安装成功,查看版本直接报错。安装默认版本埋下的一个坑,和node版本不匹配 作者直接安装vuex,默认安装也是版本不匹配,启动没报错,但是没法使用。作者是vue2版本,使用的vuex@3.1.1版本,安装的时候指定版本就好了
四、Main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store' Vue. config. productionTip = false new Vue ( { store, render : h => h ( App)
} ) . $mount ( '#app' )
五、App.vue
< template> < div class = " app-container" > < cart-header> </ cart-header> < cart-item v-for = " item in list" :key = " item.id" :item = " item" > </ cart-item> < cart-footer> </ cart-footer> </ div>
</ template> < script>
import CartHeader from '@/components/cart-header.vue'
import CartFooter from '@/components/cart-footer.vue'
import CartItem from '@/components/cart-item.vue'
import { mapState} from "vuex" ; export default { name : 'App' , components : { CartHeader, CartFooter, CartItem} , computed : { ... mapState ( 'cart' , [ 'list' ] ) } , created ( ) { this . $store. dispatch ( 'cart/getList' ) }
}
</ script> < style lang = " less" scoped >
.app-container { padding : 50px 0; font-size : 14px;
}
</ style>
六、components
cart-footer.vue
< template> < div class = " footer-container" > < div> < span> 共 {{total}} 件商品,合计:</ span> < span class = " price" > ¥{{ totalPrice}}</ span> </ div> < button class = " btn btn-success btn-settle" > 结算</ button> </ div>
</ template> < script>
import { mapGetters} from 'vuex' export default { name : 'CartFooter' , computed : { ... mapGetters ( 'cart' , [ 'total' , 'totalPrice' ] ) }
}
</ script> < style lang = " less" scoped >
.footer-container { background-color : white; height : 50px; border-top : 1px solid #f8f8f8; display : flex; justify-content : flex-end; align-items : center; padding : 0 10px; position : fixed; bottom : 0; left : 0; width : 100%; z-index : 999;
} .price { color : red; font-size : 13px; font-weight : bold; margin-right : 10px;
} .btn-settle { height : 30px; min-width : 80px; margin-right : 20px; border-radius : 20px; background : #42b983; border : none; color : white;
}
</ style>
cart-header.vue
< template> < div class = " header-container" > 购物车案例</ div>
</ template> < script>
export default { name : 'CartHeader'
}
</ script> < style lang = " less" scoped >
.header-container { height : 50px; line-height : 50px; font-size : 16px; background-color : #42b983; text-align : center; color : white; position : fixed; top : 0; left : 0; width : 100%; z-index : 999;
}
</ style>
cart-item.vue
< template> < div class = " goods-container" > < div class = " left" > < img :src = " item.thumb" class = " avatar" alt = " " > </ div> < div class = " right" > < div class = " title" > {{ item.name }}</ div> < div class = " info" > < span class = " price" > {{ item.price }}</ span> < div class = " btns" > < button class = " btn btn-light" @click = " btnClick(-1)" > -</ button> < span class = " count" > {{ item.count }}</ span> < button class = " btn btn-light" @click = " btnClick(1)" > +</ button> </ div> </ div> </ div> </ div>
</ template> < script>
export default { name : 'CartItem' , props : { item : { type : Object, request : true } } , methods : { btnClick ( step ) { const newCount = this . item. count + step; const id = this . item. id; if ( newCount < 1 ) return ; this . $store. dispatch ( 'cart/updateCountAsync' , { id, newCount} ) } }
}
</ script> < style lang = " less" scoped >
.goods-container { display : flex; padding : 10px; + .goods-container { border-top : 1px solid #f8f8f8; } .left { .avatar { width : 100px; height : 100px; } margin-right : 10px; } .right { display : flex; flex-direction : column; justify-content : space-between; flex : 1; .title { font-weight : bold; } .info { display : flex; justify-content : space-between; align-items : center; .price { color : red; font-weight : bold; } .btns { .count { display : inline-block; width : 30px; text-align : center; } } } }
} .custom-control-label::before,
.custom-control-label::after { top : 3.6rem;
}
</ style>
七、store
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import cart from "./modules/cart" ; Vue. use ( Vuex) export default new Vuex. Store ( { modules : { cart}
} )
modules/cart.js
import axios from "axios" ; export default { namespaced : true , state ( ) { return { list : [ ] } } , mutations : { updateList ( state, newList ) { state. list = newList} } , actions : { async getList ( context ) { const res = await axios. get ( "http://localhost:3000/cart" ) context. commit ( 'updateList' , res. data) } , async updateCountAsync ( context, obj ) { await axios. patch ( ` http://localhost:3000/cart/ ${ obj. id} ` , { count : obj. newCount} ) this . dispatch ( 'cart/getList' ) } } , getters : { total ( state ) { return state. list. reduce ( ( sum, item ) => sum + item. count, 0 ) ; } , totalPrice ( state ) { return state. list. reduce ( ( sum, item ) => sum + item. count * item. price, 0 ) ; } }
}