Автор: Милош Протич
Переводчик: Front-end Xiaozhi
Источник: среда
Чем больше вы знаете, тем больше вы не знаете
Ставьте лайк и смотрите снова, формируйте привычку
эта статьяГитхаб:GitHub.com/QQ449245884…Он был включен в вышеизложенное, и более ранние статьи с высокими похвалами были классифицированы, а также было систематизировано множество моих документов и учебных материалов. Добро пожаловать в Star and Perfect. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Надеюсь, у нас что-то получится вместе.
Что такое состояние приложения и зачем оно нам нужно?
Управление состоянием обычно не требуется в небольших проектах, но когда речь идет о больших масштабах, таких как приложения уровня предприятия, оно в основном необходимо. Проще говоря, состояние — это объект, который содержит последние значения, используемые приложением. Однако, если мы посмотрим на это со структурной, более абстрактной точки зрения, станет ясно, что состояние — это важная составляющая сложности, которая обеспечивает чистую архитектуру и четкое разделение задач.
Часто неопытные разработчики не могут предсказать необходимость управления состоянием и то, как оно будет реализовано, что затрудняет понимание важности управления состоянием. Если компоненты, основанные на состоянии, накапливаются, управление и обмен данными между ними становится кошмаром. Чем больше у вас компонентов, основанных на состоянии, тем больше у вас проблем в долгосрочной перспективе.
Если вы не используете внешние пакеты для управления состоянием, лучше использовать как можно меньше компонентов, основанных на состоянии, и презентационные компоненты, чтобы использовать состояние, построенное вокруг них.
Vue и компоненты без состояния (функции)
Компоненты без состояния в Vue на самом деле являются функциональными компонентами. Но что такое функциональные компоненты?Чтобы ответить на этот вопрос, мы должны сначала понять, что такое функциональное программирование.
В отличие от объектно-ориентированных подходов, которые разлагают программы на объекты, функциональное программирование поощряет разбиение программ на небольшие функции, которые используются для формирования программ более высокого уровня. Создаваемые нами функции не зависят и не могут изменять какое-либо внешнее состояние, что приводит к еще одному наблюдению, что они всегда возвращают один и тот же результат для заданного ввода.
Следовательно, функциональный компонент — это компонент, который не имеет состояния и может его изменить. Выход функционального компонента всегда основан на заданном входе. На стороне Vue такие компоненты будутprops
дает разный результат.
грамматика
Vue предоставляет простой способ определения функциональных компонентов. нам просто нужно датьfunctional
Ключевое слово подойдет. В версии 2.5.0 и выше, если используются однофайловые компоненты, функциональные компоненты на основе шаблонов могут быть объявлены следующим образом:
<template functional>
<div> 函数/无状态组件 </div>
</template>
или
export default {
functional: true,
props: {
// ...
},
render(createElement, context) {
return createElement(
'div', '函数/无状态组件'
)
}
}
Примечание. В версиях до 2.3.0, если функциональный компонент хотел получить
prop
,ноprops
опция обязательна. В версии 2.3.0 и выше можно не указыватьprops
опция, атрибуты всех компонентов автоматически неявно преобразуются вprop
.
При использовании функциональных компонентов ссылка будет
HTMLElement
, потому что они не имеют состояния и экземпляра.
должен быть в курсе, единственные данные, передаваемые функциональному компоненту,props
. Эти компоненты полностью не имеют состояния (нет данных ответа), они игнорируют любое переданное им состояние и не запускают никаких методов жизненного цикла (created
,mounted
так далее).
Кроме того, мы не можем использоватьthis
ключевое слово для доступа к экземпляру, так как эти компоненты также не создаются. Вместо этого все, что нужно компоненту, передается черезcontext
который предоставил. существуетrender
Функция, какcreateElement
Передается второй параметр метода.
Все, что нужно компоненту, передаетсяcontext
Передача параметров, это объект со следующими полями:
-
props
: объект, предоставляющий все реквизиты -
children
: массив дочерних узлов VNode -
slots
: функция, которая возвращает объект, содержащий все слоты -
scopedSlots
: (2.6.0+) Объект, раскрывающий переданный слот с областью видимости. Также предоставляет обычные слоты как функции. -
data
: Весь объект данных, переданный компоненту, передается компоненту в качестве второго параметра createElement. -
parent
: ссылка на родительский компонент -
listeners
: (2.3.0+) Объект, содержащий все прослушиватели событий, зарегистрированные родительским компонентом для текущего компонента. Это псевдоним для data.on . -
injections
: (2.3.0+) Если используется опция вставки, этот объект содержит свойства, которые должны быть вставлены.
Зачем нужны компоненты без состояния
До сих пор мы видели, что функциональные компоненты не имеют состояния, по своей сути они являются просто исполняемыми функциями, которые принимают некоторый ввод и обеспечивают вывод на его основе.
Что касается их использования, поскольку функциональные компоненты — это просто функции, накладные расходы на рендеринг также намного ниже, что также означает, что они очень эффективны и не требуют много времени для рендеринга. Между тем, рассмотрите компоненты более высокого порядка, им не нужно какое-либо состояние, все, что им нужно сделать, это обернуть данный дочерний компонент дополнительной логикой или стилем.
Далее на общих примерах показано, когда следует использовать функциональные компоненты, которые хорошо подходят для таких задач.
Пример
В этом примере мы создаемpanel
компонент, который действует как оболочка и предоставляет необходимые стили. Подкомпоненты будут вpanel
Рендер в теле:
export default {
name: 'panel',
functional: true,
props: {
title: String
},
render(createElement, context) {
const slots = context.slots();
const header = createElement('header', {
attrs: { class: 'panel-header'}
}, context.props.title);
const body = createElement('main', {
attrs: { class: 'panel-body'}
}, slots.default);
return createElement('section', {
attrs: { class: 'panel' }
}, [header, body]);
}
}
Как упоминалось выше, единственная цель этого компонента — обеспечить стиль, похожий на панели (карты), он имеетheader
а такжеmain
элемент, который содержит заголовок панели иHTML
содержание. Весь процесс осуществляется с помощьюrender
в функцииcreateElement
Параметры выполняются в .createElement
даVueЧасть системы виртуального дома, реализованная в ядре.
виртуальный DOM
Vue отслеживает, как он хочет изменить реальный DOM, создавая виртуальный DOM. Пожалуйста, внимательно посмотрите на эту строку кода:
return createElement('h1', this.blogTitle)
createElement
Что именно он вернет? не настоящийDOM
элемент. его более точное название может бытьcreateNodeDescription
, потому что содержащаяся в нем информация скажет Vue, какой тип узла необходимо отобразить на странице, включая описания его дочерних узлов. Мы описываем такой узел как «виртуальный узел», который часто обозначается аббревиатурой «VNode«Виртуальный DOM» — это наше представление всего дерева компонентов Vue, созданногоVNode
Имя дерева.
параметр createElement
Следующее, с чем вам нужно ознакомиться, это как использовать эти функции в шаблоне в функции createElement. Вот параметры, которые принимает createElement:
// @returns {VNode}
createElement(
// {String | Object | Function}
// 一个 HTML 标签名、组件选项对象,或者
// resolve 了上述任何一种的一个 async 函数。必填项。
'div',
// {Object}
// 一个与模板中属性对应的数据对象。可选。
{
// (详情见下一节)
},
// {String | Array}
// 子级虚拟节点 (VNodes),由 `createElement()` 构建而成,
// 也可以使用字符串来生成“文本虚拟节点”。可选。
[
'先写一些文字',
createElement('h1', '一则头条'),
createElement(MyComponent, {
props: {
someProp: 'foobar'
}
})
]
)
Стили панели CSS следующие:
.panel {
margin-bottom: .5rem
}
.panel, .panel-header {
border: 1px solid #d3d3d3;
border-radius: 4px;
}
.panel-header, .panel-body, .panel {
padding: .5rem;
}
.panel-header {
background-color:#efefef;
color: #eeeee
}
Вот простой и понятный CSS, который предоставляет некоторыеpadding
а такжеcolor
.
Подсборка
Теперь, чтобы оживить пример, давайте создадим еще два дополнения, одно из которых отображает список автомобилей, а другое — простоеlorem-ipsum
, требуя, чтобы они имели одинаковый стиль панели и внешний вид.
Компонент списка:
export default {
name: 'cars',
props: {
data: Array
}
}
шаблон:
<template>
<ul>
<li v-for="car in data" :key="car">{{car}}</li>
</ul>
</template>
Текстовая составляющая:
export default {
name: 'lorem-ipsum'
}
template:
<template>
<p>
终身学习者,终身学习者,终身学习者,终身学习者,终身学习者
</p>
</template>
Теперь, когда подкомпоненты доступны, все, что нам нужно сделать, это использоватьpanel
Компоненты инкапсулируют их в приложение следующим образом:
<div class="vue-app">
<panel :title="'Car Manufacturers'">
<cars :data="['Mazda', 'Ford', 'Mercedes']"></cars>
</panel>
<panel :title="'Lorem Ipsum'">
<lorem-ipsum></lorem-ipsum>
</panel>
</div>
Обратите внимание, что эти компоненты используются, потому что пример проще. В практических приложениях это может быть компонент любого типа.
полный код
hmtl
<div class="vue-app">
<panel :title="'Car Manufacturers'">
<cars :data="['Mazda', 'Ford', 'Mercedes']"></cars>
</panel>
<panel :title="'Lorem Ipsum'">
<lorem-ipsum></lorem-ipsum>
</panel>
</div>
<script type="text/x-template" id="cars">
<template>
<ul>
<li v-for="car in data" :key="car">{{car}}</li>
</ul>
</template>
</script>
<script type="text/x-template" id="lorem-ipsum">
<template>
<p>前端小智, 终身学习者,终身学习者,终身学习者,终身学习者,终身学习者</p>
</template>
</script>
css
body {
padding: .5rem
}
* {
padding: 0;
margin:0;
box-sizing: border-box;
}
.panel {
margin-bottom: .5rem
}
.panel, .panel-header {
border: 1px solid #d3d3d3;
border-radius: 4px;
}
.panel-header, .panel-body, .panel {
padding: .5rem;
}
.panel-header {
background-color:#efefef;
color: #eeeee
}
ul {
list-style: none;
}
ul > li {
padding: .5rem .2rem
}
js
// the wrapper panel
const panel = {
functional: true,
name: "panel",
props: {
title: String
},
render(createElement, context) {
const slots = context.slots();
const header = createElement('header', {
attrs: { class: 'panel-header'}
}, context.props.title);
const body = createElement('main', {
attrs: { class: 'panel-body'}
}, slots.default);
return createElement('section', {
attrs: { class: 'panel' }
}, [header, body]);
}
}
// sample components
const cars = {
name: 'cars',
template: '#cars',
props: {
data: Array
}
}
const loremIpsum = {
name: 'lorem-ipsum',
template: '#lorem-ipsum'
}
new Vue({
el: '.vue-app',
components: {
panel,
cars,
'lorem-ipsum': loremIpsum
}
});
текущий результат:
Ошибки, которые могут существовать после развертывания кода, нельзя узнать в режиме реального времени.Чтобы решить эти ошибки впоследствии, много времени тратится на отладку логов.Кстати, всем рекомендую полезный инструмент мониторинга ошибок.Fundebug.
оригинал:IT next.IO/что-он-и-о…
общаться с
общаться с
Статья постоянно обновляется каждую неделю. Вы можете выполнить поиск «Big Move to the World» в WeChat, чтобы прочитать и обновить ее как можно скорее (на одну или две статьи раньше, чем в блоге). Эта статья находится на GitHub.GitHub.com/QQ449245884…Он был включен, и многие мои документы были разобраны. Добро пожаловать в Звезду и совершенство. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Кроме того, обратите внимание на паблик-аккаунт и ответьте в фоновом режиме.Благосостояние, вы можете увидеть преимущества, вы знаете.