过滤内容后,为什么放置在Vue模板中的某些图像会消失?

时间:2019-04-10 23:25:28

标签: vue.js drupal filtering

我一直负责一个Drupal网站,该网站的某些内容通过一组复杂的Vue文件放置。我从未使用过Vue,因此在我们面临的关键问题上我需要一些帮助。

我在网站上有一个新闻版块,用户可以从下拉列表中过滤(通过从菜单中选择一个主题)。这很好。但是,每当您带回以前过滤的新闻报道时,精选图片都无法加载。 Vue模板将带回默认图像。但这仅在某些图像中发生。

正如我提到的,Vue.js文件很复杂-它导入了将近十多个控制该网站其他功能的文件。这是最适用的文件中的代码:

export default {
    props: {
        url: {
            type: String,
            required: true,
        },
        tag: {
            type: String,
            required: false,
        },
        eyebrow: {
            type: String,
            required: false,
        },
        title: {
            type: String,
            required: true,
        },
        image: {
            type: Object,
            required: false,
        },
    },
    computed: {
        imageUrl() {
            return this.image && this.image.url ? this.image.url : '/themes/my-theme/images/no-image.jpg';
        }
    },
    template: `
        <a :href="url" class="news-card">
            <span class="news-card__image">
                <img :src="imageUrl" :alt="image.alt">
            </span>
            <span class="news-card__text">
                <span class="news-card__tag" v-if="tag" v-html="tag">
                </span>
                <p class="news-card__eyebrow" v-if="eyebrow">
                    {{ eyebrow }}
                </p>
                <h2 class="news-card__title">
                    {{ title }}
                </h2>
            </span>
        </a>
    `
};

我会发布更多信息,但我不知道诊断Vue问题还需要什么。抱歉,我是Vue的新手,这非常令人困惑!

更新 我在下面添加了view.js代码:

import Vue from '@vue';
import { mapState } from 'vuex';
import ListingGrid from '/components/listing-grid';
import ListingNav from '/components/listing-nav';
import ProgramCard from '/components/program-card';
import ListingCard from '/components/listing-card';
import NewsCard from '/components/news-card';
import ListingFilters from '/components/listing-filters';
import ListingLoader from '/components/listing-loader';
import ListingStickyNav from '/components/listing-sticky-nav';
import TabSelect from '/components/tab-select';
import ajaxStore from './store/ajax';
import staticStore from './store/static';

export default (id) => {
    new Vue({
        el: `#${id}`,
        components: {
            ListingFilters,
            ListingGrid,
            ListingNav,
            ProgramCard,
            ListingCard,
            NewsCard,
            ListingLoader,
            ListingStickyNav,
            TabSelect,
        },
        data: {
            lazy: true
        },
        store: id === 'listing-static' ? staticStore : ajaxStore,
        computed: mapState({
            grid() {
                return this.$store.getters.filteredGrid;
            },
            filters: state => state.filters,
            tabs: state => state.tabs,
            loading: state => state.loading,
            showLoader: state => state.infiniteLoading,
            cardType: state => state.cardType
        }),
        image: {
            type: Object,
            default: function () {
                return {
                    url: '/themes/my-theme/images/no-image.jpg',
                    alt: 'Default No Image Alt Text'
                }
            },
        },
        template: `
            <main class="view__content v-listing vue-loaded" id="${id}">
                <listing-sticky-nav>
                    <template slot="tab-content">
                        <tab-select
                            :tabs="tabs"
                            v-if="tabs.items"
                        >
                        </tab-select>
                    </template>
                    <template slot="panel">
                        <listing-filters
                            :filters="filters"
                            additional-classes="mobile"
                        >
                        </listing-filters>
                    </template>
                </listing-sticky-nav>
                <listing-filters
                    :filters="filters"
                >
                </listing-filters>
                <listing-grid
                    :has-results="grid.length > 0"
                    :loading="loading"
                    :lazy="lazy">
                    <listing-nav
                        v-if="tabs"
                        :tabs="tabs"
                        slot="nav"
                    >
                    </listing-nav>
                    <template slot="grid">
                        <component
                            :is="cardType"
                            v-bind="item"
                            v-for="item, index in grid"
                            :key="index">
                        </component>
                    </template>
                    <template slot="empty">
                        No results found.
                    </template>
                </listing-grid>
                <span class="v-listing-footer" v-if="showLoader">
                    <listing-loader></listing-loader>
                    <span class="visually-hidden">loading</span>
                </span>
            </main>
        `
    });
}

1 个答案:

答案 0 :(得分:0)

尽管我同意上面的评论,即缺少许多要素,但我是VueJS的拥护者,如果可能的话,我希望提供帮助。

我看到的第一个明显问题是不需要属性image。计算所得的属性imageUrl()具有防御性,因为如果省略属性'/themes/my-theme/images/no-image.jpg',它将返回默认值image

但是,在<img />中的模板代码中,您引用的image对象中的对象关键字'alt'可能存在或可能不存在。

我强烈建议添加以下计算属性:

imageAlt() {
    return this.image && this.image.alt ? this.image.alt : 'Default No Image Alt Text';
}

然后在模板中按如下所示更新图像标签:

<img :src="imageUrl" :alt="imageAlt">

这将加强您的代码,确保不会发生错误。您可能想要更新默认的替代文字,因为它仅用于示例目的。

如果这不能解决问题,请在注释中提供以下信息,以寻求其他帮助。

  1. 控制台中是否存在JS错误?
  2. 您下载了Vue Devtools extension吗?
  3. 如果是,在工作时以及遇到此问题后,imageUrl的计算属性值是什么?

更新。作为一种替代方法(我更喜欢这样做),您也可以删除所有计算的属性并提供默认的image对象。这不需要观察者,看起来像这样:

image: {
    type: Object,
    default: function () {
        return {
            url: '/themes/my-theme/images/no-image.jpg',
            alt: 'Default No Image Alt Text'
        }
    },
}

您的图片标签将如下所示:

<img :src="image.url" :alt="image.alt">

有关更多信息,请访问:https://vuejs.org/v2/guide/components-props.html