带V-for的SRCET

问题描述 投票:0回答:1

我可能错过了一些基本的vue.js知识,但我有以下问题与 <picture> 特别是srcset

我的api上有不同格式的同一张图片,像这样。

"posts": [
  {
    "image": {
      "formats": {
        "thumbnail": {
          "hash": "thumbnail_image",
          "ext": ".png",
          "mime": "image/png",
          "width": 245,
          "height": 138,
          "size": 76.89,
          "url": "/uploads/thumbnail_image.png"
        },
        "large": {
          "hash": "large_image",
          "ext": ".png",
          "mime": "image/png",
          "width": 1000,
          "height": 563,
          "size": 916.23,
          "url": "/uploads/large_image.png"
        },
        "medium": {
          "hash": "medium_image",
          "ext": ".png",
          "mime": "image/png",
          "width": 750,
          "height": 422,
          "size": 562.28,
          "url": "/uploads/medium_image.png"
        },
        "small": {
          "hash": "small_image",
          "ext": ".png",
          "mime": "image/png",
          "width": 500,
          "height": 281,
          "size": 275.16,
          "url": "/uploads/small_image.png"
        }
      }
    }
  },

我想得到的最终结果是这样的:

<picture>
  <source srcset="https://apiurl.com/large_image.png 1000w, https://apiurl.com/medium_image.png  750w, https://apiurl.com/small_image.png 500w" />
</picture>

我已经把所有的格式作为一个道具传到了组件中 所以它们都被存储为 "图片"

基本上我想的是有一个单一的 源头 可以在格式中循环(不一定有大的或小的),并在:srcset中添加URL。

当然,我也能做到

<source v-for="format in images" :srcset="apiUrl + format.url">

运作,但会产生多个 源头

对于这种情况,有什么好的办法或解决方案呢? 谢谢。

vue.js nuxt.js v-for srcset
1个回答
1
投票

简单的解决方案。

如果你不想使用 计算的组成部分你可以直接使用一个方法,在这个方法中,你传递一个post,它返回srcset urls。

methods: {
    postSrcSetUrls(post) {
        if (!post || !post.image || !post.image.formats)
            return null;

        let sizes = Object.keys(post.image.formats);
        return sizes.map(size => `${post.image.formats[size].url} ${post.image.formats[size].width}w`).join(", ");
    }
}

然后,在你的模板中

<picture v-for="post in posts">
    <source :srcset="postSrcSetUrls(post)" />
</picture>

计算组件解决方案。

我会做一个组件,并使用 computed 属性来完成你的工作。然后你可以使用 Object.keys 来获取格式大小的名称,然后可以用来循环浏览你的格式。

我已经包含了下面的一段代码,你可能需要稍加修改,例如包含你的api网址。

这使用了 道具, 计算属性, 模板语法, 列表渲染组件注册 文件的各个部分,这可能是有用的。

Vue.component("post-image-formats", {
  template: "<div><strong>Src Set Url</strong><br /> {{srcsetUrl}}</div>",
  props: ["formats"],
  computed: {
    srcsetUrl() {
      if (!this.formats)
        return null;

      let sizes = Object.keys(this.formats);
      return sizes.map(size => `${this.formats[size].url} ${this.formats[size].width}w`).join(", ");
    }
  }
});

let posts = [{
    "image": {
      "formats": {
        "thumbnail": {
          "hash": "thumbnail_image",
          "ext": ".png",
          "mime": "image/png",
          "width": 245,
          "height": 138,
          "size": 76.89,
          "url": "/uploads/thumbnail_image.png"
        },
        "large": {
          "hash": "large_image",
          "ext": ".png",
          "mime": "image/png",
          "width": 1000,
          "height": 563,
          "size": 916.23,
          "url": "/uploads/large_image.png"
        },
        "medium": {
          "hash": "medium_image",
          "ext": ".png",
          "mime": "image/png",
          "width": 750,
          "height": 422,
          "size": 562.28,
          "url": "/uploads/medium_image.png"
        },
        "small": {
          "hash": "small_image",
          "ext": ".png",
          "mime": "image/png",
          "width": 500,
          "height": 281,
          "size": 275.16,
          "url": "/uploads/small_image.png"
        }
      }
    }
  },
  {
    "image": {
      "formats": {
        "thumbnail": {
          "hash": "thumbnail_image",
          "ext": ".png",
          "mime": "image/png",
          "width": 245,
          "height": 138,
          "size": 76.89,
          "url": "/uploads/thumbnail_image.png"
        },
        "large": {
          "hash": "large_image",
          "ext": ".png",
          "mime": "image/png",
          "width": 1000,
          "height": 563,
          "size": 916.23,
          "url": "/uploads/large_image.png"
        },
        "medium": {
          "hash": "medium_image",
          "ext": ".png",
          "mime": "image/png",
          "width": 750,
          "height": 422,
          "size": 562.28,
          "url": "/uploads/medium_image.png"
        },
        "small": {
          "hash": "small_image",
          "ext": ".png",
          "mime": "image/png",
          "width": 500,
          "height": 281,
          "size": 275.16,
          "url": "/uploads/small_image.png"
        }
      }
    }
  }
];

new Vue({
  el: "#app",
  data: () => {
    return {
      posts: posts
    };
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div>
    <post-image-formats v-for="post in posts" :formats="post.image.formats"></post-image-formats>
  </div>
</div>
© www.soinside.com 2019 - 2024. All rights reserved.