В этом видео мы с вами разберем, что такое slots в Vue.
Иногда нам необходимо прокинуть в компонент не переменную, а html код. Например представим, что нам нужно написать компонент alert, которым мы будем переиспользовать в разных местах приложени. И мы должны его реализовать так, чтобы было возможно прокидывать туда не только текст, но и html.
Давайте попробуем. У меня создан пустой проект webpack-simple с помощью vue-cli.
Давайте добавим Alert компонент.
Alert.vue
<template>
<div class='alert success'>
This is some success text
</div>
</template>
То есть тут у нас только div с двумя классами. Давайте добавим стилей.
Alert.vue
<style scoped>
.alert {
padding: 12px 20px;
border-radius: 5px;
border: 1px solid transparent;
font-size: 16px;
}
.success {
background-color: #dff0d8;
border-color: #d0e9c6;
color: #3c763d;
}
</style>
Мы также добавили scoped, чтобы наши стили в компоненте были уникальными. Теперь мы должны импортировать этот компонент в App.
App.vue
import alert from './Alert.vue'
...
export default {
components: {
alert
}
}
App.vue
<template>
<div>
<h1>Hello Vue!</h1>
<alert />
</div>
</template>
Если мы посмотрим в браузер, то у нас вывелся красивый зеленый алерт, который мы можем переиспользовать в разным местах приложения, так как его ширина всегда занимает весь контейнер.
Давайте теперь добавим возможно указывать текст алерта. Для этого используем props, как мы делали ранее.
Alert.vue
<div class='alert success'>
{{text}}
</div>
export default {
props: ['text']
}
Мы добавили props и теперь можем просто прокинуть текст снаружи.
App.vue
<alert text='This is our success message' />
Все работает, но что, если мы хотим передать html снаружи? Например, мы хотим, чтобы часть нашего текста была жирной. Для этого в Vue есть такое понятие, как slot. Мы можем написать текст внутри нашего компонента при вызове и он нам будет доступен для использования внутри.
Давайте попробуем
App.vue
<alert>
<b>This is</b> our success message
</alert>
Мы просто написали html внутри вызова компонента. Ничего больше. Теперь, чтобы получить этот html внутри компонента мы можем использовать специальный тег slot.
<div class='alert success'>
<slot />
</div>
Мы просто используем его, где нам нужно. Нам не нужны для этого props или что-то еще. Если мы посмотрим в браузер, то у нас отрендерился текст и часть этого текста выделена жирным.
Что насчет переменных? Что будет, если мы напишем внутри не текст а переменную? Должна ли она тогда быть определена внутри компонента или снаружи? Давайте перенесем наш текст в переменную.
App.vue
<alert>
<b>This is</b> {{message}}
</alert>
data () {
return {
message: 'our success message'
}
}
Если мы посмотрим в браузер, то все по прежнему работает. Это означает, что шаблон транспайлится до того, как прокидывается в компонент. То есть компонент получает чистый html после выполнения всей логики.
Что насчет стилей? Можем ли мы стайлить компонент снаружи?
App.vue
<style scoped>
...
b {
color: red;
}
</style>
Как мы видим, стили можно применять снаружи. Но мы можем эти стили перебить внутри компонента.
Alert.vue
<style scoped>
...
b {
color: blue;
}
</style>
Как мы видим, теперь наш жирный текст синего цвета. Что означает, что стили в компоненте всегда побеждают.
Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео.