Подразумевается, что вы уже изучили и разобрались с разделом Основы компонентов. Если нет — прочитайте его сначала.
keep-alive
с динамическими компонентамиРанее мы использовали атрибут is
для переключения компонентов во вкладках:
Но иногда, при переключении между компонентами, вы хотите сохранить их состояния или избежать повторной отрисовки по соображениям производительности. Например, когда немного доработаем наш пример с вкладками:
Вы можете заметить, что если выбрать запись, переключиться на вкладку Archive, затем переключиться обратно на Posts, то больше не будет показываться выбранная запись. Это связано с тем, что каждый раз, когда вы переключаетесь на новую вкладку, Vue создаёт новый экземпляр currentTabComponent
.
Пересоздание динамических компонентов обычно является полезным поведением, но в нашем случае, мы хотим чтобы экземпляры компонентов вкладок кэшировались после их создания в первый раз. Для решения этой проблемы мы можем обернуть наш динамический компонент в элемент <keep-alive>
:
<!-- Неактивные компоненты будут закэшированы! -->
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
Теперь вкладка Posts управляет собственным состоянием (выбранной записью) даже когда не отображается.
Обратите внимание, что <keep-alive>
требует, чтобы у всех переключаемых компонентов было задано имя, либо через настройку name
компонента, либо через местную/глобальную регистрацию.
Подробнее с элементом <keep-alive>
можно ознакомиться на странице API.
Иногда бывает удобно разделить крупное приложение на части и подгружать компоненты с сервера только тогда, когда в них возникнет потребность. Для этого Vue позволяет определить компонент как функцию-фабрику, асинхронно возвращающую определение компонента. Vue вызовет фабричную функцию только тогда, когда компонент действительно понадобится, и закэширует результат для дальнейшего использования. Например:
Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
// Передаём определение компонента в обратновызов resolve
resolve({
template: '<div>Я — асинхронный!</div>'
})
}, 1000)
})
Функция-фабрика принимает параметр resolve
— обратновызов, который вызывается после того, как определение компонента получено от сервера. Кроме того, можно вызвать reject(reason)
, если загрузка по какой-либо причине не удалась. Мы используем setTimeout
исключительно в демонстрационных целях; как именно получать компонент в рабочей ситуации — решать только вам самим.
При использовании местной регистрации компонентов, вы также можете непосредственно указывать функцию, которая возвращает Promise
:
new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
})
Добавлено в версии 2.3.0+
Фабрика асинхронного компонента также может возвращать объект следующего формата:
const AsyncComponent = () => ({
// Загружаемый компонент. Значение должно быть Promise
component: import('./MyComponent.vue'),
// Компонент загрузки, используемый пока загружается асинхронный компонент
loading: LoadingComponent,
// Компонент ошибки, используемый при неудачной загрузке
error: ErrorComponent,
// Задержка перед показом компонента загрузки. По умолчанию: 200 мс.
delay: 200,
// Компонент ошибки будет отображаться, если отсрочка
// была указана и время ожидания превышено. По умолчанию: Infinity.
timeout: 3000
})
Обратите внимание, что вы должны использовать Vue Router версии 2.4.0+ если вы хотите использовать указанный выше синтаксис для компонентов маршрута.