旋转浏览使用获取的数据创建的 img



我有一个有效的解决方案,但对我来说,这似乎很混乱,在Vue中不是正确的方法。

我需要从后端获取关于";供应商";。供应商的照片应该显示在页面上。我想要一次显示一张照片,然后通过使用setInterval改变它们的不透明度,每5秒旋转一次。

我有一个img的"ref"。但是,我不能在'.then'中使用它,因为this.$refscreated()中不可用。在这种情况下;参考文献";由于CCD_ 4中的异步获取,在CCD_。

我显然不能将setInterval放在更新中,因为它为每次更新创建了一个新的侦听器(是的,我是个白痴,实际上尝试过…(

现在,updated()每次更新时都会设置this.photoCount。在CCD_ 7中添加setInterval,并且直到CCD_。

<template>
<notification-banner
v-show="banner.displayed"
:type="banner.type"
:message="banner.message"
></notification-banner>
<div class="container">
<svg class="settingsIcon" width="24px" height="24px" stroke-width="1.5" viewBox="0 0 24 24" fill="none" color="#000000">
<path d="M12 15a3 3 0 100-6 3 3 0 000 6z" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M19.622 10.395l-1.097-2.65L20 6l-2-2-1.735 1.483-2.707-1.113L12.935 2h-1.954l-.632 2.401-2.645 1.115L6 4 4 6l1.453 1.789-1.08 2.657L2 11v2l2.401.655L5.516 16.3 4 18l2 2 1.791-1.46 2.606 1.072L11 22h2l.604-2.387 2.651-1.098C16.697 18.831 18 20 18 20l2-2-1.484-1.75 1.098-2.652 2.386-.62V11l-2.378-.605z" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
<div class="sidebar">
<h1>{{vendor.name}}</h1>
<p>{{vendor.email}}</p>

<div class="personalUrl">
<p>market.com/{{vendor.url}}</p>
<svg @click="copyUrl" width="24px" height="24px" stroke-width="1.5" viewBox="0 0 24 24" fill="none" color="#000000">
<path d="M19.4 20H9.6a.6.6 0 01-.6-.6V9.6a.6.6 0 01.6-.6h9.8a.6.6 0 01.6.6v9.8a.6.6 0 01-.6.6z" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M15 9V4.6a.6.6 0 00-.6-.6H4.6a.6.6 0 00-.6.6v9.8a.6.6 0 00.6.6H9" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</div>
</div>
<div class="contents">
<h1>{{vendor.name}}</h1>
<div class="vendorPhotos">
<div class="vendorPhoto" v-for="(photo, i) in vendor.photos" :key="i">
<img ref="vendorPhoto" :src="`http://localhost:8000${photo}`" alt="Vendor provided image" :class="i===displayedPhoto ? 'displayPhoto' : 'hidePhoto'"/>
</div>
</div>
<p>{{vendor.description}}</p>
</div>
</div>
</template>
<script>
export default {
data(){
return {
vendor: {},
banner: {
displayed: false,
type: "",
message: ""
},
displayedPhoto: 0,
photoCount: null
}
},
created(){
let token = localStorage.getItem("jwt");
let headers = {"Content-Type": "application/json"};
if(token !== null) headers["Authorization"] = `Bearer ${token}`;
fetch(`http://localhost:8000/vendor${document.location.pathname}`, {
method: "get",
headers: headers,
})
.then(r=>r.json())
.then((vendor)=>{
this.vendor = vendor;
})
.catch((err)=>{
console.error(err);
});
setInterval(()=>{
if(this.photoCount !== null){
if(this.displayedPhoto >= this.photoCount){
this.displayedPhoto = 0;
}else{
this.displayedPhoto++;
}
}
}, 5000);
},
updated(){
this.photoCount = this.$refs.vendorPhoto.length;
}

我怎么能在一个更好、更";类似vue的";方法我的解决方案在工作时看起来像垃圾。

我要更改的内容:

  • 无需计算$refsvendor.photos.length中已提供该信息
  • photoCount应该是computed。将其分离状态会有与vendor.photos.count不同步的风险,这可能会导致细微的错误。原则上,派生状态(例如:computed,存储getters(应该始终是派生状态,而不是将相同的信息保存在状态中的两个独立位置
  • CCD_ 16增量函数可以简化为:
methods: {
changePhoto() {
this.displayedPhoto = (this.displayedPhoto + 1) % this.photoCount
}
}
  • 获取供应商应该是一个独立的方法(例如:fetchVendor(。这允许在业务逻辑需要时重新获取,它不再与组件生命周期耦合
  • 我在mounted中移动了抓取。created应该只保存在组件添加到DOM之前需要运行的代码。获取数据的情况并非如此
    created中的Fetching会造成一种错误的印象,即组件可能不必在返回Fetching之前处理渲染。这从来都不是真的,即使后端运行在同一台机器上也是如此
    我宁愿取CCD_ 21;正在加载"充分陈述(例如:装载指示器、有趣的图片等(
  • 我想提请注意:
    { hidden: i !== displayedPhoto % photoCount }。我为一个边缘案例添加了% photoCount部分:如果/当你从一个有10张图片的供应商切换到一个有5张图片的卖家时,如果显示的照片索引高于5,那么在间隔fn再次运行之前,将看不到任何图片。添加% photoCount可以确保显示新供应商的图片。或者,我们可以观察vendor,并在vendor上将displayedPhoto设置为0
  • 谈到交换vendor,我还添加了一种更健壮的方式来处理";滑块">,确保在任何情况下都没有间隔

请在此处查看。注:

  • 我不得不用返回实际调用响应近似值的promise来模拟axios请求
  • 我为图像制作了一个自定义音量控制器,因为你还没有分享那个代码

就这样。

最新更新