哈喽,我又来了,vue想必大家都用的挺多的,所以,今天就用vue和vuex来写一个案例,那么,闲话不多说,我们就开始吧!
在写之前,想必大家对购物车这一电商案例会有很多的经历吧,那今天就写个购物车案例吧!为了增加点难度,我会加入响应式布局,代码如下:
//home
<template>
<div class="home">
<div class="home_header">
<div>admin</div>
<div>logout</div>
<div @click="addCartClick">
<img src="../assets/gouwuche.png" alt/>
</div>
</div>
<div class="home_price_con">
<div class="home_price">
<div>
sort by:
<span>Default</span>
</div>
<div @click="defalut">
price
<span
v-for="(item,index) in option"
:key="index"
>{{value===0?item.title1:item.title}}</span>
</div>
</div>
</div>
<div class="home_price_con_active">
<div class="home_price_active">
<div @click="defalut">
<span>Default</span>
price
<span
v-for="(item,index) in option"
:key="index"
>{{value===0?item.title1:item.title}}</span>
</div>
<div>sort by:</div>
</div>
</div>
<div class="home_content_con">
<div class="home_content">
<div class="home_left">
<h3>PRICE</h3>
<div
v-for="(item,index) in filter"
:key="index"
:class="selectIndex===index?'home_left_item_active':'home_left_item' "
@click="onClick(index,item)"
>{{item.title}}</div>
</div>
<div class="home_right">
<el-row
:gutter="15"
>
<el-col
:xs="24"
:sm="8"
:md="8"
:lg="6"
:xl="6"
v-for="(element,index) in items"
:key="index"
>
<div class="item_conetent">
<div class="item_content_image">
<img :src="element.productImage" alt />
</div>
<div class="item_content_name_price">
<div>{{element.productName}}</div>
<div class="item_content_price">¥{{element.salePrice}}</div>
</div>
<div class="home_list_item_button">
<button @click="addCart(element)">加入购物车</button>
</div>
</div>
</el-col>
</el-row>
</div>
</div>
</div>
<div class="home_loading" v-show="isShow">
<img src="../assets/loading2.gif" alt="" />
</div>
<div v-show="show" class="home_loadings">
<img src="../assets/640.webp" alt="" />
<button @click="onClicked">点击取消</button>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "Home",
components: {},
data() {
return {
filter: [],
list: [],
items: [],
selectIndex: 0,
option: [{ title1: "↑" }, { title: "↓" }],
value: 0,
isShow:false,
temps:false,
show:false,
};
},
methods: {
onClick(index, item) {
// console.log(item);
this.selectIndex = index;
var temp = [];
if (item.title == "ALL") {
temp = this.list;
} else {
this.list.forEach(ele => {
if (ele.salePrice <= item.high && ele.salePrice > item.low) {
temp.push(ele);
}
});
}
this.items = temp;
},
defalut() {
if (this.value === 1) {
this.value = 0;
this.list.sort((a, b) => {
return a.salePrice - b.salePrice;
});
} else if (this.value === 0) {
// window.console.log(111)
this.value = 1;
this.list.sort((a, b) => {
return b.salePrice - a.salePrice;
});
}
},
onClicked(){
this.show =false
},
addCart(element) {
// window.console.log(element)
this.$store.dispatch("getCartItem",element)
},
addCartClick(){
this.$router.push("/cart")
}
},
mounted() {
axios.get("http://localhost:8080/data.json").then(res => {
window.console.log(res.data.result);
this.filter = res.data.result.filter;
this.list = res.data.result.list;
this.items = res.data.result.list;
});
window.addEventListener("scroll",()=>{
var scrolltop = document.documentElement.scrollTop;
var scrollhight = document.documentElement.scrollHeight;
var cliHight = document.documentElement.clientHeight;
var offSet =scrollhight-cliHight-scrolltop
window.console.log(offSet)
if (offSet <= 1) {
if (this.temps) {
this.isShow = true
window.setTimeout(()=>{
axios
.get("http://localhost:8080/data3.json")
.then(res => {
this.list = [...this.list, ...res.data.result.list];
this.items = [...this.list];
this.temps = null
this.isShow = false
window.console.log("***",this.list);
})
.catch(error => {
window.console.log(error);
});
},3000)
} else if(this.temps === false){
this.isShow = true
window.setTimeout(()=>{
axios
.get("http://localhost:8080/data2.json")
.then(res => {
this.list = [...this.list, ...res.data.result.list];
this.items = [...this.list];
this.temps = true
this.isShow = false
window.console.log("+++",this.list);
})
.catch(error => {
window.console.log(error);
});
},3000)
}else{
this.isShow = true
window.setTimeout(()=>{
this.isShow = false
this.show = true
},3000)
}
}
})
}
};
</script>
<style>
.home {
width: 100%;
background: gainsboro;
}
.home_header {
width: 100%;
height: 64px;
background: #fff;
display: inline-flex;
justify-content: flex-end;
align-items: center;
}
.home_header div {
margin-right: 20px;
}
.home_header img {
width: 25px;
}
.home_price_con {
display: block;
width: 80%;
margin: 15px auto;
}
.home_price {
width: 100%;
height: 64px;
background: #fff;
display: inline-flex;
justify-content: flex-end;
align-items: center;
}
.home_price div {
margin-right: 20px;
}
.home_content_con {
width: 80%;
margin: 0 auto;
}
.home_content {
width: 100%;
display: inline-flex;
background: gainsboro;
/* justify-content: space-between; */
}
.home_left {
width: 20%;
height: 1000px;
/* background: green; */
margin-top: 10px;
}
.home_left_item {
width: 100%;
height: 50px;
line-height: 50px;
}
.home_left_item_active {
width: 100%;
height: 50px;
border-left: 2px solid red;
color: red;
line-height: 50px;
}
.home_right {
width: 79%;
margin-left: 10px;
}
.item_conetent {
height: 400px;
background: #fff;
margin: 10px 0px;
/* text-align: center; */
}
.item_conetent:hover {
transform: scale(1.02);
box-shadow: 5px 5px 20px 5px rgb(255, 60, 0);
}
.item_content_image {
width: 100%;
/* height: 150px; */
display: inline-flex;
justify-content: center;
align-items: center;
margin-bottom: 20px;
}
.item_content_image img {
width: 85%;
}
.item_content_price {
margin: 10px 0px;
color: red;
}
.home_list_item_button {
width: 80%;
height:60px;
margin: 30px auto;
/* line-height: 10px; */
}
.home_list_item_button button {
width: 90%;
height: 40px;
border: 1px solid red;
color: red;
text-align: center;
}
.home_price_con_active {
display: none;
width: 80%;
margin: 15px auto;
}
.home_price_active {
width: 100%;
height: 64px;
background: #fff;
display: inline-flex;
justify-content: space-between;
align-items: center;
}
.home_loading{
width: 100%;
display: inline-flex;
justify-content: center;
/* align-items: center; */
position: fixed;
bottom: 0px;
left: 0px;
}
.home_loading img{
width: 120px;
}
.home_loadings{
width: 100%;
display: inline-flex;
justify-content: center;
position: fixed;
top: 0px;
left: 0px;
}
.home_loadings img{
width: 600%;
}
@media screen and (max-width: 768px) {
.item_conetent {
width: 100%;
height: 100px;
display: inline-flex;
justify-content: flex-start;
align-items: center;
}
.item_content_image {
width: 20%;
}
.item_content_image img {
width: 50%;
}
.item_content_name_price {
width: 60%;
}
.home_list_item_button {
width: 20%;
display: inline-flex;
justify-content: flex-end;
}
.home_left {
display: none;
}
.home_right {
width: 100%;
}
.home_price_con {
/* width: 100%; */
display: none;
}
.home_content_con {
width: 100%;
}
.home_price_con_active {
width: 100%;
display: block;
}
}
</style>
//cart页面
<template>
<div class="cart">
<div>
<div v-for="(item,index) in cartItem"
:key="index"
class="cart_item">
<div>
<input type="checkbox"
:checked="item.checked"
@click="onCheckedClick(item)"/>
</div>
<div>
<img :src="item.productImage" alt="" />
</div>
<div>{{item.productName}}</div>
<div>¥{{item.salePrice}}</div>
<!-- <van-stepper v-model="item.count" /> -->
<div class="cart_count">
<button @click="minusItem(item)">-</button>
<div class="cart_item_count">{{item.count}}</div>
<button @click="addItem(item)">+</button>
</div>
<div class="cart_item_iamge" @click="deleteItem(item)">
<img src="../assets/delete.png" alt="" />
</div>
</div>
</div>
<div class="cart_sub_bar">
全选 <input type="checkbox"
:checked="allChecked"
:disabled="cartItem.length ===0?true:false"
@click="allSelected"/>
<span>{{`总价:${totalPrice}`}}</span>
<span>{{`总量${totalCount}`}}</span>
</div>
</div>
</template>
<script>
export default {
computed:{
cartItem:function(){
return this.$store.state.cartItem
},
allChecked:function(){
return this.$store.state.allChecked
},
totalCount:function(){
return this.$store.state.totalCount
},
totalPrice:function(){
return this.$store.state.totalPrice
}
},
methods:{
onCheckedClick(item){
this.$store.dispatch("getItemChecked",{_id:item._id,checked:event.target.checked})
},
allSelected(){
this.$store.dispatch("getItemAllChecked",event.target.checked)
},
addItem(item){
this.$store.dispatch("getaddItem",item)
},
minusItem(item){
// if(item.count >1){
// item.count--
// }
this.$store.dispatch("getminusItem",item)
},
deleteItem(item){
this.$store.dispatch("getdeleteItem",item)
}
}
}
</script>
<style>
.cart_item{
width: 100%;
display: inline-flex;
justify-content: space-around;
align-items: center
}
.cart_item img{
width: 100px;
}
.cart_sub_bar{
width: 100%;
height: 64px;
position: fixed;
bottom: 0px;
left: 30px;
}
.cart_count{
display: inline-flex;
}
.cart_item_count{
width: 30px;
height: 30px;
background: #fff;
text-align: center;
line-height: 30px;
}
.cart_item_iamge img{
width: 25px;
}
</style>
// vuex页面 index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
cartItem: JSON.parse(localStorage.getItem("cartItems")) || [],
allChecked:JSON.parse(localStorage.getItem("allcheckeds")) || false,
totalCount: 0,
totalPrice: 0,
empty:[]
},
mutations: {
//获取数据,并去重
getCartItem(state, items) {
var fang = false;
state.cartItem.forEach((ele) => {
if (ele._id === items._id) {
ele.count++;
fang = true
}
});
if (!fang) {
items.count = 1;
items.checked = false
state.allChecked = false
state.cartItem.push(items)
}
localStorage.setItem("cartItems", JSON.stringify(state.cartItem))
localStorage.setItem("allcheckeds", JSON.stringify(state.allChecked))
},
// 单选
getItemChecked(state, items) {
window.console.log("+++", items)
state.cartItem.forEach((ele) => {
if (ele._id === items._id) {
ele.checked = items.checked
}
});
state.allChecked = state.cartItem.every((ele) => {
return ele.checked === true
})
state.totalCount = 0;
state.totalPrice = 0;
state.cartItem.forEach((ele) => {
if (ele.checked) {
state.totalCount += ele.count;
state.totalPrice += (ele.count * ele.salePrice)
}
})
localStorage.setItem("cartItems", JSON.stringify(state.cartItem))
localStorage.setItem("allcheckeds", JSON.stringify(state.allChecked))
},
// 全选
getItemAllChecked(state, boolean) {
state.allChecked = boolean
state.cartItem.forEach((ele) => {
ele.checked = boolean
});
state.totalCount = 0;
state.totalPrice = 0;
state.cartItem.forEach((element) => {
if (element.checked) {
state.totalCount += element.count;
state.totalPrice += (element.count * element.salePrice);
}
})
localStorage.setItem("cartItems", JSON.stringify(state.cartItem))
localStorage.setItem("allcheckeds", JSON.stringify(state.allChecked))
},
// 加
getaddItem(state, item) {
item.count++
state.totalCount = 0;
state.totalPrice = 0;
state.cartItem.forEach((element) => {
if (element.checked) {
state.totalCount += element.count;
state.totalPrice += (element.count * element.salePrice);
}
})
localStorage.setItem("cartItems", JSON.stringify(state.cartItem))
},
//减
getminusItem(state, item) {
if (item.count > 1) {
item.count--
}
state.totalCount = 0;
state.totalPrice = 0;
state.cartItem.forEach((element) => {
if (element.checked) {
state.totalCount += element.count;
state.totalPrice += (element.count * element.salePrice);
}
})
localStorage.setItem("cartItems", JSON.stringify(state.cartItem))
},
//删除
getdeleteItem(state, item) {
state.cartItem.forEach((ele,index) => {
if (ele._id===item._id) {
state.cartItem.splice(index,1)
}
})
state.totalPrice = 0;
state.totalCount = 0;
state.cartItem.forEach((element) => {
if (element.checked) {
state.totalCount += element.count;
state.totalPrice += (element.count * element.salePrice);
}
})
if(state.cartItem.length ===0){
state.allChecked = false
localStorage.setItem("allcheckeds", JSON.stringify(state.allChecked))
}
// state.cartItem.splice(index , 1)
window.console.log(state)
localStorage.setItem("cartItems", JSON.stringify(state.cartItem))
}
},
actions: {
getCartItem(context, items) {
context.commit("getCartItem", items)
},
getItemChecked(context, item) {
context.commit("getItemChecked", item)
},
getItemAllChecked(context, boolean) {
context.commit("getItemAllChecked", boolean)
},
getdeleteItem(context, item) {
context.commit("getdeleteItem", item)
},
getaddItem(context, item) {
context.commit("getaddItem", item)
},
getminusItem(context, item) {
context.commit("getminusItem", item)
}
},
modules: {
}
})