Vue.js v-слот, который вам нужно знать (перевод)

Vue.js

Интервьюер: Расскажите о роли v-slot?

Подумайте минуту.

В этой статье предполагается, что у вас есть определенное понимание основ компонентов, если вы не знакомы с этим, пожалуйста,читать.

отvue@2.6.xДля начала Vue представил совершенно новый синтаксис для именованных слотов и слотов с областью действия, главный герой, о котором мы поговорим сегодня:v-slotинструкция. Цель состоит в том, чтобы унифицироватьslotиscope-slotсинтаксис, чтобы сделать код более стандартизированным и понятным. Поскольку имеется новая синтаксическая верхняя позиция, очевидно, чтоslotиscope-slotтакже будет вvue@3.0.xПопрощайтесь с нами полностью. и изvue@2.6.0Для начала чиновник рекомендует использоватьv-slotзаменить два последних.

Давайте начнем немного. Написание ограничено, пожалуйста, оставьте сообщение, чтобы исправить неточности!

именованный слот

Устарело в версии 2.6.0+

Ранее мы использовали именованные слоты для настройки содержимого шаблона, например, гипотетического<base-layout>Шаблон компонента выглядит следующим образом:

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

Предоставляя контент в именованные слоты, мы можем<template>использовать на элементахslotхарактеристика:

<base-layout>
  <template slot="header">
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <template slot="footer">
    <p>Here's some contact info</p>
  </template>
</base-layout>

Или используйте его непосредственно на обычном элементе:

<base-layout>
  <h1 slot="header">Here might be a page title</h1>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <p slot="footer">Here's some contact info</p>
</base-layout>

Визуализированный HTML для обоих приведенных выше примеров будет таким:

<div class="container">
  <header>
    <h1>Here might be a page title</h1>
  </header>
  <main>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </main>
  <footer>
    <p>Here's some contact info</p>
  </footer>
</div>

мы можем использоватьv-slotКоманда переписывает каштан выше:

<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

Это так просто, имя слота теперь передается черезv-slot:slotNameиспользуйте эту форму.

Tips:без имени<slot>содержит"default"название

Например, слот по умолчанию выше, если вы хотите отобразить вызов, будет:

<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <template v-slot:default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

В любом случае приведенный выше код выведет следующий код:

<div class="container">
  <header>
    <h1>Here might be a page title</h1>
  </header>
  <main>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </main>
  <footer>
    <p>Here's some contact info</p>
  </footer>
</div>

Пожалуйста, обрати внимание,v-slotможно добавить только в<template>или на пользовательских компонентах, в отличие от устаревшего свойства слота

слот с прицелом

Устарело в версии 2.6.0+

Иногда мы хотим получить доступ к некоторым данным, доступным внутри дочернего компонента в родительском компоненте. Например, предположим, что есть шаблон<current-user>Компоненты:

<span>
  <slot>{{ user.lastName }}</slot>
</span>

Мы можем захотеть заменить фамилию в слоте на имя пользователя, поэтому пишем:

<current-user>
  {{ user.firstName }}
</current-user>

К сожалению, приведенный выше код не работает так, как вы ожидаете, потому что среда области текущего кода находится в родительском компоненте, поэтому он не может получить к ней доступ.<current-user>внутренние данные.

Чтобы решить это, мы можем<current-user>Внутренний<slot>Динамически привязать один к элементуuserСвойства объекта:

<span>
  <!-- 完整 v-bind:user 下面是简写形式 -->
  <slot :user="user">
    {{ user.lastName }}
  </slot>
</span>

связываются с<slot>Атрибуты элементов, которые мы называемslot props. Теперь в родительской области мы можем передатьslot-scopeпосещатьuserДанные:

<current-user>
  <template slot-scope="slotProp">
    {{ slotProp.user.firstName }}
  </template>
</current-user>

Так же мы используемv-slotРефакторинг приведенного выше кода:

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>

или прямо на<current-user>по написанию:

<!-- 省略默认插槽名字 -->
<current-user v-slot="slotProp">
  {{ slotProp.user.firstName }}
</current-user>

<!-- 显示调用默认插槽名字 -->
<current-user v-slot:default="slotProp">
  {{ slotProp.user.firstName }}
</current-user>

В этом каштане мы выбираемslotPropкак нашslot propsимя, но вы можете использовать любое имя, которое вам нравится.

Аббревиатура для одного слота по умолчанию

В приведенном выше случае, если и только если предоставлено содержимое слота по умолчанию, мы можем использоватьv-slotВоздействовать непосредственно на компонент:

<current-user v-slot:default="slotProps">
  {{ slotProps.user.firstName }}
</current-user>

Мы можем упростить обозначение слота по умолчанию выше:

<current-user v-slot="slotProps">
  {{ slotProps.user.firstName }}
</current-user>

Обратите внимание, что сокращенный синтаксис для слотов по умолчанию нельзя смешивать с именованными слотами:

<!-- 控制台将报警告:-->
<!-- To avoid scope ambiguity, the default slot should also use <template> syntax when there are other named slots. -->
<!-- 意思就是说,为了避免作用域模糊 -->
<!-- 当有其他具名插槽时,默认插槽也应当使用 '<template>' 模板语法 -->
<current-user v-slot="slotProps">
  {{ slotProps.user.firstName }}
  <template v-slot:other="otherSlotProps">
    slotProps is NOT available here
  </template>
</current-user>

Итак, приведенный выше код перепишем как:

<current-user>
 <!-- 两种写法均可 -->
  <!--<template v-slot="slotProps">
    {{ slotProps.user.firstName }}
  </template>-->
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>

  <template v-slot:other="otherSlotProps">
    ...
  </template>
</current-user>

Разрушение назначения содержимого слота

Внутри кода Vue slotProps, который мы передаем, на самом деле является единственным параметром функции:

function (slotProps) {
  // ... slot content ...
}

Это также означаетv-slotЗначение допустимо, если оно удовлетворяет выражению JavaScript, определенному параметром функции. Поэтому в поддерживаемых средах (один файл или современные браузеры) вы также можете использоватьES2015Деструктурирование грамматик для извлечения определенного содержания интерполяции, например:

<current-user v-slot="{ user }">
  {{ user.firstName }}
</current-user>

Код выглядит чище, не так ли? Мы также можем переименовать деструктурирующие переменные:

<current-user v-slot="{ user: person }">>
  {{ person.firstName }}
</current-user>

Это дает нам большую свободу действий, и вы даже можете настроить запасной контент для использования, когда интерполяция не определена:

<current-user v-slot="{ user = { firstName: 'Guest' } }">>
  {{ user.firstName }}
</current-user>

Имя динамического слота

2.6.0+ Новое

Параметры динамической командытакже относится кv-slot, что позволяет нам определять динамические имена слотов:

<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>
</base-layout>

сокращенное название слота

2.6.0+ Новое

иv-onиv-bindпохожий,v-slotСуществует также сокращение, т.е. использование#заменятьv-slot. Например,v-slot:headerсокращенно#header:

<base-layout>
  <template #header>
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <template #footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

Как и в случае с другими директивами, сокращенная форма может использоваться только при наличии аргумента, следующее недопустимо:

<!-- 将会触发一个控制台警告 -->
<current-user #="{ user }">
  {{ user.firstName }}
</current-user>

То есть, если вы хотите использовать сокращенный синтаксис, обязательно укажите имя интерполяции:

<current-user #default="{ user }">
  {{ user.firstName }}
</current-user>

Ссылаться на

конец!

Сказав так много, я надеюсь, что одноклассники, которые это увидят, приобретут больше или меньше. Пожалуйста, оставьте сообщение, чтобы исправить неправильное место, большое спасибо. Как говорится,Если вы втроем, у вас должен быть мой учитель!Надеюсь, что больше друзей, увлеченных Vue, смогут собраться вместе, чтобы обменяться технологиями! Ниже приведена группа Q, которую я поддерживаю, добро пожаловать, чтобы отсканировать код, чтобы присоединиться к группе, давайте общаться и учиться вместе. Вы также можете добавить мой личный WeChat: G911214255, комментарии掘金Вот и все.Q1769617251