我可能错过了一些基本的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">
运作,但会产生多个 源头
对于这种情况,有什么好的办法或解决方案呢? 谢谢。
简单的解决方案。
如果你不想使用 计算的 或 组成部分你可以直接使用一个方法,在这个方法中,你传递一个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>