当 Vue.js 发生变化时,如何定位列表中的所有项目?
How do I target all items in a list, when a change occurs in Vue.js?
我正在构建一个使用 Vue 来支持大多数 UI 的站点。主要组件是一个视频列表,只要匹配特定 URL 模式就会更新。
主要 (video-list
) 组件大致如下所示:
let VideoList = Vue.component( 'video-list', {
data: () => ({ singlePost: '' }),
props: ['posts', 'categorySlug'],
template: `
<div>
<transition-group tag="ul">
<li v-for="(post, index) in filterPostsByCategory( posts )">
<div @click.prevent="showPost( post )">
<img :src="post.video_cover" />
/* ... */
</div>
</li>
</transition-group>
</div>`,
methods: {
orderPostsInCategory: function ( inputArray, currentCategory ) {
let outputArray = [];
for (let i = 0; i < inputArray.length; i++) {
let currentCategoryObj = inputArray[i].video_categories.find( (category) => {
return category.slug === currentCategory;
});
let positionInCategory = currentCategoryObj.category_post_order;
outputArray[positionInCategory] = inputArray[i];
}
return outputArray;
},
filterPostsByCategory: function ( posts ) {
let categorySlug = this.categorySlug,
filteredPosts = posts.filter( (post) => {
return post.video_categories.some( (category) => {
return category.slug === categorySlug;
})
});
return this.orderPostsInCategory( filteredPosts, categorySlug );
}
}
});
filterPostsByCategory()
方法根据以下路线在各种可能的类别之间切换,并立即更新列表:
let router = new VueRouter({
mode: 'history',
linkActiveClass: 'active',
routes: [
{ path: '/', component: VideoList, props: {categorySlug: 'home-page'} },
{ path: '/category/:categorySlug', component: VideoList, props: true }
]
});
我遇到的困难是以我喜欢的方式转换列表。 Ideally, when new category is selected all currently visible list items would fade out and the new list items would then fade in. I've looked at the vue transitions documentation, but haven't been able to get the effect I'm之后。
问题是有些项目有多个类别,在这些类别之间切换时,这些项目永远不会受到我尝试应用的任何转换的影响(我假设是因为 Vue 只是想提高效率并更新为尽可能少的节点)。也有可能两个或多个类别包含完全相同的列表项,在这些情况下,enter 和 leave 方法似乎根本不会触发。
所以问题是,当上面的路由模式匹配时,什么是确保我可以定位所有当前项目(无论它们在路由更改后是否仍然可见)的好方法?
您是否注意到 documentation 中的特殊 key
属性?
Vue.js 真正专注于性能,因此,当您修改与 v-for
一起使用的列表时,vue 会尝试更新尽可能少的 DOM 节点。有时它只更新节点的文本内容而不是删除整个节点然后附加一个新创建的节点。使用 :key
你告诉 vue 这个节点与给定的 key/id 具体相关,你强制 vue 在 list/array 被修改时完全更新 DOM 结果密钥已更改。在您的情况下,将 key
属性绑定到与 post 和类别过滤器本身相关的某些信息是合适的,这样无论何时修改列表或更改类别,都可以重新呈现整个列表并且因此在所有项目上应用动画:
<li v-for="(post, index) in filterPostsByCategory( posts )" :key="post.id + categorySlug">
<div @click.prevent="showPost( post )">
<img :src="post.video_cover" />
/* ... */
</div>
</li>
我正在构建一个使用 Vue 来支持大多数 UI 的站点。主要组件是一个视频列表,只要匹配特定 URL 模式就会更新。
主要 (video-list
) 组件大致如下所示:
let VideoList = Vue.component( 'video-list', {
data: () => ({ singlePost: '' }),
props: ['posts', 'categorySlug'],
template: `
<div>
<transition-group tag="ul">
<li v-for="(post, index) in filterPostsByCategory( posts )">
<div @click.prevent="showPost( post )">
<img :src="post.video_cover" />
/* ... */
</div>
</li>
</transition-group>
</div>`,
methods: {
orderPostsInCategory: function ( inputArray, currentCategory ) {
let outputArray = [];
for (let i = 0; i < inputArray.length; i++) {
let currentCategoryObj = inputArray[i].video_categories.find( (category) => {
return category.slug === currentCategory;
});
let positionInCategory = currentCategoryObj.category_post_order;
outputArray[positionInCategory] = inputArray[i];
}
return outputArray;
},
filterPostsByCategory: function ( posts ) {
let categorySlug = this.categorySlug,
filteredPosts = posts.filter( (post) => {
return post.video_categories.some( (category) => {
return category.slug === categorySlug;
})
});
return this.orderPostsInCategory( filteredPosts, categorySlug );
}
}
});
filterPostsByCategory()
方法根据以下路线在各种可能的类别之间切换,并立即更新列表:
let router = new VueRouter({
mode: 'history',
linkActiveClass: 'active',
routes: [
{ path: '/', component: VideoList, props: {categorySlug: 'home-page'} },
{ path: '/category/:categorySlug', component: VideoList, props: true }
]
});
我遇到的困难是以我喜欢的方式转换列表。 Ideally, when new category is selected all currently visible list items would fade out and the new list items would then fade in. I've looked at the vue transitions documentation, but haven't been able to get the effect I'm之后。
问题是有些项目有多个类别,在这些类别之间切换时,这些项目永远不会受到我尝试应用的任何转换的影响(我假设是因为 Vue 只是想提高效率并更新为尽可能少的节点)。也有可能两个或多个类别包含完全相同的列表项,在这些情况下,enter 和 leave 方法似乎根本不会触发。
所以问题是,当上面的路由模式匹配时,什么是确保我可以定位所有当前项目(无论它们在路由更改后是否仍然可见)的好方法?
您是否注意到 documentation 中的特殊 key
属性?
Vue.js 真正专注于性能,因此,当您修改与 v-for
一起使用的列表时,vue 会尝试更新尽可能少的 DOM 节点。有时它只更新节点的文本内容而不是删除整个节点然后附加一个新创建的节点。使用 :key
你告诉 vue 这个节点与给定的 key/id 具体相关,你强制 vue 在 list/array 被修改时完全更新 DOM 结果密钥已更改。在您的情况下,将 key
属性绑定到与 post 和类别过滤器本身相关的某些信息是合适的,这样无论何时修改列表或更改类别,都可以重新呈现整个列表并且因此在所有项目上应用动画:
<li v-for="(post, index) in filterPostsByCategory( posts )" :key="post.id + categorySlug">
<div @click.prevent="showPost( post )">
<img :src="post.video_cover" />
/* ... */
</div>
</li>