带有 v-for 的 srcset
srcset with a v-for
我可能会错过一些基本的 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>
我已经将所有格式作为道具传递到组件中,因此它们都存储为 "images"
基本上我想要的是有一个单一的 source 可以遍历格式(不一定总是有大或小)并在里面添加 URL :srcset.
当然可以
<source v-for="format in images" :srcset="apiUrl + format.url">
有效但会生成多个 source
针对这种情况的最佳方法或解决方案是什么?
谢谢
简单的解决方案:
如果您不想使用 computed 或 component,您可以只使用传递 post 并且它 returns 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 url.
这使用了文档的 Props, Computed Properties, Template Syntax, List Rendering and Component Registration 部分,可能会有用。
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>
我可能会错过一些基本的 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>
我已经将所有格式作为道具传递到组件中,因此它们都存储为 "images"
基本上我想要的是有一个单一的 source 可以遍历格式(不一定总是有大或小)并在里面添加 URL :srcset.
当然可以
<source v-for="format in images" :srcset="apiUrl + format.url">
有效但会生成多个 source
针对这种情况的最佳方法或解决方案是什么? 谢谢
简单的解决方案:
如果您不想使用 computed 或 component,您可以只使用传递 post 并且它 returns 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 url.
这使用了文档的 Props, Computed Properties, Template Syntax, List Rendering and Component Registration 部分,可能会有用。
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>