Vue.js $scopedSlots가 Vue 인스턴스에서 작동하지 않음
Clusterize.js(vue-clusterize 구성 요소가 있지만 v1.x에서만 작동)가 완료되면 게시할 Vue 구성 요소에서 작업하고 있습니다.제가 원하는 것은 Vue를 사용하여 방대한 아이템 목록을 매우 빠르게 렌더링하는 것입니다.식탁에 놓을 때 필요해요.vue-virtual-scroll로 시도했지만 테이블을 지원하지 않고 성능도 좋지 않습니다.그래서 Clusterize.js를 사용해보고 싶었습니다.
이 컴포넌트는 설정성이 높으면 좋기 때문에 아이템 리스트의 각 행에 스코프 슬롯을 제공할 수 있다고 판단했습니다.컴포넌트를 마운트하기 전에 클러스터화 컴포넌트의 스코프 슬롯을 각 행에 할당하려고 하면 동작하지 않습니다.
여기 내 코드의 일부(MVP일 뿐)가 있습니다).
클러스터화하다표시하다
템플릿
<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
};
},
};
요소.표시하다
<clusterize :items="test">
<template slot-scope="props">
item
</template>
</clusterize>
문제는 스코프 슬롯을 사용하지 않으면 완벽하게 동작하지만, 꼭 사용해야 합니다.그렇지 않으면 컴포넌트에 감각이 없습니다.
어떤 도움이나 조언이라도 주시면 감사하겠습니다.잘 부탁드립니다.
이 문제는 다른 Vue 인스턴스를 동일한 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>
아래 데모를 참조하십시오. 동일한 Vue 인스턴스를 여러 개 생성했습니다.el
그러나 Vue는 항상 첫 번째 인스턴스를 사용하여 렌더링합니다(Vue Guide에서는 유용한 문장을 찾을 수 없습니다.아마 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>
언급URL : https://stackoverflow.com/questions/51771893/vue-js-scopedslots-dont-work-for-vue-instance
'source' 카테고리의 다른 글
Python 인터프리터 내에서 파일을 실행하는 방법은 무엇입니까? (0) | 2023.01.19 |
---|---|
현재 디렉터리 및 파일 디렉터리 찾기 (0) | 2023.01.19 |
MySQL Error 1111 - 창 함수를 중첩할 때 그룹 함수가 잘못 사용됨 (0) | 2023.01.19 |
Symfony2 번들에 상대적인 파일 접근 (0) | 2023.01.19 |
팬더 DataFrame의 컬럼을 여러 줄로 네스트(폭발)하는 방법 (0) | 2023.01.19 |