js+vue+vuex点击步进器加入购物车、计算价格、点单列表,点单总数,单个列表点单数量,总价格,vuex版(增加,删除,金额计算,存储,总数,单个列表点单数量,总价格)
vuex
写在package.json 的"dependencies"方法中 然后重新安装依赖
“vuex-persistedstate”: “^4.1.0”
import Vue from 'vue'
import Vuex from 'vuex'
import persistedState from 'vuex-persistedstate'
Vue.use(Vuex)
const state = {
orderList: [], //食堂列表数据
payList: [], //已点餐列表
num: 0, //总金额
listNum: 0, //总数量
}
const mutations = {
orderList(state, data) {
console.log(data)
state.orderList = data
},
payList(state, data) {
state.payList = data
},
num(state, data) {
state.num = data
},
listNum(state, data) {
state.listNum = data
},
}
const store = new Vuex.Store({
state,
mutations,
modules: {},
plugins: [persistedState({ storage: window.sessionStorage })],
})
export default store
vue页面
<template>
<div class="home">
<div class="list">
<div class="top flex-s">
<div class="top-left flex">
<div class="image">
<img alt="" src="../../assets/images/order/[email protected]" />
</div>
<div class="title">鲜辣面食店(中海大厦店)</div>
</div>
<div class="top-right flex">
<div class="num-title">桌号:</div>
<div class="num-text">A09</div>
</div>
</div>
<div class="search">
<van-search
v-model="value"
placeholder="请输入搜索关键词"
@clear="clear"
@search="search"
/>
</div>
<div class="list-item flex-s">
<div class="item-left">
<div
v-for="(item, index) in $store.state.orderList"
:key="index"
:class="activeKey == index ? 'tab-items' : 'tab-item'"
@click="getTab(index)"
>
<div class="item-tab flex">
<div v-if="item.url" class="image">
<img alt="" src="../../assets/images/order/[email protected]" />
</div>
<div class="title">
{
{ item.title }}
<div v-if="item.badge" class="text-red">
{
{ item.badge }}
</div>
</div>
</div>
</div>
</div>
<div class="item-right">
<div
v-for="(item, index) in $store.state.orderList[activeKey].list"
:key="index"
class="flex item-list"
>
<div class="item-left-image">
<img alt="" :src="item.url" />
</div>
<div class="item-right-list">
<div class="list-title">{
{ item.title }}</div>
<div class="list-center flex">
<div class="center-img">
<img alt="" src="../../assets/images/order/[email protected]" />
</div>
<div class="center-text">{
{ item.value }}</div>
</div>
<div class="list-footer flex-s">
<div class="list-left">
<span class="list-text">¥</span>
<span class="list-num">{
{ item.price }}</span>
<span class="list-text">/份</span>
</div>
<div class="list-right">
<van-stepper
v-model="item.num"
button-size="22"
disable-input
max="10"
min="0"
theme="round"
@minus="minus(index, item)"
@plus="plus(index, item)"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="popup">
<div></div>
<div class="num">
总价格{
{ num }}   总数量{
{ listNum }}
</div>
</div>
</div>
</template>
<script>
export default {
components: {
},
data() {
return {
value: '',
activeKey: 0,
data: [
{
title: '人气',
badge: 0,
url: require('../../assets/images/order/dc_dd.png'),
list: [
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 1,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 2,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 3,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 4,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 5,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 6,
},
],
},
{
title: '面食系列',
badge: 0,
list: [
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 7,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 8,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 9,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 10,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 11,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 12,
},
],
},
{
title: '套餐系列',
badge: 0,
list: [
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 13,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 14,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 15,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 16,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 17,
},
{
url: require('@/assets/images/order/[email protected]'),
title: '红烧肉酸辣米线辣辣米',
value: '5.4折',
num: 0,
price: 42.0,
id: 18,
},
],
},
],
num: this.$store.state.num || 0, //总金额
listNum: this.$store.state.listNum || 0, //总数量
}
},
computed: {
Total() {
//在这里定义一个total为0,来存放他的总价
let total = 0
//循环data
for (let i = 0; i < this.$store.state.orderList.length; i++) {
//循环data下标的list
for (let v = 0; v < this.$store.state.orderList[i].list.length; v++) {
//相当于 total = list每一个数量 * list每一个的价钱
total +=
this.$store.state.orderList[i].list[v].num *
this.$store.state.orderList[i].list[v].price
}
}
return total
},
listTotal() {
let num = 0
//循环data
for (let i = 0; i < this.$store.state.orderList.length; i++) {
//相当于 num = datax下标的badge
num += this.$store.state.orderList[i].badge
}
return num
},
},
watch: {
Total(val) {
this.num = val
this.$store.commit('num', val)
},
listTotal(val) {
this.listNum = val
this.$store.commit('listNum', val)
},
},
mounted() {
this.$store.commit('orderList', this.data)
},
methods: {
// 搜索
search(val) {
console.log(val)
},
// 清空
clear() {
this.value = ''
},
// 点击切换
getTab(index) {
this.activeKey = index
},
// 减
minus(index) {
this.$store.state.orderList[this.activeKey].badge--
this.$store.state.orderList[this.activeKey].list[index].num--
this.$store.state.payList.filter((i, v) => {
if (i.num == 0) {
this.$store.state.payList.splice(v, 1)
}
})
},
//查询函数
findPlus(key, val, arr) {
let open = false
arr.forEach((item) => {
if (item[key] == val) {
open = true
}
})
return open
},
// 加
plus(index, item) {
this.$store.state.orderList[this.activeKey].badge++
this.$store.state.orderList[this.activeKey].list[index].num++
let open = this.findPlus('id', item.id, this.$store.state.payList)
if (!open) {
this.$store.state.payList.push(item)
}
},
},
}
</script>
<style lang="scss" scoped>
.home {
height: 100vh;
background: #fff;
.list {
height: calc(100vh - 120px);
overflow: hidden;
.top {
padding: 38px 24px 0 24px;
margin-bottom: 20px;
.top-left {
display: flex;
align-items: center;
.image {
width: 28px;
height: 32px;
margin: 5px 12px 0 0;
img {
width: 100%;
height: 100%;
}
}
.title {
margin: auto 0;
width: 60vw;
min-height: 44px;
font-weight: 500;
font-size: 32px;
color: #333333;
}
}
.top-right {
.num-title {
line-height: 74px;
font-weight: 500;
font-size: 26px;
color: #666666;
}
.num-text {
font-weight: 500;
font-size: 52px;
color: #fb6c1e;
}
}
}
.search {
margin-bottom: 20px;
::v-deep {
.van-search {
margin: 0 24px;
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
box-sizing: border-box;
height: 72px;
background: #ffffff;
border: 2px solid #dddddd;
border-radius: 46px;
}
.van-search__content {
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
padding-left: 12px;
background-color: #ffffff;
border-radius: 2px;
}
}
}
.list-item {
height: 74vh;
overflow: hidden;
.item-left {
width: 164px;
height: 74vh;
overflow-y: scroll;
.tab-item {
display: flex;
align-items: center;
min-width: 82px;
background: #f8f8f8;
.item-tab {
margin: 0 auto;
.image {
width: 30px;
height: 30px;
margin: auto 6px auto 0;
img {
width: 100%;
height: 100%;
}
}
.title {
font-size: 24px;
color: #333333;
position: relative;
height: 100px;
// line-height: 100px;
display: flex;
align-items: center;
.text-red {
position: absolute;
top: 14px;
right: -20px;
box-sizing: border-box;
min-width: 32px;
padding: 0 6px;
color: #fff;
font-weight: 500;
font-size: 24px;
font-family: -apple-system-font, Helvetica Neue, Arial,
sans-serif;
line-height: 24px;
text-align: center;
background-color: #ee0a24;
border: 1px solid #fff;
border-radius: 32px;
}
}
}
}
.tab-items {
height: 60px;
line-height: 60px;
display: flex;
align-items: center;
min-width: 82px;
background: #fff;
border-left: 8px solid red;
margin: 20px 0;
.item-tab {
height: 34px;
margin: 0 auto;
.image {
width: 30px;
height: 30px;
margin: auto 6px auto 0;
img {
width: 100%;
height: 100%;
}
}
.title {
font-size: 24px;
color: #333333;
position: relative;
// height: 100px;
// line-height: 100px;
display: flex;
align-items: center;
.text-red {
position: absolute;
top: -16px;
right: -20px;
z-index: 33;
box-sizing: border-box;
min-width: 32px;
padding: 0 3px;
color: #fff;
font-weight: 500;
font-size: 24px;
font-family: -apple-system-font, Helvetica Neue, Arial,
sans-serif;
height: 32px;
line-height: 32px;
text-align: center;
background-color: #ee0a24;
border: 1px solid #fff;
border-radius: 32px;
}
}
}
}
}
.item-right {
width: 588px;
height: 74vh;
overflow-y: scroll;
background: #fff;
.item-list {
margin: 20px;
height: 168px;
.item-left-image {
width: 168px;
height: 168px;
margin-right: 20px;
img {
width: 100%;
height: 100%;
}
}
.item-right-list {
width: 356px;
height: 168px;
position: relative;
.list-title {
font-size: 26px;
color: #333333;
margin-bottom: 8px;
}
.list-center {
width: 104px;
background: #ffeee5;
border-radius: 4px;
padding: 8px;
.center-img {
width: 16px;
height: 16px;
margin: auto 10px auto 0;
img {
width: 100%;
height: 100%;
}
}
.center-text {
font-size: 24px;
color: #fb6c1e;
}
}
.list-footer {
position: absolute;
bottom: 0;
.list-left {
.list-text {
color: #999999;
font-size: 16px;
}
.list-num {
color: #333333;
font-size: 28px;
font-weight: 500;
}
}
.list-right {
::v-deep {
.van-stepper--round .van-stepper__minus {
color: #000;
background-color: #fff;
border: 1px solid #fb6c1e;
}
.van-stepper--round .van-stepper__plus {
color: #fff;
background-color: #fb6c1e;
}
.van-stepper {
font-size: 0;
-webkit-user-select: none;
user-select: none;
position: absolute;
bottom: 0;
right: -30vw;
}
}
}
}
}
}
}
}
}
.popup {
position: fixed;
bottom: 140px;
left: 20px;
right: 20px;
height: 104px;
background: #333333;
box-shadow: 0 4px 20px 0 #00000033;
border-radius: 52px;
.num {
color: #fff;
}
}
}
.flex {
display: flex;
}
.flex-s {
display: flex;
justify-content: space-between;
}
</style>