Слоты с ограниченной областью видимости (scoped slots) позволяют передавать данные между слотом и родительским компонентом. Подобные слоты определяют шаблон, в который можно передавать данные из дочернего компонента. И эти данные ограничены слотом.
Для определения шаблона в родительском компоненте применяется какой-нибудь элемент, как правило, это элемент <template>
,
в котором устанавливается специальный атрибут slot-scope. Значение этого атрибута - название объекта с данными,
которые передаются от дочернего компонента.
Например, определим следующую веб-страницу:
<!DOCTYPE html> <html> <head> <title>Slots in Vue.js</title> <meta charset="utf-8" /> </head> <body> <div id="app"> <user> <template slot-scope="props"> <h3>Данные о пользователе</h3> <p>Имя: {{ props.username }}</p> <p>Имя: {{ props.userage }}</p> </template> </user> </div> <script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script> <script> Vue.component('user', { template: `<div class="user"> <slot username="Tom" userage="31"></slot> </div>` }); new Vue({ el: '#app' }); </script> </body> </html>
Для слота с ограниченной областью видимости здесь определен шаблон:
<template slot-scope="props"> <h3>Данные о пользователе</h3> <p>Имя: {{ props.username }}</p> <p>Имя: {{ props.userage }}</p> </template>
К примеру, дочерний компонент вывод некоторые данные о пользователе. И через элемент template эти данные будут выводиться в слот.
Для получения данные в элементе определен атрибут slot-scope="props"
. Props - это тот объект с данными, который передается от дочернего компонента.
Внутри шаблона мы можем обращаться через props к переданным данным.
Для определения данных в дочернем компоненте устанавливается элемент <slot>
с соответствующими атрибутами:
<div class="user"> <slot username="Tom" userage="31"></slot> </div>
Другой показательный пример представляет использование списков, где родительский компонент может определить шаблон для элемента списка:
<!DOCTYPE html> <html> <head> <title>Slots in Vue.js</title> <meta charset="utf-8" /> <style> .user{ font-size:14px; font-family: Verdana; padding:6px; } </style> </head> <body> <div id="app"> <userslist :users="users"> <li slot-scope="props" class="user"> {{ props.username }} </li> </userslist> </div> <script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script> <script> Vue.component('userslist', { props: ["users"], template: `<ul> <slot v-for="user in users" :username="user"></slot> </ul>` }); new Vue({ el: '#app', data:{ users: ['Tom', 'Sam', 'Bob'] } }); </script> </body> </html>
В данном случае компонент userslist получает извне список users. Для каждого элемента из этого списка создается свой элемент slot:
<slot v-for="user in users" :username="user"></slot>
Для слота определяется одно свойство - username.
В родительском компоненте определяется шаблон, в котором выводится значение свойсва username:
<li slot-scope="props" class="user"> {{ props.username }} </li>
Причем в данном случае родительский компонент сам определяет шаблон для элементов списка и правила их стилизации.