首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Vue图像延迟渲染过程

Vue图像延迟渲染过程
EN

Stack Overflow用户
提问于 2018-08-14 21:23:03
回答 1查看 784关注 0票数 1

我遇到了以下问题:我正在加载一个带有动态src的图像,如下所示

代码语言:javascript
复制
:style="{ background: `url(${imageSrc}) center` }"

imageSrc在哪里

代码语言:javascript
复制
require(`@/assets/img/${this.image}`)

一切都很好,但是我试图抽象我的组件,却遇到了一些奇怪的行为。这段代码位于Podcast.vue中,->如预期的那样完美工作。我创建了一个名为PostList.vue的新文件,并将src作为一个属性进行传递。如果我随后在Podcast中使用PostList组件,则Podcast页面不会像预期的那样在单击时直接打开-相反,它会等待图像完全加载,然后再打开页面。这会产生3-5s的延迟,这不是一个选项。它与作为prop传递的图像没有关系,当我硬编码路径时,它是完全相同的。如果我再次从PostList中提取代码,并在Podcast.vue中直接使用它--我会重新获得旧的行为。如果我注释掉require行-没有延迟,这肯定是因为图像的缘故。只有在第一次加载页面后才会发生这种情况,之后才会缓存。

下面是我的完整代码:

PostList.vue

代码语言:javascript
复制
<template>
  <div>

    <Breadcrumbs />

    <v-container fluid grid-list-md>
      <v-card class="custom-card-height">
        <v-layout row>
          <v-flex hidden-sm-and-down md6 pa-0 class="pic-cell" v-if="imageSrc">
            <img :src="imageSrc" :alt="postType">
          </v-flex>
          <v-flex md6 pa-0 class="meditation-content">
            <v-layout row wrap v-if="!loading">
              <v-flex xs6 sm3 class="entry" text-xs-center
                v-for="item of entries"
                :key="item.slug"
                @click="loadItem(item)"
              >
                <v-tooltip bottom>
                  <div slot="activator">
                    <div class="svg-inline" v-html="icon"></div>
                    <h4># {{ item.number }}</h4>
                  </div>
                  <div class="tooltip-content">
                    <h3>{{ item.title }}</h3>
                    <div v-html="item.content"></div>
                  </div>
                </v-tooltip>
              </v-flex>
            </v-layout>
            <LoadingSpinner v-else />
            <Pagination 
              v-if="pageCount"
              :page="page" 
              :pageCount="pageCount"
              @onPaginationInput="paginationHandler"
            />
          </v-flex>
        </v-layout>
      </v-card>

      <BackButton :backString="backString" :link="backLink" />

    </v-container>
  </div>
</template>

<script>
import PostMixin from '@/shared/mixins/post.mixin'
import EventBus from '@/shared/eventBus.js'
export default {
  name: 'post-list',
  mixins: [PostMixin],
  props: {
    postIcon: {
      type: String,
      required: true
    },
    image: {
      type: String,
      required: true
    },
    postType: {
      type: String,
      required: true
    }
  },
  data () {
    return {
      icon: null,
      imageSrc: null
    }
  },
  created () {
    this.icon = require(`@/assets/icons/${this.postIcon}`)
    this.imageSrc = require(`@/assets/img/${this.image}`)
  },
  methods: {
    loadItem (item) {
      let eventString = ''
      switch (this.postType) {
        case 'meditation': eventString = 'playMeditation'; break
        case 'podcast': eventString = 'playPodcast'; break
        default: console.log('kein Posttype in PostIconList.vue')
      }
      EventBus.$emit(eventString, item)
    }
  }
}
</script>

Podcast.vue

代码语言:javascript
复制
<template>
  <PostList
    postType="podcast"
    postIcon="Icon_Pod_grau.svg"
    image="headphone-1868612_1920.jpg"
    backString="Zurück auf's Sofa"
    backLink="/sofa"
  />
</template>

<script>
import PostList from '@/components/PostList'
export default {
  name: 'kopfhoerer',
  components: {
    PostList
  }
}
</script>

post.mixin.js

代码语言:javascript
复制
import Service from '@/shared/services/post.service'
import BackButton from '@/components/BackButton'
import LoadingSpinner from '@/components/LoadingSpinner'
import Breadcrumbs from '@/components/Breadcrumbs'
import Pagination from '@/components/Pagination'

export default {
  components: {
    BackButton,
    LoadingSpinner,
    Breadcrumbs,
    Pagination
  },
  props: {
    postType: {
      type: String,
      required: true
    },
    baseType: {
      type: Boolean,
      required: false,
      default: false
    },
    detailLinkBase: {
      type: String,
      required: false
    },
    backLink: {
      type: String,
      required: false
    },
    backString: {
      type: String,
      required: false
    }
  },
  data () {
    return {
      service: {},
      entries: {},
      loading: true,
      page: 1,
      pageCount: null
    }
  },
  created () {
    this.service = new Service(this.postType, this.baseType)
    this.getPostList()
    this.getMetaData()
  },
  methods: {
    getPostList () {
      this.loading = true
      this.service.getPostList(this.page, this.activeCategory, this.activeAuthor).then(data => {
        this.entries = data
        this.loading = false
        this.pageCount = this.service.pages
      })
    },
    getMetaData () {
      this.service.getMetaData().then(data => {
        if (data.categories) this.categories = data.categories
        if (data.authors) this.authors = data.authors
      })
    },
    paginationHandler (page) {
      this.page = page
      this.getPostList()
    }
  }
}

提前感谢

EN

回答 1

Stack Overflow用户

发布于 2018-08-14 23:37:21

据我所知,您在created()方法上设置了imageSrc属性,这意味着created()中的代码将在组件挂载之前执行,这就是您获得该行为的原因,在这种情况下,我要做的是在计算属性中设置图像,如下所示:

代码语言:javascript
复制
computed: {
  imageSrc() {
    return require('...');
  }
}

如此一来,你就可以确保一旦webpack加载了图片,你的应用程序行为就不会受到影响,图片就会被设置。

剩下的是对UI/UX做一些调整,我建议你使用类似于Medium的东西来显示占位符,直到图像加载,但这取决于你和你的设计:)干杯。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51842561

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档