Входные параметры и пропсы

В рамках фреймворка 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, а для agenumber. Также указывается, что пропс 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 основана на простых, но мощных принципах передачи данных, валидации, реактивности и локального состояния. Правильное использование этих концепций позволяет создавать гибкие, масштабируемые и легко поддерживаемые компоненты, что является важной частью работы с этим фреймворком.