关于一个购物车的案例

发布于:2023-01-16 ⋅ 阅读:(358) ⋅ 点赞:(0)

获取数据

通过Axios请求API,调用GET的方法。

 async initCarList(){
    //  调用GET方法,请求列表数据
    // await 等待方下列请求获取完毕
     const {data:res}= await axios.get('https://www.escook.cn/api/cart')
     console.log(res)
    }

async是一种异步函数,就算这个函数没有执行完毕,也不会影响整个程序的运行。

await可以看作一个等待,当完全获取完这个API的数据,才会继续执行这个函数里面的下一步。

保存数据

当我们请求完数据以后,那当然要把数据保存到一个容器里。

用一个空的数组保存列表数据

  data(){
    return{
      //空数组保存列表数据
      list:[]
    }

调用请求数据函数

通过生命周期函数,来调用这个initCarList()的函数。这里要注意,生命周期函数是和methods同级别,不可以写到methods。

 created() {
    //组件创建完成后,调用方法
    this.initCarList()
  }

数据展示

请求的数据列表中有很多以数组形式存在的数据,通过遍历的方法将每一个数组都显示到页面。

这里要绑定Key,相当于每一条数据都有他们自己独一无二的铭牌,比如每个数组中id

 <Goods v-for="item in datalist" :key="item.id"></Goods>

 渲染标题

商品写在子组件中,要将父组件的数值传递给子组件,使用props自定义属性。

父组件将list的值给props,子组件使用props。

通过下面这个逻辑,要渲染列表其他的数据也是一样的方法。

先设置props,再赋值

props:{
    title:{
      default:'',
      type:String
    }
<Goods v-for="item in datalist" :key="item.id" :title="item.goods_name"></Goods>

如果一个一个设置props属性可能会很麻烦,这里我们会发现, 获取的这个数据它是个对象类型

 在prop可以写成这样,一整个就是一个对象属性,父组件将所有的数据传到goods里面,再去调用。那么使用的时候可以直接

<span class="goods-price">¥{{goods.goods_price}}</span>
 props:{
    goods:{
      default:{},
      type:object
    }

注意:这里一定要用到v-bind不然,显示的就是一个静态的字符串。

状态切换

子组件向父组件传值

this.$emit("function",param);function()可以被调用

比如:@function=“newState”

关于调整状态的这个思路:

通过控制台,发现每个对象的属性中都有state属性,利用这个属性完成对状态的切换。

这个打印出来的是API获取的,但实际页面上的值是props给的,所以当前页面上的每个对象都是没有ID的,先为他们绑定id属性

 id:{
      //如果使用DEFALUT默认值,没有意义,就像每个人必须要有一个身份证一样
      //requre为true为必须选择
      required:true,
      type:Number

 当身份给他们上完以后,就要监听复选框了,复选框的值发生改动,接着就是id所对应的state数值改变。

现在监听复选框状态,一旦复选框发生改变,就会触发函数stateChange.

 <input type="checkbox" class="custom-control-input" id="cb1" :checked="state" @change="stateChange"/>

 子组件向父组件传值

methods:{

  //  复选框状态发生变化就会处理函数
    stateChange(e) {
      //获取事件触发的checked值
      const newState = e.target.checked
      // 触发自定义事件
      this.$emit('state-change', { id: this.id, value: newState })
    }
  }
 <Goods v-for="item in datalist" :key="item.id" :title="item.goods_name" :price="item.goods_price"
           :picture="item.goods_img" :state="item.goods_state" :id="item.id" @state-change="getNewState"></Goods>

对datalist遍历,找到和复选框状态改变的id相同的id,赋值,就完成转换了

etNewState(e) {
      this.datalist.some(item => {
        if (item.id === e.id) {
          item.goods_state = e.value
          // 终止后续的循环
          return true
        }
      })
    }

但是在实现全选的复选框的过程中,出现了一些问题, 每一个函数体都检查了没有错误,结果竟然是调用$emit函数的时候名字写错了,大无语

接下来做全选框,逻辑思路都是大同小异。

这次会多一个computed的计算属性,只要它依赖的属性,也就是内部的属性发生变动,计算属性就会重新执行。

    fullState(){
      return  this.datalist.every(item=>item.goods_state)
    }

every遍历每个goods_state,如果每个goods_state的值为true,最终就会返回true,否则为false,这里的计算属性就是监听true 和false之间的切换,将这里返回的值父传子。完成了逆向的商品都被选中,全选框为true。

现在,要正向实现,如果全选框为false,商品都解除true

监听复选框值的变动,触发函数体,实现子传父亲

 <input type="checkbox" class="custom-control-input" id="cbFull" :checked="isFull" @change="fullChange" />
  methods:{
    fullChange(e){
      console.log(e.target.checked)
      this.$emit('full-change',e.target.checked)
    }
  }

然后在父组件中遍历修改每个goods

    <Footer :is-full="fullState" @full-change="getFullState"></Footer>
    getFullState(val) {
      console.log(val)
      this.datalist.forEach(item => (item.goods_state = val))
    }

ok,功能实现。


网站公告

今日签到

点亮在社区的每一天
去签到

热门文章