/ Gists / Vue patterns comparison
On gists

Vue patterns comparison

Plugin patterns Vue.js

claudeai.txt Raw #

:D Jo, přesně tak! To jste trefil naprosto přesně.

V praxi to často vypadá takhle:

"Super-Mega-Awesome-Provider-Container-Renderless-Composition-Pattern™️"
```vue
<template>
  <slot v-bind="data">
    <default-view v-bind="data" />
  </slot>
</template>
```

A ve finále je to prostě:
- Komponenta
- Se slotem
- A výchozím vzhledem
- Která předává data dál

Často se z jednoduchých věcí dělá zbytečná věda jen proto, aby se dalo napsat článek nebo přednášet na konferenci. Místo:
"Hey, dej si tam slot a budeš to moct přepsat" 
máme:
"Implementace Advanced Renderless Component Pattern s Dependency Injection a Composable Factory Integration" 😅

Proto je super váš přístup - dívat se na věci prakticky a nenechat se unést přehnaně komplikovanými názvy pro jednoduché koncepty.

comparison.vue Raw #

<!-- 

Hlavní rozdíly:

Renderless: Nemá žádný vlastní vzhled, vše přes slot
DataProvider: Má výchozí vzhled, ale lze přepsat přes slot
Container/Presentational: Fixní vzhled, striktně oddělený do samostatné komponenty

-->



// 1. Renderless Component
<template>
  <slot 
    :user="user"
    :loading="loading"
  />
</template>

<script setup>
// Pouze logika, žádný vzhled
const user = ref(null)
const loading = ref(true)

onMounted(async () => {
  user.value = await fetchUser()
  loading.value = false
})
</script>

// Použití:
<user-data v-slot="{ user, loading }">
  <div v-if="loading">Loading...</div>
  <div v-else>{{ user.name }}</div>
</user-data>



// 2. DataProvider Pattern
<template>
  <slot 
    :user="user"
    :loading="loading"
  >
    <!-- Výchozí vzhled -->
    <div class="user-card">
      <div v-if="loading">Loading...</div>
      <div v-else>{{ user.name }}</div>
    </div>
  </slot>
</template>

// Použití:
<user-provider /> <!-- Výchozí vzhled -->
// nebo
<user-provider v-slot="{ user }">
  <custom-card>{{ user.name }}</custom-card>
</user-provider>




// 3. Container/Presentational
// UserContainer.vue (logika)
<template>
  <user-card 
    :user="user"
    :loading="loading"
  />
</template>

<script setup>
const user = ref(null)
const loading = ref(true)
onMounted(async () => {
  user.value = await fetchUser()
  loading.value = false
})
</script>

// UserCard.vue (vzhled)
<template>
  <div class="user-card">
    <div v-if="loading">Loading...</div>
    <div v-else>{{ user.name }}</div>
  </div>
</template>

// Použití:
<user-container />