On gists
Renderless with default layouts
•
Patterns.dev
Plugin patterns
Vue.js
DataProvider.vue
Raw
#
<!-- DataProvider.vue -->
<template>
<slot
:data="data"
:loading="loading"
:error="error"
>
<component
:is="layouts[variant]"
:data="data"
:loading="loading"
:error="error"
/>
</slot>
</template>
<script setup>
import DefaultLayout from './layouts/DefaultLayout.vue'
import CompactLayout from './layouts/CompactLayout.vue'
import CardLayout from './layouts/CardLayout.vue'
const props = defineProps({
variant: {
type: String,
default: 'default',
validator: (value) => ['default', 'compact', 'card'].includes(value)
}
})
const layouts = {
default: DefaultLayout,
compact: CompactLayout,
card: CardLayout
}
</script>
usage.vue
Raw
#
<!-- Výchozí vzhled -->
<data-provider />
<!-- Jiná předdefinovaná varianta -->
<data-provider variant="compact" />
<!-- Vlastní vzhled přes slot -->
<data-provider v-slot="{ data, loading, error }">
<my-custom-layout />
</data-provider>
layouts.vue
Raw
#
<!-- DefaultLayout.vue -->
<template>
<div class="default-layout">
<div v-if="loading">Loading...</div>
<div v-else-if="error">{{ error }}</div>
<div v-else>{{ data }}</div>
</div>
</template>
<!-- CompactLayout.vue -->
<template>
<div class="compact-layout">
<!-- jiný styl zobrazení -->
</div>
</template>
<!-- CardLayout.vue -->
<template>
<div class="card-layout">
<!-- další varianta -->
</div>
</template>