我正在一个Vue组件中工作,当它包装好Clusterize.js (有一个vue-clusterize组件,但它只对v1.x起作用)时,我将发布它。我想要实现的是使用Vue快速呈现一个庞大的项目列表。我真的需要它做桌子。我试过用虚拟卷轴,但它的不支持表和性能不是那么好。所以我想试一试Clusterize.js。
由于我希望这个组件是高度可配置的,所以我决定您将能够为项目列表的每一行提供一个作用域槽,您将在其中接收该项目。问题是,当我试图在挂载组件之前将集群组件中的作用域槽分配给每一行时,它就无法工作。
这里有一些我的代码片段(它只是一个mvp)
clusterize.vue
模板
<div class="clusterize">
<table>
<thead>
<tr>
<th>Headers</th>
</tr>
</thead>
</table>
<div
ref="scroll"
class="clusterize-scroll">
<table>
<tbody
ref="content"
class="clusterize-content">
<tr class="clusterize-no-data">
<td>Loading...</td>
</tr>
</tbody>
</table>
</div>
脚本
import Vue from 'vue';
import Clusterize from 'clusterize.js';
export default {
name: 'Clusterize',
props: {
items: {
type: Array,
required: true,
},
},
data() {
return {
clusterize: null,
};
},
computed: {
rows() {
return this.items.map(item => '<tr><slot :item="1"/></tr>');
},
},
watch: {
rows() {
this.clusterize.update(this.rows);
},
},
mounted() {
const scrollElem = this.$refs.scroll;
const contentElem = this.$refs.content;
this.clusterize = new Clusterize({
rows: this.rows,
scrollElem,
contentElem,
});
this.clusterize.html = (template) => {
contentElem.innerHTML = template;
const instance = new Vue({ el: contentElem });
instance.$slots = this.$slots;
instance.$scopedSlots = this.$scopedSlots;
instance.$mount();
console.log(instance.$scopedSlots); // empty
console.log(instance.$slots) // not empty
};
},
};component.vue
<clusterize :items="test">
<template slot-scope="props">
item
</template>
</clusterize>问题是,如果它不使用作用域槽,它就能完美地工作,但是我真的需要使用它们,否则组件就没有任何意义了。
我会感谢任何帮助或建议。提前谢谢你。
发布于 2018-08-09 21:48:36
这个问题应该是由多次将不同的Vue实例挂载到同一个el引起的(请查看第二个演示,,您不应该将多个实例安装到相同的元素,以下实例不会挂载,因为元素已经被第一个实例“阻塞”了)。
我的解决方案:在空气中创建Vue实例(不绑定到el),然后以vm.$el作为输出。
--请查看下面的简单演示,
Vue.config.productionTip = false
Vue.component('clusterize', {
template: `<div class="clusterize">
<table>
<thead>
<tr>
<th>Headers</th>
</tr>
</thead>
</table>
<div
ref="scroll"
class="clusterize-scroll">
<table>
<tbody
ref="content"
id="clusterize-id"
class="clusterize-content">
<tr class="clusterize-no-data">
<td>Loading...</td>
</tr>
</tbody>
</table>
</div></div>`,
props: {
items: {
type: Array,
required: true,
},
},
data() {
return {
clusterize: null,
clusterVueInstance: null
};
},
computed: {
rows() {
return this.items.map(item => {
return '<tr><td><span>' +item+'</span><slot :item="1"/></td></tr>'
});
},
},
watch: {
rows() {
this.clusterize.update(this.rows);
},
},
mounted() {
const scrollElem = this.$refs.scroll;
const contentElem = this.$refs.content;
this.clusterize = new Clusterize({
rows: this.rows,
scrollElem,
contentElem,
});
this.clusterize.html = (template) => {
this.clusterize.content_elem.innerHTML = template;
if(this.clusterVueInstance) {
this.clusterVueInstance.$destroy()
this.clusterVueInstance = null
}
this.clusterVueInstance = new Vue({ template: '<tbody>'+template+'</tbody>' })
//or use Vue.extend()
this.clusterVueInstance.$slots = this.$slots
this.clusterVueInstance.$scopedSlots = this.$scopedSlots
this.clusterVueInstance.$mount()
this.clusterize.content_elem.innerHTML = this.clusterVueInstance.$el.innerHTML
//console.log(this.clusterVueInstance.$scopedSlots); // empty
//console.log(this.clusterVueInstance.$slots) // not empty*/
};
}
})
app = new Vue({
el: "#app",
data() {
return {
test: ['Puss In Boots', 'test 1', 'test2'],
index: 0
}
},
mounted: function () {
//this.test = ['Puss In Boots', 'test 1', 'test2']
},
methods: {
addItem: function () {
this.test.push(`test ` + this.index++)
}
}
})<link href="https://cdn.bootcss.com/clusterize.js/0.18.0/clusterize.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<script src="https://cdn.bootcss.com/clusterize.js/0.18.0/clusterize.min.js"></script>
<div id="app">
<button @click="addItem()">
Add Item
</button>
<clusterize :items="test">
<template slot-scope="props">
item: {{props.item}}
</template>
</clusterize>
</div>
--请查看下面的演示:为同一个el创建了多个Vue实例,但是Vue总是使用第一个实例来呈现(我在Vue指南中找不到任何有用的语句,可能是从Vue Github的源代码中找到的,我们可以找到逻辑。如果有人知道,请随时编辑我的答案或添加评论)。
Vue.config.productionTip = false
app1 = new Vue({
el: '#app',
data () {
return {
test: 'test 1'
}
},
mounted(){
console.log('app1', this.test)
}
})
app2 = new Vue({
el: '#app',
data () {
return {
test: 'test 2'
}
},
mounted(){
console.log('app2', this.test)
}
})
//app1.$data.test = 3
//app1.$mount() //manual mount
app2.$data.test = 4
app2.$mount() //manual mount<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<script src="https://cdn.bootcss.com/clusterize.js/0.18.0/clusterize.min.js"></script>
<div id="app">
<a>{{test}}</a>
</div>
https://stackoverflow.com/questions/51771893
复制相似问题