1.vue小米购物车用到了 Vuex + localstorage,使用了vue2,创建项目用vue create xiaomi (名字)
1.在Home.vue里面写
<template>
<div class="home">
<header>
<span >首页</span>
<router-link to="/about" class="span">购物车({{total}})</router-link>
</header>
<div class="list" v-for="item in list" :key="item.id">
<div class="left">
<img data-v-3ebe9018="" :src="item.img">
</div>
<div class="right">
<h3 class="title">{{item.name}}</h3>
<p class="slogan">{{item.slogan}}</p>
<p class="money">{{item.price}}</p>
<button class="button" @click="setShippingjiajian(item,'PLUS')">加入购物车</button>
</div>
</div>
</div>
</template>
<script>
import {mapState,mapGetters} from "vuex"
export default {
name: 'Home',
computed:{
...mapState(["list"]),
...mapGetters(["total"])
},
created(){
this.$store.dispatch("setList")
},
methods:{
setShippingjiajian(item,_type){
console.log(item)
this.$store.dispatch("setShippingjiajian",{
id:item.id,
name:item.name,
price:item.price,
img:item.img,
slogan:item.slogan,
// 这个_type是定义加减的
_type
})
}
}
}
</script>
<style scoped>
.home{
width: 100%;
}
header{
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 0.44rem;
background: #ff6704;
color: #fff;
font-size: 0.18rem;
display: fixed;
}
.span{
position: absolute;
right: 0.15rem;
top: 0.15rem;
font-size: 0.14rem;
}
.list{
border-bottom: 1px solid #ddd;
background: #fff;
display: flex;
flex-direction: row;
}
.left img{
width: 0.94rem;
height: 0.94rem;
}
.right{
flex: 1;
overflow: hidden;
height: 1.2rem;
padding: 0.1rem 0.1rem 0.1rem 0.13rem;
box-sizing: border-box;
}
.title{
color: #333;
font-size: 0.16rem;
}
.slogan{
margin-top: 0.05rem;
color: #999;
font-size: 0.12rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.money{
margin-top: 0.15rem;
color: #ff6704;
font-size: 0.14rem;
}
.button{
float: right;
width: 0.8rem;
height: 0.2rem;
font-size: 0.12rem;
border: 1px solid #ff6704;
color: #ff6704;
border-radius: 0.02rem;
background-color: #fff;
}
</style>
2.在About.vue里面写
<template>
<div class="about">
<header>
<span>购物车</span>
<router-link to="/" class="span">返回</router-link>
</header>
<div class="list" v-for="item in shipping" :key="item.id">
<div class="left">
<img :src="item.img" alt="">
</div>
<div class="right">
<h3 class="title">{{item.name}}</h3>
<p class="slogan">{{item.slogan}}</p>
<p class="money">{{item.price}}</p>
<div class="button">
<button class="an" @click="handle(item.id,item.price,'PLUS')">+</button>
<p class="cen">{{item.mount}}</p>
<button class="an" @click="handle(item.id,item.price,'REDUCE')">-</button>
</div>
</div>
</div>
<div class="footer">总价{{zong}}</div>
</div>
</template>
<script>
import { mapState , mapActions} from "vuex"
export default({
computed:{
...mapState(["shipping"]),
shipping(){
return this.$store.state.shipping
},
zong(){
let zongji=0
this.shipping.map(v=>{
zongji +=(v.mount*v.price)
})
localStorage.setItem('totalPrice', JSON.stringify(zongji))
return zongji
}
},
methods:{
...mapActions(['getShipping']),
handle(id,price,_type){
this.$store.dispatch('setshipping',{
id,
price,
_type
})
}
},
mounted(){
this.getShipping()
}
})
</script>
<style scoped>
header{
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 0.44rem;
background: #ff6704;
color: #fff;
font-size: 0.18rem;
display: fixed;
}
.span{
position: absolute;
left: 0.15rem;
top: 0.15rem;
font-size: 0.14rem;
}
.list{
border-bottom: 1px solid #ddd;
background: #fff;
display: flex;
flex-direction: row;
}
.left img{
width: 0.94rem;
height: 0.94rem;
}
.right{
flex: 1;
overflow: hidden;
height: 1.2rem;
padding: 0.1rem 0.1rem 0.1rem 0.13rem;
box-sizing: border-box;
}
.title{
color: #333;
font-size: 0.16rem;
}
.slogan{
margin-top: 0.05rem;
color: #999;
font-size: 0.12rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.money{
margin-top: 0.15rem;
color: #ff6704;
font-size: 0.14rem;
}
.button{
float: right;
width: 0.8rem;
height: 0.2rem;
font-size: 0.12rem;
}
.an{
width: 0.2rem;
height: 0.2rem;
border: 0.01rem solid #999;
border-radius: 50%;
font-size: 0.14rem;
line-height: 0.08rem;
background-color: #fff;
float: left;
}
.cen{
float: left;
width: 0.2rem;
height: 0.2rem;
border: 1px solid #333;
line-height: 0.2rem;
text-align: center;
}
.footer{
position: absolute;
bottom: 0;
width: 100%;
background-color: #ff6704;
color: white;
height: 0.8rem;
}
</style>
3.store目录下的index.js文件里面写
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
list:[],
shipping:[],//购物车页
},
mutations: {
// 渲染数
SET_LIST(state,data) {
state.list=data
},
// 加入购物车
SET_SHipping(state,data){
const {id,img,name,price,slogan,_type}=data;
const index = state.shipping.findIndex(item=>item.id==id);
if(index==-1){
state.shipping.push({
id,img,name,price,slogan,_type,
mount:1,
tPrice:price
})
}else{
let item=state.shipping[index];
if(_type=='PLUS'){
item.mount+=1;
item.tPrice+=price;
}else if(_type=='REDUCE'){
if(item.mount>1){
item.mount-=1;
item.tPrice-=price;
}else{
alert("数量不能再减少了")
}
}
}
localStorage.setItem('shipping',JSON.stringify(state.shipping));
},
// 让购物车的数据刷新不掉
SET_SHP(state,data) {
state.shipping=data
},
},
actions: {
setList({commit}){
const list=JSON.parse(localStorage.getItem("list"))||[];
commit("SET_LIST",list)
},
setshipping({commit},data){
commit("SET_SHipping",data)
},
getShipping({commit}){
const shipping=JSON.parse(localStorage.getItem("shipping"))||[];
commit("SET_SHP",shipping)
},
setShippingjiajian({commit},data){
console.log(data)
commit("SET_SHipping",data)
},
},
modules: {
},
// 数量
getters:{
total(state){
return state.shipping.reduce((pre,item)=>{
return pre+item.mount
},0)
}
}
})
5.list购物车里面的数据
list: [
{
"id": 1,
"name": "小米9 SE",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/5652bd7a2f8bd6daaa1dd4b5c3c2e9b3.jpg",
"price": 1999,
"slogan": "新品看点:弹出式肩键|真实机械感反馈",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 2,
"name": "Redmi K40 游戏增强版",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/61454401f855cf5ed64747a6ac04bae5.jpg",
"price": 2999,
"slogan": "新品看点:年度旗舰骁龙870,新一代 E4 AMOLED旗舰直屏",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 3,
"name": "小米9 SE",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/5652bd7a2f8bd6daaa1dd4b5c3c2e9b3.jpg",
"price": 3999,
"slogan": "新品看点:弹出式肩键|真实机械感反馈",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 4,
"name": "Redmi K40 游戏增强版",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/61454401f855cf5ed64747a6ac04bae5.jpg",
"price": 4999,
"slogan": "新品看点:年度旗舰骁龙870,新一代 E4 AMOLED旗舰直屏",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 5,
"name": "小米9 SE",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/5652bd7a2f8bd6daaa1dd4b5c3c2e9b3.jpg",
"price": 999,
"slogan": "新品看点:弹出式肩键|真实机械感反馈",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 6,
"name": "Redmi K40 游戏增强版",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/61454401f855cf5ed64747a6ac04bae5.jpg",
"price": 2999,
"slogan": "新品看点:年度旗舰骁龙870,新一代 E4 AMOLED旗舰直屏",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 7,
"name": "小米9 SE",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/5652bd7a2f8bd6daaa1dd4b5c3c2e9b3.jpg",
"price": 1999,
"slogan": "新品看点:弹出式肩键|真实机械感反馈",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 8,
"name": "Redmi K40 游戏增强版",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/61454401f855cf5ed64747a6ac04bae5.jpg",
"price": 699,
"slogan": "新品看点:年度旗舰骁龙870,新一代 E4 AMOLED旗舰直屏",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 9,
"name": "小米9 SE",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/5652bd7a2f8bd6daaa1dd4b5c3c2e9b3.jpg",
"price": 799,
"slogan": "新品看点:弹出式肩键|真实机械感反馈",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 10,
"name": "Redmi K40 游戏增强版",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/61454401f855cf5ed64747a6ac04bae5.jpg",
"price": 1099,
"slogan": "新品看点:年度旗舰骁龙870,新一代 E4 AMOLED旗舰直屏",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 11,
"name": "小米9 SE",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/5652bd7a2f8bd6daaa1dd4b5c3c2e9b3.jpg",
"price": 1199,
"slogan": "新品看点:弹出式肩键|真实机械感反馈",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 12,
"name": "Redmi K40 游戏增强版",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/61454401f855cf5ed64747a6ac04bae5.jpg",
"price": 1299,
"slogan": "新品看点:年度旗舰骁龙870,新一代 E4 AMOLED旗舰直屏",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 13,
"name": "小米9 SE",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/5652bd7a2f8bd6daaa1dd4b5c3c2e9b3.jpg",
"price": 1399,
"slogan": "新品看点:弹出式肩键|真实机械感反馈",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 14,
"name": "Redmi K40 游戏增强版",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/61454401f855cf5ed64747a6ac04bae5.jpg",
"price": 1499,
"slogan": "新品看点:年度旗舰骁龙870,新一代 E4 AMOLED旗舰直屏",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 15,
"name": "小米9 SE",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/5652bd7a2f8bd6daaa1dd4b5c3c2e9b3.jpg",
"price": 15999,
"slogan": "新品看点:弹出式肩键|真实机械感反馈",
"totalMount": 0,
"totolPrice": 0,
"num":1
},
{
"id": 16,
"name": "Redmi K40 游戏增强版",
"img": "https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/61454401f855cf5ed64747a6ac04bae5.jpg",
"price": 17999,
"slogan": "新品看点:年度旗舰骁龙870,新一代 E4 AMOLED旗舰直屏",
"totalMount": 0,
"totolPrice": 0,
"num":1
}
]