16. Vueプロジェクトページの詳細ページは、Ajaxを使用して動的データを取得します(主に発生する3つの問題を解決します)

以前に詳細ページにデータを追加しましたが、動的データを取得するにはajaxを使用する必要があります

Detail.vueの親コンポーネントがaxiosをリクエストします

Axiosを最初にここに導入する必要があります

詳細ページはホームページのエントリポイントから入ってくるため、ルーティングが異なります。渡されたパラメータはブラウザに送られ、次の図に示すようにVueモードのブラウジングに切り替わります。インターフェイスをリクエストするときは、パラメータを実行する必要があります。 idであり、パラメータメソッドはthisである必要があります。$ route.params.id
ここに画像の説明を挿入
Detail.vue

<template>
  <div class="detail">
    <detail-banner
      :sightName="sightName"
      :bannerImg="bannerImg"
      :gallaryImgs="gallaryImgs"
    ></detail-banner>
    <detail-header></detail-header>
    <div class="content">
      <detail-list :list="list"></detail-list>
    </div>
  </div>
</template>

<script>
import DetailBanner from './components/Banner'
import DetailHeader from './components/Header'
import DetailList from './components/List'
import axios from 'axios'
export default {
     
     
  name: 'Detail',
  components: {
     
     
    DetailBanner,
    DetailHeader,
    DetailList
  },
  data() {
     
     
    return {
     
     
      sightName: '',
      bannerImg: '',
      gallaryImgs: [],
      list: []
    }
  },
  methods: {
     
     
    getDetailInfo() {
     
     
      axios({
     
     
        url: '/static/mock/detail.json',
        method: 'get',
        params: {
     
     
          id: this.$route.params.id
        }
      }).then(res => {
     
     
        console.log(res)
        if (res.data.ret && res.data.data) {
     
     
          this.sightName = res.data.data.sightName
          this.bannerImg = res.data.data.bannerImg
          this.gallaryImgs = res.data.data.gallaryImgs
          this.list = res.data.data.categoryList
        }
      })
    }
  },
  mounted() {
     
     
    this.getDetailInfo()
  }
}
</script>

<style lang="scss" scoped>
.content {
     
     
  height: 20rem;
}
</style>


サブコンポーネントは、インターフェイスから返されたデータに従ってデータを変更します

Banner.vue

子コンポーネントの小道具は、親コンポーネントからデータを受け取ります
ここに画像の説明を挿入

<template>
  <div>
    <div class="banner" @click="handleBannerClick">
      <img class="banner-img" :src="bannerImg" />
      <div class="banner-info">
        <div class="banner-title">{
   
   { this.sightName }}</div>
        <div class="banner-number">
          <span class="iconfont banner-icon">&#xe62d;</span>
          {
   
   {this.gallaryImgs.length}}
        </div>
      </div>
    </div>
    <common-gallary
      :imgs="gallaryImgs"
      v-show="showGallay"
      @close="handleGallaryClose"
    ></common-gallary>
  </div>
</template>

<script>
import CommonGallary from 'common/gallary/Gallary'
export default {
     
     
  name: 'DetailBanner',
  props: {
     
     
    sightName: String,
    bannerImg: String,
    gallaryImgs: Array
  },
  data() {
     
     
    return {
     
     
      showGallay: false
    }
  },
  methods: {
     
     
    handleBannerClick() {
     
     
      this.showGallay = true
    },
    handleGallaryClose() {
     
     
      this.showGallay = false
    }
  },
  components: {
     
     
    CommonGallary
  }
}
</script>

<style lang="scss" scoped>
.banner {
     
     
  overflow: hidden;
  height: 0;
  padding-bottom: 50%;
  position: relative;
  .banner-img {
     
     
    width: 100%;
  }
  .banner-info {
     
     
    display: flex;
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    line-height: 0.6rem;
    color: #fff;
    background-image: linear-gradient(
      top,
      rgba(0, 0, 0, 0),
      rgba(0, 0, 0, 0.8)
    );
    .banner-title {
     
     
      flex: 1;
      font-size: 0.32rem;
      padding: 0 0.2rem;
    }
    .banner-number {
     
     
      height: 0.4rem;
      line-height: 0.4rem;
      margin-top: 0.1rem;
      padding: 0 0.32rem;
      border-radius: 0.2rem;
      background: rgba(0, 0, 0, 0.6);
      font-size: 0.24rem;
      .banner-icon {
     
     
        margin-right: 0.1rem;
      }
    }
  }
}
</style>

これで、このページのデータ置換は基本的に完了しましたが、まだいくつかの小さな問題があり、悪い経験になります

質問1

ホームページから初めてクリックしたとき、IDは0001でした。ホームページに戻ってエントリを変更したとき、IDはまだ0001であり、データの再フェッチソリューションはありませんでした
ここに画像の説明を挿入

詳細ページはkeep-aliveによってキャッシュされるため、mountd()フック関数は1回だけ実行されます。在keep-alive标签加上exclude=“Detail”詳細ページのキャッシュを今すぐ削除する場合は、mountd()フック関数は入力するたびに実行されます。詳細ページ

ここに画像の説明を挿入
ここに画像の説明を挿入

質問2

複数のページをスライドすると相互に影響します。ホームページをスライドすると、詳細ページも続きます。次に例を示します。

ここに画像の説明を挿入解決:

公式のvue.jsドキュメントには、スクロール動作の方法が記載されています。ルートのルートの下に何かを追加するだけです。
公式リンクを添付してください:https//router.vuejs.org/zh/guide/advanced/scroll-behavior。 html#%E5%BC%82%E6%AD%A5%E6%BB%9A%E5%8A%A8

ここに画像の説明を挿入

質問3

ここに画像の説明を挿入
Vueはkeep-aliveを使用してコンポーネントをキャッシュします。exclude属性は、キャッシュされたコンポーネントが削除され、他のコンポーネントがキャッシュされることを示します。

このプロパティを使用すると、対応するコンポーネントのactivate()deactivate()メソッドは実行されません。

ここに画像の説明を挿入
解決:

着替える

  mounted() {
    
    
    window.addEventListener('scroll', this.handleScroll)
  },
  destroyed() {
    
    
    window.removeEventListener('scroll', this.handleScroll)
  }

おすすめ

転載: blog.csdn.net/weixin_45811256/article/details/109491171