Библиотека 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.
Также в шаблонах можно использовать заготовку из листинга 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.