我现在是在子组件分别获取数据,如何写可以只在index中获取一次,别的组件调用

我现在是在子组件分别获取数据,如何写可以只在index中获取一次,别的组件调用

<template>
  <transition name="product">
    <div class="product">
      <header class="g-header-container">
        <product-header></product-header>
      </header> 
      <me-scroll>
        <product-slider></product-slider>
        <product-content></product-content>
      </me-scroll> 
    </div>
  </transition>
</template>

<script>
import {getProductDetail} from 'api/product';
import ProductHeader from './header';
import MeScroll from 'base/scroll';
import ProductSlider from './slider';
import ProductContent from './content';

export default {
  name: 'Product',
  components:{
    ProductHeader,
    MeScroll,
    ProductSlider,
    ProductContent
  },
  data(){
    return {
      products:{}
    };
  },
  created(){
    getProductDetail(this.$route.params.id).then(data => {
      //console.log(data.data);
      this.products=data.data;
    });
  }
};
</script>

<style lang="scss" scoped>
@import "~assets/scss/mixins";
.product {
  overflow: hidden;
  position: absolute;
  top: 0;
  left: 0;
  z-index: $product-z-index;
  width: 100%;
  height: 100%;
  background-color: $bgc-theme;
}
.product-enter-active,
.product-leave-active {    
    transition: all 0.3s;
}

.product-enter,
.product-leave-to {
  transform: translate3d(100%, 0, 0);
}
.product-enter-to{
  transform: translate3d(0, 0, 0);
}
</style>
<template>  
    <div class="slider-wrapper">  
      <me-loading :text="'加载中'" v-if="!sliders.length"></me-loading>
      <me-slider :direction="direction" :loop="loop" :interval="interval" :pagination="pagination" :datas="sliders" v-else>
        <swiper-slide v-for="(item,index) in sliders" :key="index">
          <a href="#" class="slider-link">
            <img :src="item" alt="pic" class="slider-img">
          </a>
        </swiper-slide>
      </me-slider>
    </div>  
</template>

<script>
  import MeSlider from 'base/slider';
  import {swiperSlide} from 'vue-awesome-swiper';
  import {getProductDetail} from 'api/product';
  import {sliderOptions} from './config';
  import {getHomeSlider} from 'api/home';
  import MeLoading from 'base/loading';

  export default {
    name: 'HomeSlider',
    components:{
        MeSlider,
        MeLoading,
        swiperSlide
    },
    data(){
      return{
        direction:sliderOptions.direction,
        loop:sliderOptions.loop,
        interval:sliderOptions.interval,
        pagination:sliderOptions.pagination,
        sliders:[]
      };
    },
    created(){
      this.getSliders();
    },
    methods:{
      getSliders(){
        getProductDetail(this.$route.params.id).then(data => {
            //console.log(data.data);
            this.sliders=data.data.item.images;
        });
      }
    }
  };
</script>

<style lang="scss" scoped>
  .slider-wrapper{
    height: 300px;
  }
  .slider-link{
    display: block;
  }
  .slider-link,.slider-img{
    width: 100%;
    height: 100%;
  }
</style>
<template>
    <div>
        <div>
            <p>¥{{content.seller.allItemCount}}</p>
            <p>{{content.seller.newItemCount}}件已售</p>
        </div>
    </div>
  </template>

<script>
import {getProductDetail} from 'api/product';
export default {
    data(){
        return {
            content:{}
        };
    },
    created(){
      this.getContent();
    },
    methods:{
      getContent(){
        getProductDetail(this.$route.params.id).then(data => {
            console.log(data.data);
            this.content=data.data;
        });
      }
    }
};
</script>

<style lang="scss" scoped>

</style>
<template>      
    <me-navbar class="header">
        <i class="iconfont" slot="left" @click="goBack">&#xe60d;</i>
        <p slot="center">商品详情</p>
        <i class="iconfont" slot="right">&#xe501;</i>
    </me-navbar> 
</template>

  <script>
    import MeNavbar from "base/navbar";
  
    export default {
      name: 'ProductHeader',
      components:{
          MeNavbar
      },
      data(){
        return{
          
        };
      },
      methods:{
        goBack(){
            this.$router.back();
        }
      }
    };
  </script>

<style lang="scss" scoped>
    @import "~assets/scss/mixins";
    .header{
        background-color: $header-bgc-translucent;
        color: white;
        p{
            text-align: center;
        }
    }
</style>


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

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

2回答
好帮手慕夭夭 2020-04-14 17:17:32

同学你好,问题解答如下:

1.如下报错意思是获取不到allItemCount属性。这是因为数据是异步请求过来的,当页面渲染用到这些数据时,数据还没有加载过来,获取不到就会报错。

http://img1.sycdn.imooc.com//climg/5e95782e09141cc507830345.jpg

可以加一个if判断,当获取到数据再渲染组件:

content是一个对象,我们可以先使用Object.keys把它转换为一个数组,然后再判断数组长度,如果长度为0,if判断则为false,此时就不会渲染组件了。

http://img1.sycdn.imooc.com//climg/5e9578830975893b06160162.jpg

2.因为淘宝最近更新了一下接口的数据,有很多商品数据是和现在使用的对不上,所以浏览器中会报错。这是淘宝那边的问题,如果点击商品之后出现如下类似错误不用管,因为淘宝最近更新接口有一点频繁,有的商品数据是可以的,测试时如果遇到了此类的,可以多点几个商品试一试。

http://img1.sycdn.imooc.com//climg/5e957e0a09687f3c05740075.jpg

图片轮播区域,要获取到图片的数据,然后再传递给子组件,不然图片轮播的子组件中,使用的是所有的数据:

http://img1.sycdn.imooc.com//climg/5e95832d09cdc26907270126.jpg

其他子组件传递数据也是同理,先定义一个变量获取指定的数据,然后再传递给子组件。最后子组件中,可以在生命周期中,即组件挂载成功之后,把数据赋值给你绑定的那个data。

http://img1.sycdn.imooc.com//climg/5e95836f0987ecac04880193.jpg

祝学习愉快 ~

好帮手慕夭夭 2020-04-14 10:21:44

同学你好,因为代码不全,老师把代码放在源码中运行不了。给同学提供一个思路,自己尝试做一做哦。思路如下:

父组件中把数据请求过来,可以在调用子组件时,把数据传递给子组件。示例:

http://img1.sycdn.imooc.com//climg/5e951d7e09ca880a07230072.jpg

子组件中通过props接收,然后子组件中就可以使用productsData了

http://img1.sycdn.imooc.com//climg/5e951e180990466f07290094.jpg

如果我的回答帮助到了你,欢迎采纳,祝学习愉快~

  • 提问者 迷失的小麦 #1
    传过来的数据如何在子组件中先处理后绑定? (我给忘了如何处理,如:传过来的是data.data,要处理成data.data.item.images)
    2020-04-14 10:29:37
  • 提问者 迷失的小麦 #2
    props:{ slider:{ type:[Object,Array] } }, watch: { slider(){ this.sliders=slider.item.images; } } 这样写报错了。另,我目前写的product的4个页面全部在这里了
    2020-04-14 10:40:29
  • 提问者 迷失的小麦 #3
    通过打印结果发现我需要的数据和我获取的数据不一致
    2020-04-14 10:43:32
问题已解决,确定采纳
还有疑问,暂不采纳

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

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

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

在线咨询

领取优惠

免费试听

领取大纲

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