admin管理员组文章数量:1022552
I'm working in a Vue ponent that I'll publish when it's finished that wraps Clusterize.js (there is a vue-clusterize ponent but it only works for v1.x). What I want to achieve is to render a huge list of items pretty fast using Vue. I actually need it for a table. I tried with vue-virtual-scroll but it doesn't support tables and the performance is not that good. So I wanted to try with Clusterize.js.
Because I want this ponent to be highly configurable I decided that you will be able to provide a scoped slot for each row of the items list where you will receive the item. The problem is when I try to assign the scoped slot from the clusterize ponets to each row before mounting the ponent it doesn't work.
Here you have some snippets of my code (it is just a mvp)
clusterize.vue
Template
<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>
Script
import Vue from 'vue';
import Clusterize from 'clusterize.js';
export default {
name: 'Clusterize',
props: {
items: {
type: Array,
required: true,
},
},
data() {
return {
clusterize: null,
};
},
puted: {
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
};
},
};
ponent.vue
<clusterize :items="test">
<template slot-scope="props">
item
</template>
</clusterize>
The thing is that if it don't use a scoped slot it works perfectly but I really need to use them otherwise the ponent doesn't have any sense.
I'll appreciate any help or advice. Thank you so much in advance.
I'm working in a Vue ponent that I'll publish when it's finished that wraps Clusterize.js (there is a vue-clusterize ponent but it only works for v1.x). What I want to achieve is to render a huge list of items pretty fast using Vue. I actually need it for a table. I tried with vue-virtual-scroll but it doesn't support tables and the performance is not that good. So I wanted to try with Clusterize.js.
Because I want this ponent to be highly configurable I decided that you will be able to provide a scoped slot for each row of the items list where you will receive the item. The problem is when I try to assign the scoped slot from the clusterize ponets to each row before mounting the ponent it doesn't work.
Here you have some snippets of my code (it is just a mvp)
clusterize.vue
Template
<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>
Script
import Vue from 'vue';
import Clusterize from 'clusterize.js';
export default {
name: 'Clusterize',
props: {
items: {
type: Array,
required: true,
},
},
data() {
return {
clusterize: null,
};
},
puted: {
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
};
},
};
ponent.vue
<clusterize :items="test">
<template slot-scope="props">
item
</template>
</clusterize>
The thing is that if it don't use a scoped slot it works perfectly but I really need to use them otherwise the ponent doesn't have any sense.
I'll appreciate any help or advice. Thank you so much in advance.
Share Improve this question asked Aug 9, 2018 at 16:24 andreszandresz 531 silver badge5 bronze badges 1- 1 Can you please provide a reproduction (jsfiddle)? – Marlon Barcarol Commented Aug 9, 2018 at 16:55
1 Answer
Reset to default 2The issue should be caused by mount different Vue instance to same el
multiple times (please look into the second demo, you shouldn't mount multiple instances to same element, the following instances will not mount since the element is already “blocked” by first instance).
My solution: create Vue instance (doesn't bind to el
) in the air then take vm.$el
as the output.
Please look into below simple demo,
Vue.config.productionTip = false
Vue.ponent('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
};
},
puted: {
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./clusterize.js/0.18.0/clusterize.min.css" rel="stylesheet"/>
<script src="https://unpkg./[email protected]/dist/vue.js"></script>
<script src="https://cdn.bootcss./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>
Please look into below demo: created multiple Vue instance to same el
, but Vue always uses first instance to render (I can't find any useful statement at Vue Guide, probably from the source codes from Vue Github we can find out the logic. If someone knows, please feel free to edit my answer or add a ment).
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./[email protected]/dist/vue.js"></script>
<script src="https://cdn.bootcss./clusterize.js/0.18.0/clusterize.min.js"></script>
<div id="app">
<a>{{test}}</a>
</div>
I'm working in a Vue ponent that I'll publish when it's finished that wraps Clusterize.js (there is a vue-clusterize ponent but it only works for v1.x). What I want to achieve is to render a huge list of items pretty fast using Vue. I actually need it for a table. I tried with vue-virtual-scroll but it doesn't support tables and the performance is not that good. So I wanted to try with Clusterize.js.
Because I want this ponent to be highly configurable I decided that you will be able to provide a scoped slot for each row of the items list where you will receive the item. The problem is when I try to assign the scoped slot from the clusterize ponets to each row before mounting the ponent it doesn't work.
Here you have some snippets of my code (it is just a mvp)
clusterize.vue
Template
<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>
Script
import Vue from 'vue';
import Clusterize from 'clusterize.js';
export default {
name: 'Clusterize',
props: {
items: {
type: Array,
required: true,
},
},
data() {
return {
clusterize: null,
};
},
puted: {
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
};
},
};
ponent.vue
<clusterize :items="test">
<template slot-scope="props">
item
</template>
</clusterize>
The thing is that if it don't use a scoped slot it works perfectly but I really need to use them otherwise the ponent doesn't have any sense.
I'll appreciate any help or advice. Thank you so much in advance.
I'm working in a Vue ponent that I'll publish when it's finished that wraps Clusterize.js (there is a vue-clusterize ponent but it only works for v1.x). What I want to achieve is to render a huge list of items pretty fast using Vue. I actually need it for a table. I tried with vue-virtual-scroll but it doesn't support tables and the performance is not that good. So I wanted to try with Clusterize.js.
Because I want this ponent to be highly configurable I decided that you will be able to provide a scoped slot for each row of the items list where you will receive the item. The problem is when I try to assign the scoped slot from the clusterize ponets to each row before mounting the ponent it doesn't work.
Here you have some snippets of my code (it is just a mvp)
clusterize.vue
Template
<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>
Script
import Vue from 'vue';
import Clusterize from 'clusterize.js';
export default {
name: 'Clusterize',
props: {
items: {
type: Array,
required: true,
},
},
data() {
return {
clusterize: null,
};
},
puted: {
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
};
},
};
ponent.vue
<clusterize :items="test">
<template slot-scope="props">
item
</template>
</clusterize>
The thing is that if it don't use a scoped slot it works perfectly but I really need to use them otherwise the ponent doesn't have any sense.
I'll appreciate any help or advice. Thank you so much in advance.
Share Improve this question asked Aug 9, 2018 at 16:24 andreszandresz 531 silver badge5 bronze badges 1- 1 Can you please provide a reproduction (jsfiddle)? – Marlon Barcarol Commented Aug 9, 2018 at 16:55
1 Answer
Reset to default 2The issue should be caused by mount different Vue instance to same el
multiple times (please look into the second demo, you shouldn't mount multiple instances to same element, the following instances will not mount since the element is already “blocked” by first instance).
My solution: create Vue instance (doesn't bind to el
) in the air then take vm.$el
as the output.
Please look into below simple demo,
Vue.config.productionTip = false
Vue.ponent('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
};
},
puted: {
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./clusterize.js/0.18.0/clusterize.min.css" rel="stylesheet"/>
<script src="https://unpkg./[email protected]/dist/vue.js"></script>
<script src="https://cdn.bootcss./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>
Please look into below demo: created multiple Vue instance to same el
, but Vue always uses first instance to render (I can't find any useful statement at Vue Guide, probably from the source codes from Vue Github we can find out the logic. If someone knows, please feel free to edit my answer or add a ment).
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./[email protected]/dist/vue.js"></script>
<script src="https://cdn.bootcss./clusterize.js/0.18.0/clusterize.min.js"></script>
<div id="app">
<a>{{test}}</a>
</div>
本文标签: javascriptVuejs scopedSlots don39t work for Vue instanceStack Overflow
版权声明:本文标题:javascript - Vue.js $scopedSlots don't work for Vue instance - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745554397a2155784.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论