1.index.vue
1.1安装依赖
yarn add axios vant amfe-flexible router
1.2引入依赖 main.js
import Vue from 'vue'
import router from './router'
import 'amfe-flexible/index.js'
import Vant from 'vant'
import 'vant/lib/index.css'
import axios from 'axios'
Vue.config.productionTip = false
Vue.filter("formats",function(val,params){
return "$"+val.toFixed(params);
}
)
Vue.filter("format",function(val){
if(val.length>7){
val=val.slice(0,7)+'...'
}
return val
})
Vue.use(Vant)
Vue.prototype.axios=axios;
1.3新建组件components/Shop.vue
<template>
<div class="container">
<div class="box">
<p>购物车</p>
<p>您确定要删除这件商品吗?</p>
<button @click="handleCancel">取消</button>
<button @click="handleDelete">确定删除</button>
</div>
</div>
</template>
<script>
export default {
name:"Shop",
methods:{
handleCancel(){
this.$emit("can") //取消
},
handleDelete(){
this.$emit("del") //删除
}
}
}
</script>
1.4Cart/index.vue中引入组件
//1.引入组件
import Shop from '@/components/Shop.vue'
//2.注册组件
components:{
Shop
}
//3.使用组件
//isShow:是否显示组件 @can:取消 @del:删除
<Shop v-show="isShow" @can="handleCancel" @del="handleDelete"></Shop>
1.5核心业务
//1.给按钮进行一个切换的动作,点击删除按钮会出现一个模态框
<button class="del" @click="toggle" >删除</button>
export default{
data(){
return{
isShow:false
}
},
methods:{
toggle(){ //模态框显示
this.isShow=true;
},
handleCancel(){
this.isShow=false //取消时模态框不显示
},
handleDelete(index){
this.products.splice(index,1) //点击删除时删除一条数据,同时模态框不显示
this.isShow=false
}
}
}
<template>
<div class="cart">
<div class="item list" v-for="(item,index) of products" :key="item.id" :index="index">
<div class="list icon f1">
<van-checkbox v-model="item.isSelected" icon-size="23px"></van-checkbox>
</div>
<div class="pic">
<img :src="item.productCover" alt />
</div>
<div class="f3">
<div>
<p class="red">{{item.productName | format(9)}}</p>
<p>{{item.productInfo | format(9)}}</p>
<p>
{{item.productPrice}}元
<span class="price">小计:{{item.productCount*item.productPrice | formats(2)}}元</span>
</p>
<van-stepper v-model="item.productCount" min="1" button-size="23px" />
</div>
</div>
<div class="f2 icon list">
<button class="del" @click="toggle" >删除</button>
</div>
</div>
<div class="footer list">
<div class="list icon f2">
<van-checkbox v-model="checked" icon-size="23px">全选</van-checkbox>
</div>
<div class="list icon f3">总计:{{sum | formats(2)}}元</div>
<div class="f2">
<button class="confirm">确定</button>
</div>
</div>
<Shop v-show="isShow" @can="handleCancel" @del="handleDelete"></Shop>
</div>
</template>
<script>
import Shop from '@/components/Shop.vue'
export default {
name: "Cart",
data() {
return {
products: [],
isShow:false
};
},
components:{
Shop
},
mounted() {
var url="http://yapi.demo.qunar.com/mock/34774/"
this.axios.get(url).then(res => {
this.products = res.data;
});
},
methods: {
toggle(){
this.isShow=true;
},
handleCancel(){
this.isShow=false
},
handleDelete(index){
this.products.splice(index,1)
this.isShow=false
}
},
computed: {
sum() {
var val;
val = 0;
this.datas.forEach(item => {
if (item.isSelected) {
val = val + item.productCount * item.productPrice;
}
});
return val;
},
checked: {
get() {
return this.products.every(item => item.isSelected);
},
set(val) {
this.products.forEach(item => (item.isSelected = val));
}
}
}
};
</script>
<style scoped>
.footer {
position: fixed;
bottom: 30px;
width: 100%;
background: #ddd;
}
.confirm {
position: relative;
right: -30px;
width: 150px;
height: 80px;
background: red;
outline: none;
border-radius: 5px;
color: #fff;
}
.red {
color: rgb(182, 51, 51);
font-size: 32px;
}
.price{
margin-left: 10px;
}
p {
margin-bottom: 20px;
}
.item {
padding: 10px 0;
}
.pic img {
width: 160px;
height: 240px;
border-radius: 10px;
margin-top: 20px;
}
.list {
display: flex;
}
.icon {
justify-content: center;
align-items: center;
}
.f1 {
flex: 1;
}
.f2 {
flex: 2;
}
.f3 {
flex: 5;
}
.del {
color: #fff;
width: 130px;
height: 80px;
background: red;
outline: none;
border-radius: 5px;
}
.cart{
font-size: 28px;
}
</style>