Vue

Библиотека Patron интегрируется в Vue без каких-либо проблем. Например, чтобы источник данных привязать к ref можно использовать такой класс (Листинг 1).

Листинг 1.

class VueRefPatron<T> implements GuestType<T> {
    private readonly innerRef: Ref<T | undefined>;

    public constructor(defaultValue: T | undefined = undefined) {
        this.innerRef = ref(defaultValue);
    }

    public ref() {
        return this.innerRef;
    }

    public give(value: T) {
        this.innerRef.value = value;
        return this;
    }

    public introduction() {
        return 'patron' as const;
    }
}

Класс VueRefPatron можно использовать как посетителя для разных источников данных, связывая таким образом источники данных с системой реактивности Vue.

Источники в шаблоне Vue

Также в шаблонах можно использовать заготовку из листинга 2, для того, чтобы концентрироваться на разработке чистых компонентов, ожидающих простые данные, вместо того, чтобы смешивать логику получения данных и логику компонентов.

Листинг 2.


<template>
  <div>
    <slot v-if="!data" name="fallback" />
    <slot v-else :data="data" />
  </div>
</template>

<script lang="ts">
import { Source, Guest, Patron } from 'patron-oop';
import { defineComponent, ref } from 'vue';
import { PropType } from 'vue/types/v3-component-props';

export default defineComponent({
  name: 'Source',
  emits: ['input'],
  props: {
    source: {
      type: Object as PropType<Source<any>>,
      required: true,
    },
  },
  setup(props, { emit }) {
    const data = ref(null);
    props.source.value(
      new Patron(
        new Guest(value => {
          data.value = value;
          emit('input', value);
        })
      )
    );
    return {
      data,
    };
  },
});
</script>

В результате компонент Source можно использовать, чтобы оборачивать другие компоненты, требующие данные, передать в компонент источник данных, результат работы которого будет в пропсе data в слоте default.