在将绑定(bind)项对象移动到不同的数据数组时,我试图让组件保持事件状态。因为它被移动了,所以默认的 keep-alive 标签不起作用。
当我的应用程序中的动态组件使用外部库时,我需要它来缩短加载时间。
简化示例: ( https://jsfiddle.net/eywraw8t/24419/ )
HTML:
<div id="app">
<div v-for="list in lists">
<h1>{{ list.title }}</h1>
<ul>
<draggable v-model="list.items" :options="{group: 'list-items'}">
<list-item
v-for="item in list.items"
:key="item.key"
:content="item.content">
</list-item>
</draggable>
</ul>
</div>
</div>
JS:
Vue.component('list-item', {
props: {
content: {
required: true
}
},
mounted () {
document.body.insertAdjacentHTML('beforeend', 'Mounted! ');
},
template: '<li>{{ content }}</li>'
})
new Vue({
el: "#app",
data: {
lists: [
{
title: 'List 1',
items: [
{ key: 'item1', content: 'Item 1' },
{ key: 'item2', content: 'Item 2' },
{ key: 'item3', content: 'Item 3' }
]
},
{
title: 'List 2',
items: [
{ key: 'item4', content: 'Item 4' },
{ key: 'item5', content: 'Item 5' },
{ key: 'item6', content: 'Item 6' }
]
}
]
}
})
最佳答案
如果问题只是缓存昂贵的 html 构建之一,您可以通过从模板中删除 list-item
组件并在 app.mounted( )
。
这在您的真实场景中的效果取决于 item.content
的性质及其生命周期。
console.clear()
const ListItem = Vue.component('list-item', {
props: {
content: {
required: true
}
},
mounted () {
document.body.insertAdjacentHTML('beforeend', 'Mounted! ');
},
template: '<li>{{ content }}</li>'
})
new Vue({
el: "#app",
methods: {
getHtml(content) {
const li = new ListItem({propsData: {content}});
li.$mount()
return li.$el.outerHTML
}
},
mounted () {
this.lists.forEach(list => {
list.items.forEach(item => {
const cacheHtml = this.getHtml(item.content)
Vue.set( item, 'cacheHtml', cacheHtml )
})
})
},
data: {
lists: [
{
title: 'List 1',
items: [
{ key: 'item1', content: 'Item 1' },
{ key: 'item2', content: 'Item 2' },
{ key: 'item3', content: 'Item 3' }
]
},
{
title: 'List 2',
items: [
{ key: 'item4', content: 'Item 4' },
{ key: 'item5', content: 'Item 5' },
{ key: 'item6', content: 'Item 6' }
]
}
]
}
})
ul {
margin-bottom: 20px;
}
li:hover {
color: blue;
cursor: move;
}
h1 {
font-size: 20px;
font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.6.0/Sortable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/15.0.0/vuedraggable.min.js"></script>
<div id="app">
<div v-for="list in lists">
<h1>{{ list.title }}</h1>
<ul>
<draggable v-model="list.items" :options="{group: 'list-items'}">
<div v-for="item in list.items" :key="item.key">
<li v-html="item.cacheHtml"></li>
</div>
</draggable>
</ul>
</div>
</div>
react 性item.content
要在 item.content
更改时保持响应,您需要更多代码。
- 将
item.content
的副本添加到缓存 - 添加一个方法,在内容发生变化时通过刷新获取缓存的 html。
(您可以使用参数化计算属性更优雅地执行此操作)。
为了模拟 item.content 的变化,我在 mounted() 中添加了一个 setTimeout。
console.clear()
const ListItem = Vue.component('list-item', {
props: {
content: {
required: true
}
},
mounted () {
document.body.insertAdjacentHTML('beforeend', 'Mounted! ');
},
template: '<li>{{ content }}</li>'
})
new Vue({
el: "#app",
methods: {
getHtml(content) {
const li = new ListItem({
propsData: { content }
});
li.$mount()
return li.$el.outerHTML
},
cacheHtml(item) {
if (item.cache && item.cache.content === item.content) {
return item.cache.html
} else {
const html = this.getHtml(item.content)
const cache = {content: item.content, html}
Vue.set(item, 'cache', cache)
}
}
},
mounted () {
this.lists.forEach(list => {
list.items.forEach(item => {
this.cacheHtml(item)
})
})
setTimeout(() =>
Vue.set( this.lists[0].items[0], 'content', 'changed' )
,2000)
},
data: {
lists: [
{
title: 'List 1',
items: [
{ key: 'item1', content: 'Item 1' },
{ key: 'item2', content: 'Item 2' },
{ key: 'item3', content: 'Item 3' }
]
},
{
title: 'List 2',
items: [
{ key: 'item4', content: 'Item 4' },
{ key: 'item5', content: 'Item 5' },
{ key: 'item6', content: 'Item 6' }
]
}
]
}
})
ul {
margin-bottom: 20px;
}
li:hover {
color: blue;
cursor: move;
}
h1 {
font-size: 20px;
font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.6.0/Sortable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/15.0.0/vuedraggable.min.js"></script>
<div id="app">
<div v-for="list in lists">
<h1>{{ list.title }}</h1>
<ul>
<draggable v-model="list.items" :options="{group: 'list-items'}">
<div v-for="item in list.items" :key="item.key">
<li v-html="cacheHtml(item)"></li>
</div>
</draggable>
</ul>
</div>
</div>
关于javascript - 移动到其他数组时 Vue 保持事件组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49732777/