Vue.js предоставляет два способа загрузки компонентов: глобально на экземпляре Vue и на уровне компонентов. Каждый метод обладает своими преимуществами.
При использовании глобальной загрузки компонент будет доступен из любого шаблона в приложении, включая подкомпоненты, что сокращает необходимость импортирования глобального компонента в подкомпоненты. Также при использовании глобальной загрузки можно избежать ошибки компонента register Vue “did you register the component correctly?”
. Однако глобальную загрузку компонентов стоит использовать только в исключительных случаях, поскольку она приводит к расширению приложения. Даже если компонент не используется, он все равно будет включен в сборки Webpack.
import Vue from 'vue';
import Editor from './componetns/Editor.vue'
//Где 'editor' - это имя компонента <editor></editor>
Vue.component('editor', Editor);
При локальной загрузке можно изолировать компоненты и загружать их только при необходимости. В сочетании с Webpack можно использовать отложенную загрузку компонентов только во время их использования. Это значительно уменьшает исходный размер файла приложения и сокращает время начальной загрузки.
template>
<section>
<editor></editor>
</section>
</template>
<script>
import Editor from './Editor'
export default {
name: 'dashboard',
components: {
Editor
}
}
</script>
Отложенная загрузка компонентов с использованием динамических импортов Webpack. Vue поддерживает отложенную загрузку компонентов во время рендеринга и разделение кода. Благодаря этим оптимизациям код компонента загружается только при необходимости, благодаря чему уменьшается размер HTTP-запроса, размер файла и автоматически повышается производительность. Отличительной особенностью этой функции является возможность работы как с глобально, так и с локально загруженными компонентами.
Глобальная загрузка асинхронных компонентов:
import Vue from 'vue';
//Где 'editor' - это название компонента <editor></editor>
//Возвращает промис, который вызывается только при визуализации компонента, а затем кешируется.
Vue.component('editor', () => import('./componetns/Editor.vue'));
Локальная загрузка асинхронных компонентов:
<template>
<section>
<editor></editor>
</section>
</template>
<script>
export default {
name: 'dashboard',
components: {
'Editor': () => import('./Editor')
}
}
</script>
Props для компонента можно создать несколькими способами: передача массива строк, представляющих названия prop, или передача объекта с ключами в качестве названий prop и объекта конфигурации.
При использовании объектно-ориентированного подхода можно создать несколько ключевых изменений конфигурации для каждого prop, один из которых будет требуемым ключом. Требуемый ключ ожидает значения true
или false
. True выдает ошибку, если prop не установлен при использовании компонента, а false (значение по умолчанию) не выдает ошибку, если prop не установлен. Рекомендуется использовать требуемый prop при совместном использовании компонентов несколькими разработчиками.
<template>
<section>
<editor v-if="isAdmin"></editor>
</section>
</template>
<script>
export default {
name: 'Editor',
props: {
enabled: {},
isAdmin: {
required: true
}
}
}
</script>
$emit
Связь между дочерним и родительским компонентами можно осуществлять с помощью встроенной функции компонентов $emit
для генерации пользовательских событий. Функция $emit
принимает строку для названия события и необязательное значение для отправки. Для прослушивания события добавьте “@eventName
” к компоненту, генерирующему событие, и передайте обработчик события.
<template>
<section>
<button @click="onClick">Save</button>
</section>
</template>
<script>
export const SAVE_EVENT = 'save';
export default {
name: 'triggerEvent',
methods: {
onClick() {
this.$emit(SAVE_EVENT);
}
}
}
</script>
<template>
<section>
<p v-show="showSaveMsg">Thanks for Listening for the saved event</p>
<trigger-event @save="onSave"></trigger-event>
</section>
</template>
<script>
export default {
name: 'TriggerEvent',
data(){
return {
showSaveMsg: false
}
},
components:{
//Trigger Custom Events в VueJs можно найти по этой ссылке https://gist.github.com/eabelard/36ebdc8367bfeff75387cc863c810f65
TriggerEvent: () => import('./TriggerEvent')
},
methods: {
onSave() {
this.showSaveMsg = true;
}
}
}
</script>
Как определить логические составляющие, на которые нужно разбить компонент? Первый способ разделения компонента основан на показателе изменения данных. Если данные изменяются последовательно в одном разделе компонента, но не в других, то, вероятно, из этого раздела можно создать отдельный компонент.
Причина заключается в том, что если данные или HTML изменяются последовательно в одном разделе шаблона, то этот раздел необходимо проверить и обновить. Однако, если тот же HTML размещается в собственном компоненте с данными, переданными с использованием props, то только этот компонент будет обновляться при изменении его props.
Другой способ логического разделения компонентов применяется для повторного использования. При наличии HTML, графиков или функций, которые последовательно используются в приложении, можно создать новый компонент для повторного использования.
Вместо использования массива строк для определения props используйте нотацию объекта, с помощью которой можно конфигурировать каждый prop. К полезным стилям конфигурации можно отнести type и validator.
При использовании параметра type Vue автоматически выполняет проверку типов значения prop. Например, при ожидании prop Number, но получении String, в консоли появится следующее предупреждение:
[Vue warn]: Invalid prop: type check failed for prop "count". Expected NumberПри выполнении более сложных проверок можно передать функцию свойству validator, которое принимает значение в качестве аргумента и возвращает true
или false
. Благодаря этому можно написать пользовательскую проверку по значению, которое передается этому конкретному свойству.
<template>
<section class="custom-validation" :class="[{enabled}, status]">
<p>You {{status}} the test</p>
</section>
</template>
<script>
export default {
name: "CustomValidation",
props: {
enabled: Boolean,
status: {
default: "fail",
validator: function(value) {
return ["pass", "fail"].includes(value);
}
}
}
};
</script>
<style scoped>
.custom-validation {
opacity: 0.5;
}
.enabled {
opacity: 1;
}
.pass {
color: green;
}
.fail {
color: red;
}
</style>
Если компонент обладает несколькими props, то установление привязки для каждого prop отнимет много времени. К счастью, есть быстрый способ установить привязку для всех свойств компонента путем привязки объекта вместо одного свойства с помощью v-bind
.
Дополнительным преимуществом использования привязки объекта является возможность перезаписи любой привязки из объекта. В данном случае, если в объекте person для isActive
установлено значение false, то можно сделать еще одну привязку к фактическому компоненту person и установить для isActive
значение true, не перезаписывая оригинал.
<template>
<div id="app">
<person v-bind="person" :isActive="true"/>
</div>
</template>
<script>
import Person from "./components/Person.vue";
export default {
name: "App",
components: { Person },
data() {
return {
person: {
firstName: "Jaxson",
lastName: "Pierre",
dob: "05/22/1996",
isActive: false
}
};
}
};
</script>
Иногда при изменении значения, переданного из prop, может появиться предупреждение “Avoid mutating a prop directly”. Поэтому используйте значение prop в качестве значения по умолчанию для свойства локальных данных. Благодаря этому можно увидеть исходное значение, однако при модификации локальных данных значение prop не изменится.
При использовании этого метода свойство локальных данных не реагирует на значение prop, поэтому любые изменения в значении prop из родительского компонента не обновят локальное значение. В случае необходимости выполнения этих обновлений можно комбинировать значения с помощью вычисляемого свойства.
<template>
<main>
<section>
<h2>Non Reactive</h2>
<p>{{ localFirstName }}</p>
<button @click.prevent="changeLocalFirstName">Update First Name</button>
</section>
<section>
<h2>Reactive List</h2>
<ol>
<li v-for="item in itemsList" :key="item">{{ item }}</li>
</ol>
</section>
</main>
</template>
<script>
export default {
name: "FullName",
props: {
firstName: {
type: String,
default: "Mike"
},
title: {
type: String,
default: "Senior"
},
items: {
type: Array,
default() {
return ["lemons", "oranges"];
}
}
},
computed: {
itemsList() {
return [...this.items, ...this.localItems];
}
},
data() {
return {
localItems: ["mangos", "apples"],
localFirstName: this.firstName
};
},
methods: {
changeLocalFirstName() {
this.localFirstName = "Jackson";
}
}
};
</script>
<style scoped>
</style>
Есть два способа создания и загрузки компонентов в утилитах тестирования Vue: mount и shallow mount. Каждый из них обладает своими преимуществами и недостатками.
Техника mount удобна при проведении взаимозависимого тестирования между компонентом и его подкомпонентами. С ее помощью можно проверить правильность взаимодействия родительского компонента с подкомпонентами. Метод shallow mount создает экземпляр и визуализирует только родительский компонент в полной изоляции, игнорируя подкомпоненты.
Какой метод лучше? Решать вам. Выбранные стратегии зависят от поставленных целей. При необходимости тестирования компонента с полной изоляцией стоит использовать метод shallow. При работе с компонентом, обладающим подкомпонентами, следует использовать метод mount. Также методы можно комбинировать.
Vue CLI — это мощный интерфейс командной строки, с помощью которого разработчики могут использовать множество функций, ускоряющих рабочий процесс.
Я часто использую функцию, при которой нужно запустить vue serve
и передать путь к компоненту Vue. При этом можно разрабатывать компонент изолированно, а также выполнять горячую перезагрузку и итерацию по компоненту. Нет необходимости временно импортировать новый компонент на страницу для разработки.
При работе в команде можно выделить определенный компонент и поделиться им с другими. Vue CLI предоставляет возможность экспортировать компонент Vue в виде библиотеки. При вызове Vue автоматически создает отдельный компонент файла, перемещает CSS во внешний CSS-файл (его также можно встроить), а также создает файлы UMD и Common .js для импорта в другие проекты JS.
vue build —-target lib --name goldenRule ./components/views/GoldenRuleПеревод статьи
Комментарии