/ Gists / Renderless with default layouts
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>