从问题answer的What is affecting on will Vue computed property re-computed or no?开始,我知道
Vue无法检测到对数组的以下更改:
直接用索引设置项目时,例如 vm.items [indexOfItem] = newValue当您修改 阵列,例如vm.items.length = newLength
肯定是其他情况,因为我明确分配新值到数组。
keyPath
数组为空时,滑块应改为显示虚拟图像(如“无图像”)。"sublayers.moe.position"
更新后,滑块必须显示更新后的照片(如果已删除所有照片,则为空白)。下面的实现达到第一个和第二个目标。
photosURLs
图像滑块指向product.photosURLs
。
.ImageSliderForNarrowScreens
.ImageSliderForNarrowScreens-ActiveImage-DefaultBackgroundUnderlay
.ImageSliderForNarrowScreens-ActiveImage-ImageLayer(
v-if="product.photosURLs.length < 2"
:style="`background-image: url(${activeProductPhotoURL_ForImagesViewer});`"
)
template(v-else)
.ImageSliderForNarrowScreens-ActiveImage-ImageLayer(
:key="'IMAGE_SLIDER-IMAGE-'+activeProductPhotoArrayIndexForImagesViewer"
:style="`background-image: url(${activeProductPhotoURL_ForImagesViewer});`"
v-touch:swipe.left="switchImagesSliderToPreviousPhoto"
v-touch:swipe.right="switchImagesSliderToNextPhoto"
)
将被复制到product.photosURLs
,这是更新但尚未提交的照片URL的数组。product.photosURLs
时,uploadedProductPhotosURLs
将被复制到uploadedProductPhotosURLs
; uploadedProductPhotosURLs
当product.photosURLs
为空时,让我们尝试添加和提交新照片。调试输出将是:
import { Vue, Component, Watch } from "vue-property-decorator";
@Component
export default class MyComponent extends Vue {
private product!: Product;
private uploadedProductPhotosURLs: Array<string> = [];
/* --- Product photos viewing ------------------------------------------------------------------------------------ */
private activeProductPhotoArrayIndexForImagesViewer: number = 0;
private get activeProductPhotoURL_ForImagesViewer(): string {
if (this.product.photosURLs.length === 0) {
return PRODUCT_DUMMY_PHOTO_URL;
}
return this.product.photosURLs[this.activeProductPhotoArrayIndexForImagesViewer];
}
// --- Well, it does not matter, I just mentioned it in template
private switchImagesViewersToNextProductPhoto(): void {
this.activeProductPhotoArrayIndexForImagesViewer =
this.activeProductPhotoArrayIndexForImagesViewer !== this.product.photosURLs.length - 1 ?
this.activeProductPhotoArrayIndexForImagesViewer + 1 : 0;
}
private switchImagesViewersToPreviousProductPhoto(): void {
this.activeProductPhotoArrayIndexForImagesViewer =
this.activeProductPhotoArrayIndexForImagesViewer !== 0 ?
this.activeProductPhotoArrayIndexForImagesViewer - 1 : this.product.photosURLs.length - 1;
}
// ------------------------------------------------------------
/* --- Submitting of changes ------------------------------------------------------------------------------------ */
private async onClickSaveProductButton(): Promise<void> {
try {
await ProductsUpdatingAPI.submit({
// ...
productPhotosURLs: this.uploadedProductPhotosURLs
});
console.log("checkpoint");
console.log("uploadedProductPhotosURLs:");
console.log(this.uploadedProductPhotosURLs);
console.log("'product.photosURLs' before updating:");
console.log(JSON.stringify(this.product.photosURLs, null, 2));
this.product.photosURLs = this.uploadedProductPhotosURLs;
// normally, I must set it to 0, but for now it does not affect
// this.activeProductPhotoArrayIndexForImagesViewer = 0;
console.log("'product.photosURLs' after updating:");
console.log(JSON.stringify(this.product.photosURLs, null, 2));
} catch (error) {
// ....
}
}
}
从算法的角度来看,尚未重新计算所有正确但已计算的属性this.product.photosURLs
(以TypeScript OOP语法获取的属性)!
这意味着checkpoint
uploadedProductPhotosURLs:
[
"https://XXX/c732d006-1261-403a-a32f-f73c0f205aa8.jpeg",
"https://XXX/2b7ae2e2-4424-4038-acee-9624d5b937bc.jpeg",
__ob__: Observer
]
'product.photosURLs' before updating:
[]
'product.photosURLs' after updating:
[
"https://XXX/c732d006-1261-403a-a32f-f73c0f205aa8.jpeg",
"https://XXX/2b7ae2e2-4424-4038-acee-9624d5b937bc.jpeg"
]
仍在显示。
activeProductPhotoURL_ForImagesViewer
与删除图像相同:调试输出与预期的匹配,但是仍显示已删除的缓存图像!
PRODUCT_DUMMY_PHOTO_URL
与替换图像相同。
答案 0 :(得分:2)
扩展@Estradiaz的评论,并在Vue自己的文档中提到:Reactivity in Depth,
Vue无法检测到属性的添加或删除。
您可能需要使用空数组初始化product.photosURLs
,或者需要使用Vue.set()
来在this.product.photosURLs
函数中为onClickSaveProductButton
赋值,像这样:
Vue.set(this.product, 'photosURLs', this.uploadedProductPhotosURLs);