老师,我跟着老师进行结构复用,为什么我的效果达不到讲师中的效果呢

老师,我跟着老师进行结构复用,为什么我的效果达不到讲师中的效果呢

<template>
  <div class="cart">
    <div class="product" v-for="item in productItemList" :key="item._id">
      <img :src="item.imgUrl" class="product__img" />
      <div class="product__list">
        <span class="product__list__name">{{ item.name }}</span>
        <span class="product__list__sales">月售{{ item.sales }}件</span>
        <div class="product__list__price">
          <span class="cur-price">
            <i class="cur-price__icon">¥</i>
            {{ item.price }}
          </span>
          <span class="price">¥{{ item.oldPrice }}</span>
        </div>
      </div>
      <div class="product__number">
        <span
          class="product__number__minus"
          @click="
            () => {
              changeCartItemInfo(shopId, item._id, item, -1);
            }
          "
          >-</span
        >
        {{ cartList?.[shopId]?.[item._id]?.count || 0 }}
        <span
          class="product__number__plus"
          @click="
            () => {
              changeCartItemInfo(shopId, item._id, item, 1);
            }
          "
          >+</span
        >
      </div>
    </div>
    <div class="cart__sort">
      <span class="iconfont cart__sort__icon">&#xe607;</span>
      <span class="cart__sort__number">{{ total }}</span>
    </div>
    <div class="cart__total-price">
      <span class="cart__total-price__total">总价:</span>
      <span class="cart__total-price__price">¥ {{ price }}</span>
    </div>
    <div class="cart__pay">去结算</div>
  </div>
</template>

<script>
import { useStore } from "vuex";
import { useRoute } from "vue-router";
import { computed } from "vue";

//获取购物车信息逻辑
const useCartEffect = () => {
  const store = useStore();
  const route = useRoute();
  const shopId = route.params.id;
  const cartList = store.state.cartList;

  //计算总单数
  const total = computed(() => {
    const productList = cartList[shopId];
    let count = 0;
    if (productList) {
      for (let i in productList) {
        const product = productList[i];
        count += product.count;
      }
    }
    return count;
  });

  //计算总价格
  const price = computed(() => {
    const productList = cartList[shopId];
    let count = 0;
    if (productList) {
      for (let i in productList) {
        const product = productList[i];
        count += product.price * product.count;
      }
    }
    return count.toFixed(2);
  });

  const productItemList = computed(() => {
    const productList = cartList[shopId] || [];
    // console.log(productList);
    return {
      productList,
    };
  });

  console.log(total);
  return {
    total,
    price,
    productItemList,
  };
};

export default {
  name: "Cart",
  setup() {
    const { total, price, productItemList } = useCartEffect();
    return { price, total, productItemList };
  },
};
</script>

<style lang="scss" scoped>
@import "../../style/viriables.scss";
@import "../../style/mixins.scss";

.cart {
  display: flex;
  align-items: center;
  box-sizing: border-box;
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 0.5rem;
  background: $color-FFF;
  box-shadow: 0 -1px 1px 0 $color-F1F1F1;
  &__sort {
    position: relative;
    margin: 0 0.32rem 0 0.24rem;
    &__icon {
      font-size: 0.26rem;
      color: $color-0091FF;
    }
    &__number {
      position: absolute;
      display: flex;
      justify-content: center;
      align-items: center;
      left: 0.25rem;
      top: -0.07rem;
      padding: 0 0.05rem;
      min-width: 0.2rem;
      height: 0.2rem;
      border-radius: 0.1rem;
      font-size: 0.16rem;
      color: $color-FFF;
      transform: scale(0.5);
      transform-origin: left center;
      background-color: $color-E93B3B;
    }
  }
  &__total-price {
    width: 1.93rem;
    &__total {
      font-size: 0.12rem;
      color: $color-333;
      margin-right: 0.1rem;
    }
    &__price {
      font-size: 0.18rem;
      color: $color-E93B3B;
    }
  }
  &__pay {
    flex: 1;
    text-align: center;
    line-height: 0.49rem;
    width: 0.98rem;
    color: $color-FFF;
    font-size: 0.14rem;
    background-color: $color-4FB0F9;
  }
  .product {
  position: absolute;
  bottom: 0.5rem;
  display: flex;
  width: 100%;
  height: 0.8rem;
  border-bottom: 0.01rem solid #f1f1f1;
  margin-bottom: 0.12rem;
  &__number {
    position: absolute;
    display: flex;
    align-items: center;
    right: 0;
    bottom: 0.12rem;
    &__minus {
      @include addAndMinus;
      box-sizing: border-box;
      border: 0.01rem solid $color-666;
      color: $color-666;
      margin-right: 0.1rem;
    }
    &__plus {
      @include addAndMinus;
      background-color: $color-0091FF;
      color: $color-FFF;
      margin-left: 0.1rem;
    }
  }
  &__img {
    height: 0.68rem;
  }
  &__list {
    display: flex;
    margin-left: 0.16rem;
    flex-direction: column;
    &__name {
      @include ellipsis;
      width: 1.5rem;
      font-size: 0.14rem;
      color: $color-333;
      line-height: 0.2rem;
      font-weight: 600;
      margin-bottom: 0.06rem;
    }
    &__sales {
      font-size: 12px;
      color: $color-333;
      line-height: 16px;
      margin-bottom: 0.06rem;
    }
    &__price {
      display: flex;
      align-items: center;
      .cur-price {
        color: $color-E93B3B;
        &__icon {
          font-style: normal;
          display: inline-block;
          font-size: 0.12rem;
          transform: scale(0.85);
          margin-right: -0.03rem;
        }
      }
      .price {
        text-decoration: line-through;
        display: inline-block;
        margin-left: -0.07rem;
        font-size: 0.2rem;
        color: $color-999;
        line-height: 0.2rem;
        transform: scale(0.5);
      }
    }
  }
}
}
</style>


正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

2回答
好帮手慕星星 2021-12-15 18:11:13

同学你好,解答如下:

1、课程中返回的是计算属性,而同学代码中返回的是{},所以需要调用。可以修改为:

https://img1.sycdn.imooc.com//climg/61b9be5409564b3a05670112.jpg

https://img1.sycdn.imooc.com//climg/61b9be5f0917a4c806120241.jpg

2、useCommonCartEffect方法在下一小节中有讲解,提取出来放在js文件中,然后在页面中引入使用,可以继续往下面看。

3、这边测试输出的是一次

https://img1.sycdn.imooc.com//climg/61b9bde60906bf3010250128.jpg

4、这边是一份结构,不是两份

https://img1.sycdn.imooc.com//climg/61b9bead09ba76ae13870722.jpg

建议重启项目再测试下。

好帮手慕星星 2021-12-15 17:18:45

同学你好,代码中缺少数据提交,代码修改如下:

<script>
import { useStore } from "vuex";
import { useRoute } from "vue-router";
import { computed } from "vue";
// 缺少引入
import { useCommonCartEffect } from './commonCartEffect'

//获取购物车信息逻辑
// const useCartEffect = () => {
const useCartEffect = (shopId) => {
  const store = useStore();
  // const route = useRoute();
  // const shopId = route.params.id;
  const cartList = store.state.cartList;
  //计算总单数
  const total = computed(() => {
    const productList = cartList[shopId];
    let count = 0;
    if (productList) {
      for (let i in productList) {
        const product = productList[i];
        count += product.count;
      }
    }
    return count;
  });

  //计算总价格
  const price = computed(() => {
    const productList = cartList[shopId];
    let count = 0;
    if (productList) {
      for (let i in productList) {
        const product = productList[i];
        count += product.price * product.count;
      }
    }
    return count.toFixed(2);
  });


  const productItemList = computed(() => {

    const productList = cartList[shopId] || [];
    // return {
    //   productList,
    // };
    return productList;
  });

  return {
    total,
    price,
    productItemList,
  };
};

export default {
  name: "Cart",
  setup() {
    const route = useRoute();
    const shopId = route.params.id;
    // 解构
    const { changeCartItemInfo } = useCommonCartEffect()
    // const { total, price, productItemList } = useCartEffect();
    const { total, price, productItemList } = useCartEffect(shopId);
    // return { price, total, productItemList };
    return { price, total, productItemList, changeCartItemInfo, shopId };
  },

};

</script>

https://img1.sycdn.imooc.com//climg/61b9b01f098e86ad07760314.jpg

修改后,实现效果是这样的

https://img1.sycdn.imooc.com//climg/61b9af980993dd9405240156.jpg

所有商品是叠加状态。

这是因为product是绝对定位,top位置设置的是一样的,建议修改布局和课程中一样,在product下面遍历template,并在每一条商品外面再包裹一个盒子。

https://img1.sycdn.imooc.com//climg/61b9b266096fefea07970530.jpg

https://img1.sycdn.imooc.com//climg/61b9b2f0095bb36205420343.jpg

https://img1.sycdn.imooc.com//climg/61b9b2db0982226404490295.jpg

可以从源代码中下载进行着对比修改:

https://img1.sycdn.imooc.com//climg/61b9b15a096ebd1409370241.jpg

祝学习愉快!

  • 提问者 陆小小 #1

    老师,我自己修改了一遍,我在它的外层套了个div就不用跟讲师的结构一致了,

    但讲师中没有引入这个东西啊?https://img1.sycdn.imooc.com//climg/61b9b43109550cff00000000.jpg为什么他可以导出直接用数据,但是我导出后还需要打点调用productList才可以遍历数据

    下面的是我修改后的代码:

    <template>
      <div class="cart-menu">
        <div
          class="product"
          v-for="item in productItemList.productList"
          :key="item._id"
        >
          <img :src="item.imgUrl" class="product__img" />
          <div class="product__list">
            <span class="product__list__name">{{ item.name }}</span>
            <!-- <span class="product__list__sales">月售{{ item.sales }}件</span> -->
            <div class="product__list__price">
              <span class="cur-price">
                <i class="cur-price__icon">¥</i>
                {{ item.price }}
              </span>
              <span class="price">¥{{ item.oldPrice }}</span>
            </div>
          </div>
          <div class="product__number">
            <span
              class="product__number__minus"
              @click="
                () => {
                  changeCartItemInfo(shopId, item._id, item, -1);
                }
              "
              >-</span
            >
            {{ cartList?.[shopId]?.[item._id]?.count || 0 }}
            <span
              class="product__number__plus"
              @click="
                () => {
                  changeCartItemInfo(shopId, item._id, item, 1);
                }
              "
              >+</span
            >
          </div>
        </div>
      </div>
      <div class="cart">
        <div class="cart__sort">
          <span class="iconfont cart__sort__icon">&#xe607;</span>
          <span class="cart__sort__number">{{ total }}</span>
        </div>
        <div class="cart__total-price">
          <span class="cart__total-price__total">总价:</span>
          <span class="cart__total-price__price">¥ {{ price }}</span>
        </div>
        <div class="cart__pay">去结算</div>
      </div>
    </template>
    
    <script>
    import { useStore } from "vuex";
    import { useRoute } from "vue-router";
    import { computed } from "vue";
    
    //获取购物车信息逻辑
    const useCartEffect = () => {
      const store = useStore();
      const route = useRoute();
      const shopId = route.params.id;
      const cartList = store.state.cartList;
    
      //计算总单数
      const total = computed(() => {
        const productList = cartList[shopId];
        let count = 0;
        if (productList) {
          for (let i in productList) {
            const product = productList[i];
            count += product.count;
          }
        }
        return count;
      });
    
      //计算总价格
      const price = computed(() => {
        const productList = cartList[shopId];
        let count = 0;
        if (productList) {
          for (let i in productList) {
            const product = productList[i];
            count += product.price * product.count;
          }
        }
        return count.toFixed(2);
      });
    
      const productItemList = computed(() => {
        const productList = cartList[shopId] || [];
        // console.log(productList);
        return {
          productList,
        };
      });
    
      return {
        total,
        price,
        productItemList,
        cartList,
        shopId,
      };
    };
    
    export default {
      name: "Cart",
      setup() {
        const { total, price, productItemList, cartList, shopId } = useCartEffect();
        console.log(productItemList.value);
        return { price, total, productItemList, cartList, shopId };
      },
    };
    </script>
    
    <style lang="scss" scoped>
    @import "../../style/viriables.scss";
    @import "../../style/mixins.scss";
    .cart-menu {
      position: absolute;
      padding: 0 0.18rem;
      left: 0;
      right: 0;
      bottom: 0.5rem;
      background-color: $color-FFF;
      .product {
        position: relative;
        display: flex;
        width: 100%;
        height: 0.8rem;
        border-bottom: 0.01rem solid $color-FFF;
        background-color: $color-FFF;
        &__number {
          position: absolute;
          display: flex;
          align-items: center;
          right: 0;
          bottom: 0.12rem;
          &__minus {
            @include addAndMinus;
            box-sizing: border-box;
            border: 0.01rem solid $color-666;
            color: $color-666;
            margin-right: 0.1rem;
          }
          &__plus {
            @include addAndMinus;
            background-color: $color-0091FF;
            color: $color-FFF;
            margin-left: 0.1rem;
          }
        }
        &__img {
          height: 0.68rem;
        }
        &__list {
          display: flex;
          margin-left: 0.16rem;
          flex-direction: column;
          &__name {
            @include ellipsis;
            width: 1.5rem;
            font-size: 0.14rem;
            color: $color-333;
            line-height: 0.2rem;
            font-weight: 600;
            margin-bottom: 0.06rem;
          }
          // &__sales {
          //   font-size: 12px;
          //   color: $color-333;
          //   line-height: 16px;
          //   margin-bottom: 0.06rem;
          // }
          &__price {
            display: flex;
            align-items: center;
            .cur-price {
              color: $color-E93B3B;
              &__icon {
                font-style: normal;
                display: inline-block;
                font-size: 0.12rem;
                transform: scale(0.85);
                margin-right: -0.03rem;
              }
            }
            .price {
              text-decoration: line-through;
              display: inline-block;
              margin-left: -0.07rem;
              font-size: 0.2rem;
              color: $color-999;
              line-height: 0.2rem;
              transform: scale(0.5);
            }
          }
        }
      }
    }
    .cart {
      display: flex;
      align-items: center;
      box-sizing: border-box;
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      height: 0.5rem;
      background: $color-FFF;
      box-shadow: 0 -1px 1px 0 $color-F1F1F1;
      &__sort {
        position: relative;
        margin: 0 0.32rem 0 0.24rem;
        &__icon {
          font-size: 0.26rem;
          color: $color-0091FF;
        }
        &__number {
          position: absolute;
          display: flex;
          justify-content: center;
          align-items: center;
          left: 0.25rem;
          top: -0.07rem;
          padding: 0 0.05rem;
          min-width: 0.2rem;
          height: 0.2rem;
          border-radius: 0.1rem;
          font-size: 0.16rem;
          color: $color-FFF;
          transform: scale(0.5);
          transform-origin: left center;
          background-color: $color-E93B3B;
        }
      }
      &__total-price {
        width: 1.93rem;
        &__total {
          font-size: 0.12rem;
          color: $color-333;
          margin-right: 0.1rem;
        }
        &__price {
          font-size: 0.18rem;
          color: $color-E93B3B;
        }
      }
      &__pay {
        flex: 1;
        text-align: center;
        line-height: 0.49rem;
        width: 0.98rem;
        color: $color-FFF;
        font-size: 0.14rem;
        background-color: $color-4FB0F9;
      }
    }
    </style>

    实现的效果是这样的:

    https://img1.sycdn.imooc.com//climg/61b9b49f098192e519201038.jpg



    还有以下问题:

    问题一:我打印这段代码,为什么控制台出现了两遍呢?

    https://img1.sycdn.imooc.com//climg/61b9b4fd0950571619201030.jpg


    问题二:为什么我的html结构会重复了两次,但是没有影响页面的显示

    https://img1.sycdn.imooc.com//climg/61b9b56c09aafc6019200902.jpg

    2021-12-15 17:29:22
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师