Javascript 从v-bind:style中调用函数不会';t触发对视图的更新
我有一个图像列表(像一个画廊)。图片上的长按(我使用的是Nativescript vue)将更改图像的样式,并使其显示为“选中”。这是图像:Javascript 从v-bind:style中调用函数不会';t触发对视图的更新,javascript,vue.js,nativescript,Javascript,Vue.js,Nativescript,我有一个图像列表(像一个画廊)。图片上的长按(我使用的是Nativescript vue)将更改图像的样式,并使其显示为“选中”。这是图像: <ListView layout="grid" ref="backedupImages" for="image in sortedBackedupImages"> <v-template> <ImageComponent v-bind:style="{backgroundColo
<ListView layout="grid" ref="backedupImages" for="image in sortedBackedupImages">
<v-template>
<ImageComponent
v-bind:style="{backgroundColor:isSelected(image.identifier) ? 'cyan' : 'white'}"
:onLongPress="()=>{onLongPress(image.identifier)}"
:onShortPress="()=>{onShortPress(image.identifier)}"
:image="image"
></ImageComponent>
</v-template>
</ListView>
这是onLongPress方法,用于切换图像选择状态:
onLongPress(identifier) {
if(this.selectedImages.includes(identifier)){
const index = this.selectedImages.indexOf(identifier);
this.$delete(this.selectedImages,index);
}else{
const index = this.selectedImages.length;
this.$set(this.selectedImages,index,identifier);
}
},
数组操作似乎有效,但我看不到任何反应。有什么问题吗?在Vue中是否有更好的方法?我认为我不能使用computed属性,因为我需要将一个参数传递给“计算”。您遇到的问题是
ListView
上的v-for
循环将无法按预期运行。此问题在以下章节中描述:
不会像使用v-for
循环时所期望的那样循环列表项。相反,
只创建必要的视图,以显示屏幕上当前可见的项目,并在滚动时重用屏幕外的视图。这一概念称为视图回收,通常用于移动应用程序以提高性能
这一点很重要,因为您不能依赖v-template
中附加的事件侦听器。相反,您需要使用itemTap
事件,该事件包含点击项目的索引和列表中的实际项目
MTAP(事件){console.log(event.index)
console.log(event.item)
}
我确实检查了它,因此使用了$set和$delete方法。它现在不应该工作吗?编辑:我尝试将这一行添加到onLongPress函数中-没有更改。啊,我的错误,我看到
$delete
应该是反应式的。你检查过控制台有没有错误?我用tns调试android来愚弄正在发生的事情,它看起来很好。此外,我还使用vue开发工具查看状态的变化,看起来也不错。我要提到的是,如果我向下滚动并再次向上滚动(ListView组件是Nativescript的虚拟化组件),一切都会正常工作。但是没有滚动,就没有反应。您必须提到这是Nativescript,而不是纯Vue.js。这大大改变了情况。请阅读下面这篇文章。它准确地描述了您的问题,这是使用v-for
在ListView
中对v-template
的限制。这是一个性能优化功能。好吧,这似乎给我想要的功能设置了一个障碍,因为itemTap事件似乎没有区分短点击和长点击……你知道吗?老实说,我怀疑这是否真的是问题所在,因为我“以正常方式”检测事件没有问题。@sheff2k1在同一文档中提到了refresh()
方法。这可以很好地解决问题:)如果这样做有效,请让我知道,我会相应地更新我的答案以反映这一点。可怕的文档,我甚至不知道如何使用这种刷新方法。我该怎么称呼它呢DOk,一个重要的更新:通过完全删除整个“selectedImages”数组,并将一个“selected”属性附加到image对象,我成功地实现了这一点。问题是,我正在修改一个对象上的属性,该属性作为道具从父对象接收。它现在可以工作了,但这是bug的来源吗?在这种情况下,永远都有“一个真理的来源”。Vue呢?你有时会在孩子体内修改道具吗?你不应该修改道具。相反,查看
道具的任何更改,并在更改时创建一个副本以存储在本地数据中。这样可以确保父级更改仍然可以覆盖子组件的数据,但子组件的更改仅限于其自己的范围。
onLongPress(identifier) {
if(this.selectedImages.includes(identifier)){
const index = this.selectedImages.indexOf(identifier);
this.$delete(this.selectedImages,index);
}else{
const index = this.selectedImages.length;
this.$set(this.selectedImages,index,identifier);
}
},