老师,我的shopName为什么是空?

正在回答

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

1回答

同学你好,老师这里也猜不到是为什么,需要使用代码测试。请将相关涉及到的代码全部复制粘贴上来(vue与js的)

如store中的js代码如下:

import Vuex from 'vuex'

export default Vuex.createStore({

  state: {

    cartList: {}

  },

  mutations: {

    changeCartItemInfo(state, payload) {

      const { shopId, productId, productInfo } = payload

      let shopInfo = state.cartList[shopId] || {

        shopName: '', productList:{}

      }

      let product = shopInfo.productList[productId]

      if(!product) {

        productInfo.count = 0

        product = productInfo

      }

      product.count = product.count + payload.num

      if(payload.num > 0) { product.check = true }

      if(product.count < 0) { product.count = 0 }

      shopInfo.productList[productId] = product

      state.cartList[shopId] = shopInfo

    },

    changeShopName(state, payload) {

      const { shopId, shopName } = payload

      const shopInfo = state.cartList[shopId] || {

        shopName: '', productList:{}

      }

      shopInfo.shopName = shopName

      state.cartList[shopId] = shopInfo

    },

    changeCartItemChecked(state, payload) {

      const { shopId, productId } = payload

      const product = state.cartList[shopId].productList[productId]

      product.check = !product.check

    },

    cleanCartProducts(state, payload) {

      const { shopId } = payload

      state.cartList[shopId].productList = {}

    },

    setCartItemsChecked(state, payload) {

      const { shopId } = payload

      const products = state.cartList[shopId].productList

      if(products) {

        for(let key in products) {

          const product = products[key]

          product.check = true

        }

      }

    }

  }

})


祝学习愉快!

  • 慕UI4313976 提问者 #1

    shopView

    <template>
      <div class="wrapper">
        <div class="search">
          <div class="search__back iconfont" @click="handleBackClick">&#xe600;</div>
          <div class="search__content">
            <span class="search__content__icon iconfont">&#xe6ac;</span>
            <input class="search__content__input" placeholder="请输入商品名称" />
          </div>
        </div>
        <ShopInfo :item="item" :hideBorder="true" v-show="item.imgUrl" />
        <ContentView :shopName="item.name" />
        <CartView />
      </div>
    </template>
    <script>
    import { reactive, toRefs } from 'vue';
    import { useRouter, useRoute } from 'vue-router';
    import { get } from '../../utils/request';
    import ShopInfo from '../../components/ShopInfo';
    import ContentView from './ContentView.vue'
    import CartView from './CartView.vue';
    
    // 获取当前商铺信息
    const useShopInfoEffect = () => {
      const route = useRoute();
      const data = reactive({
        item: {},
      });
      const getItemData = async () => {
        const result = await get(`api/shop/${route.params.id}`)
        if (result?.errno === 0 && result?.data) {
          data.item = result.data;
        }
      }
    
      const { item } = toRefs(data);
      return { item, getItemData }
    }
    
    //点击回退逻辑
    const useBackRouterEffect = () => {
      const router = useRouter();
      const handleBackClick = () => {
        router.back();
      }
    
      return { handleBackClick }
    }
    
    export default {
      name: 'ShopView',
      components: { ShopInfo, ContentView, CartView, CartView },
      setup() {
        const { item, getItemData } = useShopInfoEffect();
        const { handleBackClick } = useBackRouterEffect();
        getItemData();
    
        return { item, handleBackClick }
      }
    }
    </script>
    
    <style lang="scss" scoped>
    @import '../../style/virables.scss';
    
    .wrapper {
      padding: 0 .18rem;
    }
    
    .search {
      display: flex;
      margin: .14rem 0 .04rem 0;
    
      &__back {
        width: .32rem;
        line-height: .32rem;
        font-size: .24rem;
        color: #b6b6b6;
      }
    
      &__content {
        flex: 1;
        display: flex;
        background: $search-bgColor;
        border-radius: .16rem;
    
        &__icon {
          width: .44rem;
          line-height: .34rem;
          text-align: center;
          color: $search-fontColor;
        }
    
        &__input {
          display: block;
          width: 100%;
          padding-right: .2rem;
          border: none;
          outline: none;
          background: none;
          line-height: .32rem;
          font-size: .14rem;
          color: $content-fontcolor;
    
          &::placeholder {
            color: $content-fontcolor;
          }
        }
      }
    }
    </style>
    2022-10-20 14:13:36
  • 慕UI4313976 提问者 #2

    ContentView.vue

    <template>
      <div class="content">
        <div class="category">
          <div :class="{ 'category__item': true, 'category__item--active': currentTab === item.tab }"
            v-for="item in categories" :key="item.name" @click="() => { handleTabClick(item.tab) }">
            {{ item.name }}
          </div>
        </div>
        <div class="product">
          <div class="product__item" v-for="item in list" :key="item._id">
            <img class="product__item__img" :src="item.imgUrl" alt="">
            <div class="product__item__detail">
              <h4 class="product__item__title">{{ item.name }}</h4>
              <p class="product__item__sales">月售{{ item.sales }}件</p>
              <p class="product__item__price">
                <span class="product__item__yen">&yen;</span>{{ item.price }}
                <span class="product__item__origin">&yen;{{ item.oldPrice }}</span>
              </p>
            </div>
            <div class="product__number">
              <span class="product__number__minus"
                @click="() => { changeCartItem(shopId, item._id, item, -1,shopName) }">-</span>
              {{ cartList?.[shopId]?.productList?.[item._id]?.count || 0 }}
              <span class="product__number__plus"
                @click="() => { changeCartItem(shopId, item._id, item, 1,shopName) }">+</span>
            </div>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    import { reactive, ref, toRefs, watchEffect } from 'vue';
    import { useRoute } from 'vue-router';
    import { useStore } from 'vuex'
    import { get } from '../../utils/request';
    import { useCommonCartEffect } from './commonCartEffect';
    
    const categories = [
      { name: '全部商品', tab: 'all' },
      { name: '秒杀', tab: 'seckill' },
      { name: '新鲜水果', tab: 'fruit' }
    ]
    // Tab 切换相关逻辑
    const useTabEffect = () => {
      const currentTab = ref(categories[0].tab);
      const handleTabClick = (tab) => {
        currentTab.value = tab;
      }
    
      return { currentTab, handleTabClick }
    }
    
    // 列表内容相关逻辑
    const useCurrentListEffect = (currentTab, shopId) => {
      const content = reactive({ list: [] })
    
      const getContentData = async () => {
        const result = await get(`/api/shop/${shopId}/products`, {
          tab: currentTab.value
        })
        if (result?.errno === 0 && result?.data?.length) {
          content.list = result.data;
        }
      }
    
      watchEffect(() => {
        getContentData()
      })
    
      const { list } = toRefs(content);
    
      return { list };
    }
    
    export default {
      name: 'ContentView',
      props: ['shopName'],
      setup() {
        const router = useRoute();
        const shopId = router.params.id;
        const store = useStore();
    
        const { currentTab, handleTabClick } = useTabEffect();
        const { list } = useCurrentListEffect(currentTab, shopId);
        const { cartList, changeCartItemInfo } = useCommonCartEffect();
        const changeShopName = (shopId, shopName) => {
          store.commit('changeShopName', { shopId, shopName })
        }
        const changeCartItem = (shopId, productId, item, num, shopName) => {
          changeCartItemInfo(shopId, productId, item, num)
          changeShopName(shopId, shopName)
        }
    
        return {
          currentTab, handleTabClick, categories, list, shopId, changeCartItem, cartList
        }
      }
    }
    </script>
    
    <style scoped>
    @import '../../style/virables.scss';
    @import '../../style/mixins.scss';
    
    .content {
      display: flex;
      position: absolute;
      left: 0;
      right: 0;
      top: 1.5rem;
      bottom: .5rem;
    }
    
    .category {
      overflow-y: scroll;
      width: .76rem;
      height: 100%;
      background: $search-bgColor;
    
      &__item {
        line-height: .4rem;
        text-align: center;
        font-size: .14rem;
        color: $content-fontcolor;
    
        &--active {
          background: $bgColor;
        }
      }
    }
    
    .product {
      overflow-y: scroll;
      flex: 1;
    
      &__item {
        position: relative;
        display: flex;
        padding: .12rem 0;
        margin: 0 .16rem;
        border-bottom: .01rem solid $content-bgColor;
    
        &__detail {
          overflow: hidden;
        }
    
        &__img {
          width: .68rem;
          height: .68rem;
          margin-right: .16rem;
        }
    
        &__title {
          margin: 0;
          line-height: .2rem;
          font-size: .14rem;
          color: $content-fontcolor;
          @include ellipsis;
        }
    
        &__sales {
          margin: .06rem 0;
          line-height: .16rem;
          font-size: .12rem;
          color: $content-fontcolor;
        }
    
        &__price {
          margin: 0;
          line-height: .2rem;
          font-size: .14rem;
          color: $hightlight-fontColor;
        }
    
        &__yen {
          font-size: .02rem;
        }
    
        &__origin {
          margin-left: .06rem;
          line-height: .2rem;
          font-size: .12rem;
          color: $light-fontColor;
          text-decoration: line-through;
        }
    
        .product__number {
          position: absolute;
          right: 0;
          bottom: .12rem;
    
          &__minus,
          &__plus {
            display: inline-block;
            width: .2rem;
            height: .2rem;
            line-height: .19rem;
            border-radius: 50%;
    
            font-size: .2rem;
            text-align: center;
          }
    
          &__minus {
            border: .01rem solid $medium-fontColor;
            color: $medium-fontColor;
            margin-right: .05rem;
          }
    
          &__plus {
            background: $btn-bgColor;
            color: $bgColor;
            margin-left: .05rem;
          }
        }
      }
    }
    </style>



    2022-10-20 14:14:01
  • 慕UI4313976 提问者 #3

    store

    import { createStore } from "vuex";
    
    export default createStore({
      state: {
        // {shopId:{shopName:'',productList:{priductId:{}}}}
        cartList: {
          // // 第一层级是商铺的ID
          // shopId: {
          //  商店名称
          //  shopName:'沃尔玛',
          //  商品列表
          //  productList:{
          //    第二层是商品ID
          //    productId: {
          //    第二层内容商品内容以及购物数量
          //     _id: "1",
          //     name: "番茄 250g / 份",
          //     imgUrl: "http://www.dell-lee.com/imgs/vue3/tomato.png",
          //     sales: 10,
          //     price: 33.6,
          //     oldPrice: 39.6,
          //     count: 1,
          //   },
          // }
          // },
        },
      },
      getters: {},
      mutations: {
        changeCartItemInfo(state, payload) {
          const { shopId, productId, productInfo } = payload;
          let shopInfo = state.cartList[shopId] || {
            shopName: '', productList: {}
          }
          let product = shopInfo.productList[productId];
          if (!product) {
            product = productInfo;
            product.count = 0;
          }
          product.count = product.count + payload.num;
          if (payload.num > 0) {
            product.check = true;
          }
          if (product.count < 0) {
            product.count = 0;
          }
          shopInfo.productList[productId] = product;
          state.cartList[shopId] = shopInfo;
          console.log(state.cartList);
        }, changeShopName(state, payload) {
          const { shopId, shopName } = payload
          const shopInfo = state.cartList[shopId] || {
            shopName: '', productList: {}
          }
          shopInfo.name = shopName
          state.cartList[shopId] = shopInfo
        },
        changeCartItemChecked(state, payload) {
          const { shopId, productId } = payload;
          const product = state.cartList[shopId].productList[productId];
          product.check = !product.check;
        },
        cleanCartProducts(state, payload) {
          const { shopId } = payload;
          state.cartList[shopId].productList = {};
        },
        setCartItemsChecked(state, payload) {
          const { shopId } = payload;
          const products = state.cartList[shopId].productList
          if (products) {
            for (let key in products) {
              const product = products[key];
              product.check = true;
            }
          }
        }
      },
      actions: {},
      modules: {},
    });



    2022-10-20 14:14:16
问题已解决,确定采纳
还有疑问,暂不采纳

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

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

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

在线咨询

领取优惠

免费试听

领取大纲

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