main.js
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'
Vue.config.productionTip = false
axios.defaults.baseURL = "http://localhost:3000/"
Vue.prototype.$axios = axios
new Vue({
render: h => h(App),
}).$mount('#app')
Vue.$axios
准备好一个接口,我自己用的是express搭建的,也可以用其他的,用axios来获取数据
根组件App.vue 导入每个子组件
<template>
<div>
<my-header color="#fff" tit="购物车" bgcolor="blue"></my-header>
<div class="main">
<MyGoods v-for="obj in list" :key="obj.id" :lists="obj"></MyGoods>
</div>
<MyFooter :num="allnum" :price="allPrice" :lists="list"></MyFooter>
</div>
</template>
<script>
import MyHeader from './components/MyHeader'
import MyGoods from './components/MyGoods'
import MyFooter from './components/MyFooter'
export default {
components: {
MyHeader,
MyGoods,
MyFooter
},
data () {
return {
list: []
}
},
created () {
this.$axios({
url: '/api/cart'
}).then(res => {
this.list = res.data.list
console.log(this.list);
})
},
computed:{
allnum(){
return this.list.reduce((num,lis)=>{
if(lis.goods_state){
num += lis.goods_count
}
return num
},0)
},
allPrice(){
return this.list.reduce((num,lis)=>{
if(lis.goods_state){
num += lis.goods_price * lis.goods_count
}
return num
},0)
},
}
}
</script>
<style lang="less" scoped>
.main{
padding-top: 45px;
padding-bottom: 50px;
}
</style>
头部组件
<template>
<div class="my-header" :style="{color:color,background:bgcolor}">{{ tit }}</div>
</template>
<script>
export default {
props: ["color","bgcolor","tit"]
}
</script>
<style lang="less" scoped>
.my-header {
height: 45px;
line-height: 45px;
text-align: center;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 2;
}
</style>
内容组件
<template>
<div class="my-goods-item" >
<div class="left">
<input type="checkbox" class="inp" name="check" v-model="lists.goods_state" :id="lists.id">
<label :for="lists.id">
<img :src=lists.goods_img alt="">
</label>
</div>
<div class="right">
<div class="top">{{lists.goods_name}}</div>
<div class="bottom">
<span class="price">¥{{ lists.goods_price }}</span>
<span>
<MyCount :lists="lists"></MyCount>
</span>
</div>
</div>
</div>
</template>
<script>
import MyCount from './MyCount.vue';
export default {
components: { MyCount },
props: ['lists']
}
</script>
<style lang="less" scoped>
.my-goods-item {
display: flex;
padding: 10px;
border-bottom: 1px solid #ccc;
.left {
display: flex;
.inp{
margin-right:10px ;
}
img {
width: 120px;
height: 120px;
margin-right: 8px;
border-radius: 10px;
}
}
.right {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
.top {
font-size: 14px;
font-weight: 700;
}
.bottom {
display: flex;
justify-content: space-between;
padding: 5px 0;
align-items: center;
.price {
color: red;
font-weight: bold;
}
}
}
}</style>
控制数量的组件
<template>
<div class="my-counter">
<button type="button" class="btn" @click="sub" :disabled="lists.goods_count==1">-</button>
<input type="number" class="inp" v-model="lists.goods_count">
<button type="button" class="btn" @click="add">+</button>
</div>
</template>
<script>
export default {
props: ["lists"],
methods: {
add(){
this.lists.goods_count++;
},
sub(){
this.lists.goods_count--;
}
},
watch: {
lists:{
handler(){
if(this.lists.goods_count < 1){
this.lists.goods_count = 1;
}
},
deep:true
}
}
}
</script>
<style lang="less" scoped>
.my-counter {
display: flex;
.inp {
width: 30px;
text-align: center;
margin: 0 6px;
}
.btn{
width: 20px;
}
}
</style>
底部组件
<template>
<!-- 底部 -->
<div class="my-footer">
<!-- 全选 -->
<div >
<input type="checkbox" v-model="isSelect">
<label for="footerCheck" >全选</label>
</div>
<!-- 合计 -->
<div>
<span>合计:</span>
<span class="price">¥ {{price}}</span>
</div>
<!-- 按钮 -->
<button type="button" class="footer-btn">结算 ( {{num}} )</button>
</div>
</template>
<script>
export default {
props: ["num","price","lists"],
computed: {
isSelect: {
set(value) {
this.lists.forEach(item => item.goods_state = value)
},
get(){
return this.lists.every(item => item.goods_state)
}
}
}
}
</script>
<style lang="less" scoped>
.my-footer {
position: fixed;
z-index: 2;
bottom: 0;
width: 100%;
height: 50px;
border-top: 1px solid #ccc;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
background: #fff;
box-sizing: border-box;
.price {
color: red;
font-weight: bold;
font-size: 15px;
}
.footer-btn {
min-width: 80px;
height: 30px;
line-height: 30px;
border-radius: 25px;
padding: 0;
border: none;
background: rgb(81, 142, 255);
color: white;
}
}
</style>