购物车案例
一、流程
1、全局配置axios(创建单独请求)
2、自定义标题(父传子)
3、渲染页面
4、计算总价、数量(计算属性)
5、实现全选,全不选
(一)全局配置axios
在request.is中配置全局url,方便以后不用配置
// 引入axios资源插件
import axios from 'axios';
// 设置全局配置Url
axios.defaults.baseURL = 'https://www.escook.cn'
// 暴露该axios
export default axios
在cart.js中引入全局url配置,封装一个获取商品信息的函数
// 引入全局配置axios url的配置
import axios from '../utils/cartrequest'
// 输出一个获取商品信息的函数
export function getCartList() {
return axios({
url: '/api/cart ',
})
}
在cart.vue中引入该方法
import { getCartList } from "@/apis/cart";
(二)自定义标题
父组件传递子组件需要的数据
<template>
<div class="nav">
<!-- 使用:把text,bgcolor,textcolor传递给子组件 -->
<MyHeader :text="text" :bgcolor="'blue'" :textcolor="'orange'"></MyHeader>
<MyGoods></MyGoods>
<MyFooter></MyFooter>
</div>
</template>
data() {
return {
text: "我的购物车",
};
},
子组件接收父组件的数据
<template>
<div class="my-header" :style="{ background: bgcolor, color: textcolor }">
{{ text }}
</div>
</template>
<script>
export default {
// 使用props接收父盒子传递的信息,并规定接收的类型(String,Number),和是否必须传递(required),如果未传递则为默认值(default)
props: {
text: {
type: [String, Number],
required: true,
},
bgcolor: {
type: String,
default: "red",
},
textcolor: {
type: String,
default: "green",
},
},
};
</script>
(三)渲染页面
在父组件中
<!-- 根据获取的商品信息循环生成结构,并把每个商品信息传递给子组件 -->
<MyGoods v-for="item in list" :key="item.id" :list="item"></MyGoods>
data() {
return {
text: "我的购物车",
// list存储获取的数据
list: [],// 从服务器中获取商品信息,因为需要在渲染前需要获取数据,所以用created
created() {
getCartList().then((res) => {
console.log(res);
this.list = res.data.list;
});
},
};
},
在子组件中
<template >
<div class="my-goods-item">
<div class="left">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="input" />
<label class="custom-control-label" for="input">
<!-- 单标签不能使用插值表达式💥 -->
<img :src="list.goods_img" alt="" />
</label>
</div>
</div>
<div class="right">
<div class="top">{{ list.goods_name }}</div>
<div class="bottom">
<span class="price">¥ {{ list.goods_price }}</span>
<MyCount :list="list"></MyCount>
</div>
</div>
</div>
</template>
<script>
// 引入增减文件
import MyCount from "./MyCount.vue";
export default {
// 接收父组件的商品信息
props: {
list: {
type: Object,
required: true,
},
},
components: {
MyCount,
},
};
</script>
(四)计算总价、数量(计算属性)
<template>
<!-- 底部 -->
<div class="my-footer">
<!-- 全选 -->
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="footerCheck" />
<label class="custom-control-label" for="footerCheck">全选</label>
</div>
<!-- 合计 -->
<div>
<span>合计:</span>
<span class="price">¥ {{ getTotalPrice }}</span>
</div>
<!-- 按钮 -->
<button type="button" class="footer-btn btn btn-primary">
结算 ( {{ getTotalCount }} )
</button>
</div>
</template>
<script>
export default {
// 接收父组件的商品信息
props: {
list: {
type: Array,
required: true,
},
},
// 使用计算属性计算总价和数量
computed: {
getTotalPrice() {
let total = 0;
this.list.forEach((v) => {
if (v.goods_state) {
total += v.goods_count * v.goods_price;
}
});
return total;
},
getTotalCount() {
let count = 0;
this.list.forEach((v) => {
if (v.goods_state) {
count++;
}
});
return count;
},
},
};
</script>
(五)实现全选,全不选
用计算属性实现
<div class="custom-control custom-checkbox">
<input
type="checkbox"
class="custom-control-input"
id="footerCheck"
v-model="checkAll"
/>
<label class="custom-control-label" for="footerCheck">全选</label>
</div>
// 设置是否全选
checkAll: {
// get用来设置子按钮影响全选按钮
get() {
// 遍历数组当一个假则为假
return this.list.every((v) => v.goods_state);
},
// set用来设置全选按钮影响子按钮
set(value) {
this.list.forEach((v) => {
// 当全选按钮为真则子按钮全为真。。
v.goods_state = value;
});
},
},
\