vue2 数组18 some erver filter reduce axios 购物车案例

some:

 return  true是固定写法,终止some循环

 

erver:

 

filter:

 

 

 

优化写法:
 arr.filter(item=>item.state).reduce((累加的结果,当前循环项)=>{},初始值)

拿上面的arr优化写法示例:
arr.filter(item=>item.state).reduce((amt,item)=>{
  return amt += item.price*item.count
},0)

  reduce:

二次简写:
const count = arr.filter(item=>item.state).reduce((amt,item)=>amt += item.price*item.count,0)

  axios:

导入:
npm i axios -S
使用:
methods:{
    // 封装请求列表数据
    async initCar(){
      // 调用axios的get方法数据
      const {data:res}=await axios.get('接口')
      console.log(res);
    }
  },
  created(){
    this.initCar()
  }
 
案例:
  
<Goods v-for="item in list" :key="item.id" :title="item.goods_name" :img="item.goods_img" :Price="item.goods_price"  :state="item.goods_state">
</Goods>
 
 
import Goods from './components/Goods/Goods.vue'
import axios from 'axios'
 
 
components: {
    Header, Goods
  },
  data() {
    return {
      // 储存购物车的列表数据,默认空数组
      list: [],
    }
  },
methods: {
    // 封装请求列表数据
    async initCar() {
      // 调用axios的get方法数据
      const { data: res } = await axios.get('https://www.escook.cn/api/cart')
      // 请求到的数据需要渲染,则必须要转存到data上
      console.log(res);
      if (res.status === 200) {
        this.list = res.list
      }
    }
  },
  created() {
    this.initCar()
    console.log(this.list);
  }
 
APP页面:
<template>
  <div class="app-container">
    <!-- 头部组件 -->
    <Header title="购物车"></Header>
    <Goods v-for="item in list" :key="item.id" :id="item.id" :title="item.goods_name" :img="item.goods_img"
      :Price="item.goods_price" :state="item.goods_state" @state-change="getnewState" :count="item.goods_count">
    </Goods>
    <Footer :isfull="fallState" :amm="amo" :all="total" @full-change="getFullState" ></Footer>
  </div>
</template>

<script>
import Header from './components/Header/Header.vue'
import Goods from './components/Goods/Goods.vue'
import Footer from './components/Footer/Footer.vue'
import bus from './components/eventerBus.js'
import axios from 'axios'
export default {
  components: {
    Header, Goods, Footer
  },
  data() {
    return {
      // 储存购物车的列表数据,默认空数组
      list: [],
    }
  },
  computed: {
    // 通过计算属性动态计算状态是false还是true
    fallState() {
      return this.list.every(item => item.goods_state === true)
    },
    amo() {
      return this.list.filter(item => item.goods_state).reduce((total, item) => (total += item.goods_price * item.goods_count), 0)
    },
    total() {
      return this.list.filter(item=>item.goods_state).reduce((t,item)=>(t+=item.goods_count),0)
    }
  },
  methods: {
    // 封装请求列表数据
    async initCar() {
      // 调用axios的get方法数据
      const { data: res } = await axios.get('https://www.escook.cn/api/cart')
      // 请求到的数据需要渲染,则必须要转存到data上
      console.log(res);
      if (res.status === 200) {
        this.list = res.list
      }
    },
    getnewState(e) {
      this.list.some(item => {
        if (item.id === e.id) {
          item.goods_state = e.value
          // return true
        }
      })
    },
    // 接受子组件传递过来的状态
    getFullState(val) {
      this.list.forEach(item => (item.goods_state = val))
    }
  },
  created() {
    this.initCar()
    bus.$on('plus', val => {
      this.list.some(item => {
        if (item.id === val.id) {
          item.goods_count = val.value
          return
        }
      })
    }),
      bus.$on('reduce', val => {
        this.list.some(item => {
          if (item.id === val.id) {
            item.goods_count = val.value
          }
        })
      })
  }
}
</script>

<style lang="less" scoped>
.app-container {
  padding-top: 45px;
  padding-bottom: 50px;
}
</style>
 
 Header组件:
<template>
  <div class="header-container">{{title}}</div>
</template>

<script>
export default {
  props:{
    title:{
      default:'',
      type:String,
    }
  }
}
</script>

<style lang="less" scoped>
.header-container {
  font-size: 12px;
  height: 45px;
  width: 100%;
  background-color: #1d7bff;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
  position: fixed;
  top: 0;
  z-index: 999;
}
</style>
Goods 组件:
<template>
  <div class="goods-container">
    <!-- 左侧图片 -->
    <div class="thumb">
      <div class="custom-control custom-checkbox">
        <!-- 复选框 -->
        <input type="checkbox" class="custom-control-input" :id="'cb'  +  id" :checked="state" @change="statechange" />
        <label class="custom-control-label" :for="'cb'  +  id">
          <!-- 商品的缩略图 -->
          <img :src="img" alt="" />
        </label>
      </div>
    </div>
    <!-- 右侧信息区域 -->
    <div class="goods-info">
      <!-- 商品标题 -->
      <h6 class="goods-title">{{ title }}</h6>
      <div class="goods-info-bottom">
        <!-- 商品价格 -->
        <span class="goods-price">¥{{ Price }}</span>
        <!-- 商品的数量 -->
        <Counter :num="count" :id="id"></Counter>
      </div>
    </div>
  </div>
</template>

<script>
import Counter from '../Counter/Counter.vue'
export default {
  props: {
    //在这里封装一个id是因为将来商品勾选状态变化后,需要子传父的形式,通知父组件,通知父组件,根据id修改对应商品的勾选状态
    id: {
      required: true,
      type: true,
    },
    title: {
      default: '',
      type: String,
    },
    img: {
      default: '',
      type: String,
    },
    Price: {
      default: '',
      type: Number,
    },
    // 勾选状态
    state: {
      default: true,
      type: Boolean,
    },
    count:{
      default:1,
      type:Number,
    }
  },
  components:{
    Counter
  },
  methods: {
    statechange(e) {
      const newState = e.target.checked
      this.$emit('state-change', { id: this.id, value: newState })
    }
  },
}
</script>

<style lang="less" scoped>
.goods-container {
  +.goods-container {
    border-top: 1px solid #efefef;
  }

  padding: 10px;
  display: flex;

  .thumb {
    display: flex;
    align-items: center;

    img {
      width: 100px;
      height: 100px;
      margin: 0 10px;
    }
  }

  .goods-info {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    flex: 1;

    .goods-title {
      font-weight: bold;
      font-size: 12px;
    }

    .goods-info-bottom {
      display: flex;
      justify-content: space-between;

      .goods-price {
        font-weight: bold;
        color: red;
        font-size: 13px;
      }
    }
  }
}
</style>
Footer组件:
<template>
  <div class="footer-container">
    <!-- 左侧的全选 -->
    <div class="custom-control custom-checkbox">
      <input type="checkbox" class="custom-control-input" id="cbFull" :checked="isfull" @change="fullChange" />
      <label class="custom-control-label" for="cbFull">全选</label>
    </div>

    <!-- 中间的合计 -->
    <div>
      <span>合计:</span>
      <span class="total-price">¥{{ amm.toFixed(2) }}</span>
    </div>

    <!-- 结算按钮 -->
    <button type="button" class="btn btn-primary btn-settle">结算({{ all }})</button>
  </div>
</template>

<script>
export default {
  props:{
    // 全选的状态
    isfull:{
      type:Boolean,
      default:true,
    },
    amm:{
      type:Number,
      default:0,
    },
    all:{
      type:Number,
      default:0,
    }
  },
  methods:{
    fullChange(e){
      this.$emit('full-change',e.target.checked)
    },
  }

}
</script>

<style lang="less" scoped>
.footer-container {
  font-size: 12px;
  height: 50px;
  width: 100%;
  border-top: 1px solid #efefef;
  position: fixed;
  bottom: 0;
  background-color: #fff;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 10px;
}

.custom-checkbox {
  display: flex;
  align-items: center;
}

#cbFull {
  margin-right: 5px;
}

.btn-settle {
  height: 80%;
  min-width: 110px;
  border-radius: 25px;
  font-size: 12px;
}

.total-price {
  font-weight: bold;
  font-size: 14px;
  color: red;
}
</style>
 
Counter组件:
<template>
  <div class="number-container d-flex justify-content-center align-items-center">
    <!-- 减 1 的按钮 -->
    <button type="button" class="btn btn-light btn-sm" @click="sub">-</button>
    <!-- 购买的数量 -->
    <span class="number-box">{{num}}</span>
    <!-- 加 1 的按钮 -->
    <button type="button" class="btn btn-light btn-sm" @click="add">+</button>
  </div>
</template>

<script>
import bus from '../eventerBus.js'
export default {
  props:{
    id:{
      required:true,
      type:Number,
    },
    num:{
      default:1,
      type:Number,
    }
  },
  methods:{
    add(){
      const obj ={
        id:this.id,
        value:this.num+1
      }
      bus.$emit('plus',obj)
    },
    sub(){
      if(this.num - 1 === 0 )return
      const obj = {
        id:this.id,
        value:this.num-1
      }
      bus.$emit('reduce',obj)
    }
  }
}
</script>

<style lang="less" scoped>
.number-box {
  min-width: 30px;
  text-align: center;
  margin: 0 5px;
  font-size: 12px;
}

.btn-sm {
  width: 30px;
}
</style>
eventerBus.js
import Vue from "vue"
export default new Vue()

  

posted @ 2022-12-01 17:51  文采呱呱  阅读(58)  评论(0编辑  收藏  举报