【问题标题】:v-if Not work when the function return true or false [VueJs]v-if 当函数返回 true 或 false 时不起作用 [VueJs]
【发布时间】:2019-02-20 09:53:00
【问题描述】:

我正在研究 VueJs,并且在我的 template 部分中......我定义了一个条件来检查图像 URL 是否存在。

template:

<div v-for="(sub, key) in Work.sub" :key="sub.id" >
  <span v-if="Image('https://XXXX.blob.core.windows.net/XXXX/XXXXX-' + key +'.png')" > 
     <b-img :src="'https://XXXX.blob.core.windows.net/XXXX/XXXXX-' + key +'.png'" />
  </span>
  <span v-else>
     <b-img :src="default_avatar"/> 
  </span>
</div>

在script:

Image: function(img_url)
{
   return axios({
      method: "GET",
      timeout: 3000,
      headers: {
        .......................
      },
      url: img_url
   })
   .then( function(response){
      this.ifImageExist = true;
      return this.ifImageExist;
   })
   .catch( function(error){
      this.ifImageExist = false;
      return this.ifImageExist;
   })
},

对于default_avatar,它已经在data section 中定义并且没有问题。

我的问题是Image 函数检查图像 URL 是否存在。如果存在,则在给定的 URL 中提供图像,但如果不存在,则图像将为空白!

例如:

当我运行代码时,我的结果会是这样的:

但我希望第一张图片默认填充,不显示不存在图标!

如何解决这个问题?

【问题讨论】:

  • 可以分享一下b-img组件的代码吗?另外我认为 v-if 表达式将始终为真,因为您的 Image 函数返回一个承诺,而不是您返回的实际真/假。所以,即使图像不存在,你 v-if div 也会渲染。
  • b-img 是 bootstrap VueJs 预定义的组件:bootstrap-vue.js.org/docs/components/image,如何解决 promise 的问题? @fullmetal
  • 这是标签而不是组件,对不起! @fullmetal
  • 是的,您可以..您可以创建一个数据属性,即 ifImageExist 并分别在 then/catch 中将其设置为 true 或 false。然后在模板中你可以使用 v-if="ifImageExists"。
  • 我尝试定义一个新变量,调用它 ifImageEcist 并在开始时将其值设置为 false,然后在 axios 内部,当它转到时,我将它的值更改为 true,当它捕获值时将是假的..然后返回它的值..检查问题的更新,但它对我不起作用..仍然是同样的问题。 @fullmetal

标签: javascript azure vue.js vuejs2 azure-storage


【解决方案1】:

首先,您的函数 Image() 不返回 Boolean 它返回 Promise(来自 axios), 所以v-if 评估为 true;

要让v-if 使用 API 调用 (Axios GET),最简单的方法是将 Image 方法转换为 异步方法

Image: async function(img_url)
{
   return axios({
      method: "GET",
      timeout: 3000,
      headers: {
        .......................
      },
      url: img_url
   })
   .then( function(response){
      this.ifImageExist = true;
      return this.ifImageExist;
   })
   .catch( function(error){
      this.ifImageExist = false;
      return this.ifImageExist;
   })
},

如果您已将所有构建配置为使用async function,该方法将等待响应并评估v-if 所期望的Boolean。

【讨论】:

    【解决方案2】:

    替代解决方案:看起来v-if 和v-else 之间的唯一区别是b-img 的src,因此替代方案是将逻辑移至JavaScript,仅当 URL 无法解析时,将 Work.sub 映射到默认为 default_avatar 的图像 URL 数组。

    所以你的模板是:

    <template>
      <div v-for="(img, index) in images" :key="index">
        <b-img :src="img" />
      </div>
    </template
    

    您将添加一个数据属性来保存图像 URL:

    data() {
      return {
        images: []
      }
    }
    

    还有一个Work.sub 上的观察者,它设置this.images:

    watch: {
      'Work.sub': {
        immediate: true,
        async handler(sub) {
          // For each image URL, attempt to fetch the image, and if it returns
          // data (image exists), collect the URL. Otherwise, default.
          this.images = await Promise.all(Object.keys(sub).map(async (key) => {
            const img = sub[key];
            if (!img) return this.default_avatar;
    
            const url = `//placekitten.com/${img}`;
            const { data } = await axios.get(url);
            return data ? url : this.default_avatar;
          }));
        }
      }
    }
    

    demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 2019-03-29
      • 1970-01-01
      • 1970-01-01
      • 2017-08-19
      • 1970-01-01
      相关资源
      最近更新 更多