В рамках фреймворка Marko, входные параметры и пропсы являются важнейшими концепциями для построения динамичных и масштабируемых интерфейсов. Эти параметры позволяют передавать данные от родительских компонентов к дочерним, а также влияют на рендеринг и поведение компонентов. Основные принципы их использования заключаются в передаче данных между компонентами, их валидации и обеспечении реактивности.
Пропсы в Marko — это данные, которые передаются в компонент через его входные параметры. Они могут быть простыми значениями или объектами, и используются для того, чтобы компонент мог адаптироваться к различным данным, которые поступают от родительских компонентов.
Компоненты в Marko обладают строгой структурой. Внутри каждого компонента можно указать список пропсов, которые должны быть переданы извне. При этом пропсы могут быть не только данными, но и функциями или реактивными переменными, что даёт гибкость в управлении состоянием и поведением компонентов.
Для того чтобы объявить пропсы в компоненте, используется ключевое
слово input. Этот элемент определяет входные параметры,
которые компонент принимает. Пропсы могут быть как обязательными, так и
опциональными, в зависимости от потребностей.
<template>
<div>
<h1>Hello, ${input.name}!</h1>
<p>You are ${input.age} years old.</p>
</div>
</template>
<script>
module.exports = {
input: {
name: 'User',
age: 30
}
};
</script>
В данном примере компонент принимает два пропса — name и
age. Эти пропсы используются для динамической генерации
содержимого в разметке. input представляет собой объект, в
котором можно указать начальные значения для каждого пропса, если они не
были переданы извне.
Для обеспечения целостности данных и правильного поведения компонента важно правильно валидировать входные параметры. Marko позволяет задавать типы для каждого пропса, что обеспечивает статическую проверку типов в процессе разработки.
<template>
<div>
<h1>Hello, ${input.name}!</h1>
<p>Your age is: ${input.age}</p>
</div>
</template>
<script>
module.exports = {
input: {
name: { type: 'string' },
age: { type: 'number', required: true }
}
};
</script>
В этом примере для пропса name указан тип
string, а для age — number. Также
указывается, что пропс age является обязательным (опция
required: true). Это позволяет предотвратить ошибочные или
некорректные данные, поступающие в компонент.
При необходимости можно задать дефолтные значения для пропсов, что особенно полезно для обеспечения работы компонента, когда пропс не был передан извне.
<template>
<div>
<h1>Hello, ${input.name}!</h1>
<p>Your age is: ${input.age}</p>
</div>
</template>
<script>
module.exports = {
input: {
name: { default: 'Anonymous' },
age: { default: 18 }
}
};
</script>
Здесь заданы дефолтные значения для name и
age, что означает, что если родительский компонент не
передаст эти пропсы, компонент будет использовать эти значения по
умолчанию.
В Marko можно изменять значения пропсов внутри компонента. Однако это не следует воспринимать как изменение самого входного параметра. Пропсы являются только для чтения в контексте компонента, и их изменение не отражается на родительском компоненте.
Если необходимо изменить значение внутри компонента, лучше использовать локальное состояние, которое будет управляться внутри компонента.
<template>
<div>
<h1>Hello, ${input.name}!</h1>
<p>Your age is: ${local.age}</p>
<button on-click="incrementAge">Increase Age</button>
</div>
</template>
<script>
module.exports = {
input: {
name: 'User'
},
state: {
age: 30
},
incrementAge() {
this.state.age++;
}
};
</script>
В данном примере age не является пропсом, а локальным
состоянием компонента, которое можно изменять с помощью методов, таких
как incrementAge. Это помогает избегать изменений пропсов и
сохранять правильное поведение приложения.
Одной из особенностей Marko является реактивность. Это означает, что любые изменения в пропсах или состояниях компонента автоматически приведут к его перерасчету и перерисовке. В Marko это поведение встроено на уровне системы шаблонов, и каждый раз, когда пропс или состояние меняется, компонент обновляется без необходимости вручную управлять этим процессом.
<template>
<div>
<h1>Hello, ${input.name}!</h1>
<p>Your age is: ${input.age}</p>
</div>
</template>
<script>
module.exports = {
input: {
name: 'User',
age: 30
}
};
</script>
Если родительский компонент обновит пропс age, компонент
автоматически перерассчитает и отрендерит новый возраст, не требуя
дополнительных действий.
Пропсы могут быть переданы не только в корневой компонент, но и в дочерние. В этом случае дочерний компонент будет получать пропсы через родительский компонент и отображать или использовать их в своей разметке.
<template>
<div>
<h1>Hello, ${input.name}!</h1>
<child-component name=input.name age=input.age />
</div>
</template>
<script>
const childComponent = require('./childComponent');
module.exports = {
input: {
name: 'User',
age: 30
}
};
</script>
В этом примере данные name и age передаются
в дочерний компонент childComponent. Дочерний компонент
будет использовать эти пропсы для своей работы.
Работа с пропсами в Marko основана на простых, но мощных принципах передачи данных, валидации, реактивности и локального состояния. Правильное использование этих концепций позволяет создавать гибкие, масштабируемые и легко поддерживаемые компоненты, что является важной частью работы с этим фреймворком.