Я думаю, что ваша проблема связана с неправильным пониманием того, как <slot>
изначально работает в VueJS. Слоты используются для переплетения контента из родительского компонента-потребителя в дочерний компонент. Смотри это как HTML-эквивалент v-bind:prop
. Когда вы используете v-bind:prop
для компонента, вы фактически передаете данные в дочерний компонент. Это так же, как слоты.
Без какого-либо конкретного примера или кода с вашей стороны, этот ответ будет в лучшем случае просто угадать. Я предполагаю, что ваш родительский компонент сам является приложением VueJS, а дочерний компонент содержит элемент <slot>
.
<!-- Parent template -->
<div id="app">
<custom-component>
<!-- content here -->
</custom-component>
</div>
<!-- Custom component template -->
<template>
<slot></slot>
</template>
В этом случае приложение имеет основное состояние по умолчанию, когда оно передает статический HTML-код дочернему компоненту:
<!-- Parent template -->
<div id="app">
<custom-component>
<!-- Markup to be interweaved into custom component -->
<p>Lorem ipsum dolor sit amet.</p>
</custom-component>
</div>
<!-- Custom component template -->
<template>
<slot></slot>
</template>
Затем, когда происходит событие, вы хотите заменить эту разметку основного состояния новой входящей разметкой. Это можно сделать, сохранив входящий HTML-код в атрибуте data
и просто используя v-html
для его условной визуализации. Допустим, мы хотим сохранить входящую разметку в приложении vm.$data.customHTML
:
data: {
customHTML: null
}
Тогда ваш шаблон будет выглядеть так:
<!-- Parent template -->
<div id="app">
<custom-component>
<div v-if="customHTML" v-html="customHTML"></div>
<div v-else>
<p>Lorem ipsum dolor sit amet.</p>
</div>
</custom-component>
</div>
<!-- Custom component template -->
<template>
<slot></slot>
</template>
Обратите внимание, что в отличие от кода, который вы пробовали, различия заключаются в следующем:
- Именно родительский компонент (т.е. потребляющий компонент ) отвечает за определение того, какую разметку передать дочернему элементу
- Дочерний компонент выглядит как тупой , поскольку он получает: он просто получает разметку и отображает ее в элементе
<slot>
См. Подтверждение концепции ниже:
var customComponent = Vue.component('custom-component', {
template: '#custom-component-template'
});
new Vue({
el: '#app',
data: {
customHTML: null
},
components: {
customComponent: customComponent
},
methods: {
updateSlot: function() {
this.customHTML = '<p>Foo bar baz</p>';
}
}
});
.custom-component {
background-color: yellow;
border: 1px solid #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
<h1>I am the app</h1>
<button type="button" @click="updateSlot">Click me to update slot content</button>
<custom-component>
<div v-if="customHTML" v-html="customHTML">
</div>
<div v-else>
<p>Lorem ipsum dolor sit amet.</p>
</div>
</custom-component>
</div>
<!-- custom-component template -->
<script type="text/template" id="custom-component-template">
<div class="custom-component">
<h2>I am a custom component</h2>
<!-- slot receives markup set in <custom-component> -->
<slot></slot>
</div>
</script>