Переводчик: Front-end Xiaozhi
Ставь лайк и смотри, поиск в WeChat【Переезд в мир】Обратите внимание на этого человека, который не имеет большого фабричного прошлого, но имеет восходящий и позитивный настрой. эта статья
GitHub
GitHub.com/QQ449245884…Он был включен, статьи были классифицированы, и многие мои документы и учебные материалы были систематизированы.
Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.
В недавнем выпуске Vue 2.6 синтаксис использования слотов стал более лаконичным. Это изменение в слотах побудило меня открыть для себя потенциальные возможности слотов для обеспечения повторного использования, новой функциональности и более удобного чтения для наших проектов на основе Vue. Каковы действительно способные слоты?
Если вы новичок в Vue или не видели изменений в версии 2.6, продолжайте читать. Возможно, лучшим ресурсом для изучения слотов является собственная документация Vue, но здесь я дам краткое описание.
Чтобы читать больше качественных статей, пожалуйстаПосетите блог GitHub, Сотни качественных статей ждут вас каждый год!
Что такое слот?
Слоты — это механизм для компонентов Vue, который позволяет вам составлять компоненты таким образом, который отличается от строгих отношений родитель-потомок. Слоты дают вам возможность размещать контент в новом месте или делать компонент более общим. Начните с простого примера:
// frame.vue
<template>
<div class="frame">
<slot></slot>
</div>
</template>
Внешний слой этого компонента представляет собойdiv
. Предположениеdiv
существует для создания структуры стиля вокруг его содержимого. Этот компонент можно использовать для оборачивания фрейма вокруг wq как угодно, давайте посмотрим, как это работает. здесьframe
Компонент относится к компоненту, который мы только что сделали.
// app.vue
<template>
<frame><img src="an-image.jpg"></frame>
</template>
в начале и в концеframe
Содержимое между тегами будет вставлено в слот, гдеframe
компонент, заменитьslot
отметка. Это самый основной метод. Вы также можете указать содержимое по умолчанию для размещения в слоте, просто заполнив
// frame.vue
<template>
<div class="frame">
<slot>如果这里没有指定任何内容,这就是默认内容</slot>
</div>
</template>
Итак, теперь, если мы используем это так:
// app.vue
<template>
<frame />
</template>
"Если здесь ничего не указано, это значение по умолчанию” является содержимым по умолчанию, но если оно используется как прежде, текст по умолчанию будетimg
Наложение тегов.
Несколько/именованных слотов
К компоненту можно добавить несколько слотов, но если вы это сделаете, все слоты, кроме одного, должны иметь имена. Если есть слот без имени, это слот по умолчанию. Вот как создать несколько слотов:
// titled-frame.vue
<template>
<div class="frame">
<header><h2>
<slot name="header">Title</slot>
</h2></header>
<slot>如果这里没有指定任何内容,这就是默认内容</slot>
</div>
</template>
Мы сохранили тот же слот по умолчанию, но на этот раз мы добавили слот с именемheader
слот, где вы можете ввести название следующим образом:
// app.vue
<template>
<titled-frame>
<template v-slot:header>
<!-- The code below goes into the header slot -->
My Image’s Title
</template>
<!-- The code below goes into the default slot -->
<img src="an-image.jpg">
</titled-frame>
</template>
Как и раньше, если мы хотим добавить контент в слот по умолчанию, просто поместите его прямо вtitled-frame
в компоненте. Однако, чтобы добавить содержимое в именованный слот, нам нужно использоватьv-slot
Директива оборачивает код вtemplate
Маркировка. существуетv-slot
добавить двоеточие после(:)
, а затем напишите содержимое, которое будет переданоslot
Имя.
Уведомление,v-slot
даVue 2.6
, поэтому, если вы используете более старую версию, вам нужно прочитатьДокументация по синтаксису устаревшего слота.
слот с прицелом
Еще одна вещь, которую нужно знать, это то, что слоты могут передавать данные/функции своим дочерним элементам. Чтобы продемонстрировать это, нам нужен совершенно другой пример компонента со слотами: создайте компонент, который отправляет данные текущего пользователя в свой слот:
// current-user.vue
<template>
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
</template>
<script>
export default {
data () {
return {
user: ...
}
}
}
</script>
Этот компонент имеетuser
, который содержит сведения о пользователе. По умолчанию компонент отображает фамилию пользователя, но обратите внимание, что он используетv-bind
Привязать пользовательские данные кslot
. Таким образом, мы можем использовать этот компонент для предоставления пользовательских данных его потомкам.
// app.vue
<template>
<current-user>
<template v-slot:default="slotProps">{{ slotProps.user.firstName }}</template>
</current-user>
</template>
Для доступа перейдите кslot
data мы используем значение директивы v-slot, чтобы указать имя переменной области видимости.
Здесь следует отметить несколько вещей:
-
мы указали
default
, но вам не нужно указывать имя слота по умолчанию. Вместо этого мы можем использовать v-slot="slotProps"
. -
Не нужно использовать
slotProps
Как имя, вы можете называть его как хотите. -
Если используется только слот по умолчанию, внутренние компоненты можно пропустить.
template
отметка, прямоv-slot
команда на текущийcurrent-user
начальство. -
Вместо использования одного имени переменной можно использовать деструктурирование объекта для создания прямых ссылок на данные слота с заданной областью. Другими словами, вы можете использовать
v-slot="{user}"
заменятьv-slot="slotProps"
, который затем можно использовать напрямуюuser
вместоslotProps.user
.
Итак, приведенный выше пример можно переписать так
// app.vue
<template>
<current-user v-slot="{user}">
{{ user.firstName }}
</current-user>
</template>
Еще несколько моментов, которые нужно помнить:
-
можно использовать
v-bind
Директивы связывают несколько значений. -
Также можно передавать функции в слоты с заданной областью действия. Многие библиотеки используют его для предоставления повторно используемых функциональных компонентов.
-
v-slot
Псевдоним#
. Поэтому вы можете использовать#header="data"
заменитьv-slot:header="data"
. также можно использовать#header
заменитьv-slot:header
(Предпосылка: когда нет слота с областью действия). Для слотов по умолчанию требуется при использовании псевдонимовУкажите имя по умолчанию. Другими словами, вам нужно написать#default="data"
вместо#="data"
.
Доступна сДокументациядля получения более подробной информации, но этого достаточно, чтобы помочь вам понять, что обсуждается в остальной части этой статьи.
Что можно делать со слотами?
Слоты не созданы для одной цели, или, по крайней мере, если они и созданы, они вышли за рамки своего первоначального предназначения и стали мощными инструментами для выполнения множества разных задач.
многоразовый шаблон
Компоненты всегда предназначены для повторного использования, но некоторые шаблоны нецелесообразно реализовывать с помощью одного «простого» компонента, потому что для его настройки требуетсяprops
Их может быть слишком много или нужно пройтиprops
Передайте большую часть контента или других компонентов.
Слоты могут заключать в себе внешние HTML-теги или компоненты и позволяют размещать другие HTML или компоненты в именованном слоте, соответствующем именованному слоту.
Для первого примера начните с чего-то простого: кнопки. Допустим, наша команда использует Bootstrap. В Bootstrap кнопки обычно такие же, как и в основных“btn”
Класс привязан к классу, определяющему цвет, например“btn-primary”
. вы также можете добавитьsize
классы, такие как'btn-lg'
.
Для простоты предположим, что ваше приложение используетbtn
,btn-primary
а такжеbtn-lg
. Вы не хотите всегда писать эти три класса на кнопке, или вы не доверяете новичкам, чтобы они не забывали их записывать.
В этом случае можно создать компонент, который автоматически включает все три этих класса, но как разрешить настраиваемый контент? props непрактичны, потому что кнопки могут содержать различный HTML, поэтому вместо этого мы должны использовать слот.
<!-- my-button.vue -->
<template>
<button class="btn btn-primary btn-lg">
<slot>Click Me!</slot>
</button>
</template>
Теперь мы можем использовать его где угодно, какой бы контент вы ни захотели
<!-- 使用 my-button.vue -->
<template>
<my-button>
<img src="/img/awesome-icon.jpg"> 我是小智!
</my-button>
</template>
Конечно, вы можете выбрать что-то большее, чем кнопка. Придерживаясь Bootstrap, давайте посмотрим на модальное окно:
<!-- my-modal.vue -->
<template>
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<slot name="header"></slot>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<slot name="body"></slot>
</div>
<div class="modal-footer">
<slot name="footer"></slot>
</div>
</div>
</div>
</div>
</template>
Теперь используйте его:
<!-- 使用 my-modal.vue -->
<template>
<my-modal>
<template #header>
<h5>大家最棒!</h5>
</template>
<template #body>
<p>大家加油</p>
</template>
<template #footer>
<em>大家好样的!</em>
</template>
</my-modal>
</template>
Вышеупомянутый вариант использования слота, очевидно, очень полезен, но он может делать гораздо больше.
функция повторного использования
Компоненты Vue — это не только HTML и CSS. Они построены на JavaScript, так что тоже о функциях. Слоты полезны для создания функций один раз и использования их в нескольких местах. Вернемся к модальному примеру и добавим функцию, закрывающую модальное окно.
<!-- my-modal.vue -->
<template>
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<slot name="header"></slot>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<slot name="body"></slot>
</div>
<div class="modal-footer">
<slot name="footer" :closeModal="closeModal"></slot>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
//...
methods: {
closeModal () {
// 关闭对话框时,需要做的事情
}
}
}
</script>
Используя этот компонент, вы можетеfooter
Добавьте кнопку, которая может закрыть модальное окно. Как правило, в случае режима Bootstrap можно поставитьdata-dismiss =“modal”
Добавлено в кнопку, чтобы закрыть.
Но мы хотим скрыть определенные вещи Bootstrap. Поэтому мы передаем им функцию, которую они могут вызывать, чтобы пользователь не знал, что у нас есть что-то, использующее Bootstrap.
<!-- 使用 my-modal.vue -->
<template>
<my-modal>
<template #header>
<h5>Awesome Interruption!</h5>
</template>
<template #body>
<p>大家加油!</p>
</template>
<template #footer="{closeModal}">
<button @click="closeModal">
点我可以关闭烦人的对话框
</button>
</template>
</my-modal>
</template>
нет компонента рендеринга
Наконец, возьмите то, что вы знаете об использовании слотов для передачи многократно используемых функций, удалите весь HTML и просто используйте слоты. В этом суть компонента без рендеринга: компонента, который предоставляет только функции без какого-либо HTML.
Сделать компонент действительно без рендеринга может быть немного сложно, так как это требует написанияrender
вместо использования шаблона для удаления зависимости от корневого элемента, но это не всегда может быть необходимо. Давайте рассмотрим простой пример, который начинается с шаблонов:
<template>
<transition name="fade" v-bind="$attrs" v-on="$listeners">
<slot></slot>
</transition>
</template>
<style>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
Это странный пример компонента без рендеринга, поскольку в нем даже нет JavaScript. В основном это связано с тем, что мы создаем предварительно настроенную версию для повторного использования без встроенной функции рендеринга:transition
.
Да, Vue имеет встроенные компоненты без рендеринга. Этот конкретный пример взят из статьи Cristi Jora наМногоразовый переходв статье, показывающей простой способ создания компонентов без рендеринга, которые стандартизируютtransition
.
В другом нашем примере мы создадим компонент для управления переключением того, что появляется в разных состояниях промиса: ожидание, разрешение и сбой. Это распространенный шаблон, и хотя он не требует большого количества кода, он загромождает множество компонентов, не извлекая логику для повторного использования.
<!-- promised.vue -->
<template>
<span>
<slot name="rejected" v-if="error" :error="error"></slot>
<slot name="resolved" v-else-if="resolved" :data="data"></slot>
<slot name="pending" v-else></slot>
</span>
</template>
<script>
export default {
props: {
promise: Promise
},
data: () => ({
resolved: false,
data: null,
error: null
}),
watch: {
promise: {
handler (promise) {
this.resolved = false
this.error = null
if (!promise) {
this.data = null
return
}
promise.then(data => {
this.data = data
this.resolved = true
})
.catch(err => {
this.error = err
this.resolved = true
})
},
immediate: true
}
}
}
</script>
Что здесь происходит, приятель?Во-первых, обратите внимание, что этот компонент принимает параметр типа Promise. существуетwatch
раздел, мониторpromise
меняется, когдаpromise
Когда происходит изменение, очистите состояние, затем вызовите then и перехватите промис, обновив состояние, когда промис будет успешным или неудачным.
Затем в шаблоне мы отображаем другой слот в зависимости от состояния. Обратите внимание, что мы не оставили его полностью без рендеринга, потому что нам нужен корневой элемент для использования шаблона. мы такжеdata
а такжеerror
Передано в соответствующую область действия слота.
<template>
<div>
<promised :promise="somePromise">
<template #resolved="{ data }">
Resolved: {{ data }}
</template>
<template #rejected="{ error }">
Rejected: {{ error }}
</template>
<template #pending>
请求中...
</template>
</promised>
</div>
</template>
...
мы будемsomePromise
Передано необработанным компонентам. затем подождите, пока он закончится, дляpending
слот, показывающий "Запрос...". В случае успеха отображается «Решено: соответствующее значение». В случае сбоя отображается сообщение «Отклонено: причина сбоя». Теперь нам больше не нужно следить заpromise
состояние, потому что раздел вытягивается в свой собственный повторно используемый компонент.
Итак, что мы можем сделать, чтобы обойтиpromised.vue
слот в? Чтобы удалить его, нам нужно удалитьtemplate
раздел и добавляем в наш компонентrender
функция:
render () {
if (this.error) {
return this.$scopedSlots['rejected']({error: this.error})
}
if (this.resolved) {
return this.$scopedSlots['resolved']({data: this.data})
}
return this.$scopedSlots['pending']()
}
Этот
Здесь нет ничего слишком сложного. мы просто используем некоторыеif
блок, чтобы найти состояние, а затем вернуть правильную областьslot
(пройти черезthis.$ scopedslot ['SLOTNAME'](…)
) и передать соответствующие данные вslot
объем. Если вы не используете шаблоны, вы можете пропустить использование.vue
расширение файла путем преобразования JavaScript изscript
отмечай и вставляй.js
в файле. Это должно дать вам очень небольшой прирост производительности при компиляции этих файлов Vue.
Суммировать
Слоты Vue выводят разработку на основе компонентов на совершенно новый уровень, и, хотя в этой статье показано много отличных способов использования слотов, их гораздо больше. Добро пожаловать, чтобы оставить сообщение для обсуждения.
Ошибки, которые могут существовать после развертывания кода, нельзя узнать в режиме реального времени.Чтобы решить эти ошибки впоследствии, много времени тратится на отладку логов.Кстати, всем рекомендую полезный инструмент мониторинга ошибок.Fundebug.
общаться с
Статья постоянно обновляется каждую неделю. Вы можете выполнить поиск «Big Move to the World» в WeChat, чтобы прочитать и обновить ее как можно скорее (на одну или две статьи раньше, чем в блоге). Эта статья находится на GitHub.GitHub.com/QQ449245884…Он был включен, и многие мои документы были разобраны. Добро пожаловать в Звезду и совершенство. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Кроме того, обратите внимание на паблик-аккаунт и ответьте в фоновом режиме.Благосостояние, вы можете увидеть преимущества, вы знаете.