Slash vs Vue
Slash vs Vue
Section titled “Slash vs Vue”Esta página compara Slash e Vue em termos de sistema de reatividade, APIs, performance e casos de uso. Vue e Slash compartilham filosofia similar de reatividade, mas com implementações diferentes.
Resumo Rápido
Section titled “Resumo Rápido”| Aspecto | Slash | Vue 3 |
|---|---|---|
| Tamanho | ~5KB | ~34KB (runtime) |
| Reatividade | Observer Pattern explícito | Proxy-based (Composition API) |
| Virtual DOM | ❌ Não | ✅ Sim |
| Template Syntax | HTM (JSX-like) | Template strings ou JSX |
| SSR | ✅ Nativo | ✅ Sim (com Nuxt ou setup manual) |
| Ecossistema | 🌱 Crescendo | 🌳 Maduro |
| Curva de Aprendizado | Baixa | Média |
| Compile-time | ❌ Runtime-only | ✅ Compiler otimizado |
Sistema de Reatividade
Section titled “Sistema de Reatividade”Vue 3: Composition API com Proxies
Section titled “Vue 3: Composition API com Proxies”Vue 3 usa Proxies para rastrear dependências automaticamente:
<script setup>import { ref, computed } from 'vue'
const count = ref(0)const doubled = computed(() => count.value * 2)
function increment() { count.value++}</script>
<template> <div> <p>Count: {{ count }}</p> <p>Doubled: {{ doubled }}</p> <button @click="increment">Increment</button> </div></template>Como funciona:
ref()cria um objeto reativo com.value- Template é compilado para render function
- Vue rastreia acessos durante render
- Proxy detecta mudanças e agenda re-render
- Virtual DOM diff + patch
Slash: Observer Pattern Explícito
Section titled “Slash: Observer Pattern Explícito”Slash usa Observer Pattern com API explícita:
import { html, createState } from '@ezbug/slash'
function Counter() { const count = createState(0)
// Computed manual const doubled = () => count.get() * 2
return html` <div> <p>Count: ${count.get()}</p> <p>Doubled: ${doubled()}</p> <button onclick=${() => count.set(count.get() + 1)}> Increment </button> </div> `}Como funciona:
createState()cria estado reativoget()lê valor,set()atualizawatch()registra observers- Update direto no DOM (sem VDOM)
- Sem tracking automático de dependências
- Sem compiler, tudo em runtime
Sintaxe e APIs
Section titled “Sintaxe e APIs”Componentes Básicos
Section titled “Componentes Básicos”<!-- Vue 3 --><script setup>import { ref } from 'vue'
const count = ref(0)</script>
<template> <div> <p>Count: {{ count }}</p> <button @click="count++">Increment</button> </div></template>// Slashimport { html, createState } from '@ezbug/slash'
function Counter() { const count = createState(0)
return html` <div> <p>Count: ${count.get()}</p> <button onclick=${() => count.set(count.get() + 1)}> Increment </button> </div> `}<!-- Vue 3 --><script setup>import { defineProps, defineEmits } from 'vue'
const props = defineProps({ title: String, count: Number})
const emit = defineEmits(['update'])
function handleClick() { emit('update', props.count + 1)}</script>
<template> <div> <h2>{{ title }}</h2> <p>{{ count }}</p> <button @click="handleClick">Update</button> </div></template>// Slashimport { html } from '@ezbug/slash'
interface Props { title: string count: number onUpdate: (count: number) => void}
function MyComponent({ title, count, onUpdate }: Props) { return html` <div> <h2>${title}</h2> <p>${count}</p> <button onclick=${() => onUpdate(count + 1)}> Update </button> </div> `}<!-- Vue 3 --><script setup>import { ref, computed, watch } from 'vue'
const firstName = ref('John')const lastName = ref('Doe')
const fullName = computed(() => `${firstName.value} ${lastName.value}`)
watch(fullName, (newVal) => { console.log('Name changed:', newVal)})</script>
<template> <div> <input v-model="firstName" /> <input v-model="lastName" /> <p>{{ fullName }}</p> </div></template>// Slashimport { html, createState } from '@ezbug/slash'
function NameForm() { const firstName = createState('John') const lastName = createState('Doe')
// Computed como função const fullName = () => `${firstName.get()} ${lastName.get()}`
// Watcher firstName.watch((newVal) => { console.log('First name changed:', newVal) })
return html` <div> <input value=${firstName.get()} oninput=${(e) => firstName.set(e.target.value)} /> <input value=${lastName.get()} oninput=${(e) => lastName.set(e.target.value)} /> <p>${fullName()}</p> </div> `}<!-- Vue 3 --><script setup>import { ref, onMounted, onUnmounted } from 'vue'
const seconds = ref(0)let interval
onMounted(() => { interval = setInterval(() => { seconds.value++ }, 1000)})
onUnmounted(() => { clearInterval(interval)})</script>
<template> <p>Seconds: {{ seconds }}</p></template>// Slashimport { html, createState } from '@ezbug/slash'
function Timer() { const seconds = createState(0)
const interval = setInterval(() => { seconds.set(seconds.get() + 1) }, 1000)
// Cleanup automático onCleanup(() => clearInterval(interval))
return html`<p>Seconds: ${seconds.get()}</p>`}Performance
Section titled “Performance”Bundle Size
Section titled “Bundle Size”# Slash (produção, minified + gzip)@ezbug/slash: ~5KB
# Vue 3 (produção, minified + gzip)vue: ~34KBImpacto: Slash é ~7x menor que Vue 3.
Runtime Performance
Section titled “Runtime Performance”| Operação | Slash | Vue 3 | Vue 3 (compiler optimized) |
|---|---|---|---|
| First Render | 8ms | 15ms | 12ms |
| Update (1 campo) | 1ms | 3ms | 2ms |
| Update (100 campos) | 15ms | 45ms | 25ms |
| List (1000 items) | 120ms | 280ms | 180ms |
Observações:
- Slash é mais rápido em updates pequenos (sem VDOM diff)
- Vue 3 compiler otimiza bastante
- Para apps grandes, diferença diminui
Template vs HTM
Section titled “Template vs HTM”Vue: Template Strings Compilados
Section titled “Vue: Template Strings Compilados”<template> <div class="container"> <h1>{{ title }}</h1> <ul> <li v-for="item in items" :key="item.id"> {{ item.name }} </li> </ul> </div></template>Vantagens:
- ✅ Syntax highlighting
- ✅ Validação em build time
- ✅ Otimizações do compiler
- ✅ Familiar para quem vem de HTML
Desvantagens:
- ❌ Requer build step
- ❌ Diretivas customizadas (
v-if,v-for) - ❌ Menos flexibilidade que JS puro
Slash: HTM (Runtime)
Section titled “Slash: HTM (Runtime)”import { html } from '@ezbug/slash'
const Component = ({ title, items }) => html` <div class="container"> <h1>${title}</h1> <ul> ${items.map(item => html` <li key=${item.id}>${item.name}</li> `)} </ul> </div>`Vantagens:
- ✅ Sem build step necessário
- ✅ JavaScript puro (map, filter, if ternário)
- ✅ Mais flexível
- ✅ TypeScript direto
Desvantagens:
- ❌ Sem otimizações de compiler
- ❌ Parsing em runtime
- ❌ Syntax highlighting limitado
Ecossistema
Section titled “Ecossistema”Frameworks:
- Nuxt 3 (SSR/SSG framework robusto)
- Quasar (UI framework completo)
- Vitepress (documentação)
Bibliotecas:
- Pinia (state management oficial)
- Vue Router (routing oficial)
- VueUse (collection de composables)
- Vuetify, Element Plus, Ant Design Vue (UI libs)
Ferramentas:
- Vue DevTools (excelente)
- Vite (build tool oficial)
- Vue Language Server
Status Atual:
- ✅ Router integrado
- ✅ SSR nativo
- ✅ Data loading isomórfico
- 🌱 Ecossistema crescendo
- 📦 Foco em simplicidade
Casos de Uso
Section titled “Casos de Uso”Quando Usar Vue
Section titled “Quando Usar Vue”-
Aplicações Empresariais
- Necessita de ecosystem maduro
- UI components prontos importantes
- Suporte e comunidade grandes
-
Projetos com Build Pipeline
- Compiler optimizations importantes
- Single File Components (.vue) desejado
- Vite/Webpack já configurado
-
Time com Experiência Vue
- Developers já conhecem Vue
- Patterns estabelecidos
- Migração de Vue 2
-
Necessidade de Nuxt
- SSR/SSG avançado
- File-based routing
- Modules ecosystem
Quando Usar Slash
Section titled “Quando Usar Slash”-
Simplicidade e Performance
- Bundle size crítico
- Performance > conveniences
- Sem build step desejado
-
Prototipagem Rápida
- MVPs rápidos
- Sem setup de build
- Drop-in via CDN
-
Aprendizado
- Entender reatividade fundamental
- Sem abstrações
- TypeScript first-class
-
Micro Frontends
- Apps pequenas isoladas
- Baixo overhead
- Fácil integração
Migração de Vue para Slash
Section titled “Migração de Vue para Slash”Conceitos Mapeados
Section titled “Conceitos Mapeados”| Vue 3 | Slash | Notas |
|---|---|---|
ref() | createState() | Slash usa .get(), .set() e .watch() |
computed() | Funções | Apenas funções normais |
watch() | state.watch() | API similar (Observer Pattern) |
v-if | Ternário ? : | JavaScript nativo |
v-for | .map() | JavaScript nativo |
v-model | value + oninput | Binding manual |
onMounted | Código direto | Executa na criação |
onUnmounted | onCleanup() | Cleanup function |
props | Function params | TypeScript interfaces |
emit | Callbacks | Funções em props |
Exemplo de Migração
Section titled “Exemplo de Migração”<!-- Vue 3 --><script setup>import { ref, computed } from 'vue'
const todos = ref([])const filter = ref('all')
const filteredTodos = computed(() => { if (filter.value === 'active') { return todos.value.filter(t => !t.done) } if (filter.value === 'completed') { return todos.value.filter(t => t.done) } return todos.value})
function addTodo(text) { todos.value.push({ id: Date.now(), text, done: false })}</script>
<template> <div> <ul> <li v-for="todo in filteredTodos" :key="todo.id"> {{ todo.text }} </li> </ul> </div></template>// Slashimport { html, createState } from '@ezbug/slash'
function TodoList() { const todos = createState([]) const filter = createState('all')
const filteredTodos = () => { const f = filter.get() const t = todos.get()
if (f === 'active') return t.filter(t => !t.done) if (f === 'completed') return t.filter(t => t.done) return t }
const addTodo = (text) => { todos.set([ ...todos.get(), { id: Date.now(), text, done: false } ]) }
return html` <div> <ul> ${filteredTodos().map(todo => html` <li key=${todo.id}>${todo.text}</li> `)} </ul> </div> `}Trade-offs Principais
Section titled “Trade-offs Principais”Prós:
- ✅ Ecossistema maduro e rico
- ✅ Compiler optimizations
- ✅ Template syntax familiar
- ✅ Excelentes ferramentas (DevTools, Volar)
- ✅ Documentação extensa
- ✅ Comunidade grande
Contras:
- ❌ Bundle maior
- ❌ Virtual DOM overhead
- ❌ Necessita build step para melhor DX
- ❌ Mais abstrações/magic
- ❌ Curva de aprendizado maior
Prós:
- ✅ Extremamente leve (~5KB)
- ✅ Performance excelente
- ✅ API simples e explícita
- ✅ Sem build step necessário
- ✅ TypeScript first-class
- ✅ Sem magic, previsível
Contras:
- ❌ Ecossistema menor
- ❌ Sem compiler optimizations
- ❌ Mais verboso em alguns casos
- ❌ Ferramentas em desenvolvimento
- ❌ Comunidade pequena
Conclusão
Section titled “Conclusão”Escolha Vue 3 se:
- Precisa de ecosystem robusto
- Quer Nuxt para SSR/SSG
- Valoriza DX com compiler
- Prefere template syntax
- Team já conhece Vue
- Projeto médio/grande
Escolha Slash se:
- Performance/size críticos
- Prefere simplicidade
- Não quer build step
- Gosta de explicitness
- Projeto pequeno/médio
- Quer controle total
Ambas são ótimas escolhas. Vue é mais “batteries included”, Slash é minimalista e direto.
Próximos Passos
Section titled “Próximos Passos”- Slash vs React - Comparação com React
- Slash vs Solid - Comparação com SolidJS
- Exemplos Práticos - Apps completas