Modelo de Framework Vue com Setup

Para facilitar a compreensão, dividi o setup em várias seções distintas:

<script setup>
    // 1. Importação de dependências necessárias, como ref, reactive, etc.

    // 2. Definição de props, ou seja, dados recebidos pelo componente

    // 3. Definição de data, ou seja, dados internos do componente

    // 4. Definição de emits, ou seja, eventos do componente

    // 5. Definição de methods, ou seja, métodos do componente

    // 6. Definição de computed, ou seja, propriedades computadas

    // 7. Definição de watch, ou seja, observadores de dados

    // 8. Definição do ciclo de vida do componente

    // 9. Definição da interface exposta pelo componente
   
</script>

1. Importação de dependências

<script setup>
    // Dependências comuns do Vue
    import {
        ref,
        reactive,
        toRefs,
        computed,
        watch,
        onMounted,
        onUpdated,
        onUnmounted,
        getCurrentInstance
    } from 'vue'

    // Algumas funções não precisam de importação, como:
    // defineProps, defineEmits, defineExpose

    // Importação de funções ou interfaces externas
    import $utils from '@/common/js/utils.js'
</script>

2. Definição de props

<script setup><br></br>    // Método 1: Definição simples de props<br></br>    //const props = defineProps(['propA', 'propB'])<br></br><br></br>    // Método 2: Definição detalhada de props<br></br>    // Recomenda-se usar o método 2 para configuração rigorosa de cada prop
    const props = defineProps({
        
        // Verificação básica de tipo (`null` e `undefined` passam por qualquer validação)
        valorNumerico: Number,
        
        // Múltiplos tipos possíveis
        valorAlfanumerico: [String, Number],
        
        // String obrigatória
        textoObrigatorio: {
            type: String,
            required: true
        },
        
        // Número com valor padrão
        numeroPadrao: {
            type: Number,
            default: 100
        },
        
        // Objeto com valor padrão
        objetoPadrao: {
            type: Object,
            // Objetos ou arrays precisam de uma função factory para valores padrão
            default: function() {
                return {
                    mensagem: 'olá'
                }
            }
        },
        
        // Função de validação personalizada
        valorValidado: {
            validator: function(valor) {
                // O valor deve corresponder a uma das strings abaixo
                return ['sucesso', 'alerta', 'perigo'].indexOf(valor) !== -1
            }
        }
    })

    // No script, use props.valorNumerico para acessar o valor
    // No template, use a sintaxe de interpolação: <view>{{valorNumerico}}</view>
    // Se não precisar acessar no script, pode usar defineProps({})
</script>

Observações:

  1. Recomenda-se usar a convenção camelCase para props, distinguindo maiúsculas de minúsculas. Por exemplo: classeArtigo
  2. Os tipos disponíveis para validação são:
  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol
  1. Não é possível acessar outras variáveis definidas em <script setup> dentro de default ou validator, pois toda a expressão é movida para uma função externa durante a compilação.
  2. Por padrão, quando um componente contém atributos não listados nas props, esses atributos são diretamente anexados ao elemento raiz do componente. Por exemplo:

Código do componente teste: <input type="text" class="conta"/>

Ao chamar o componente teste no componente pai, adicionando os atributos type e class, que não estão definidos nas props do componente teste: <teste class="entrada" type="numero"/>

O código do componente se torna: <teste class="conta entrada" type="numero"/>

O princípio adotado é: atributos, exceto class e style, são substituídos. Class e style são mesclados.

Se não desejar que o elemento raiz do componente herde atributos, pode definir inheritAttrs: false nas opções do componente. No entanto, inheritAttrs não afeta o binding de class e style!

Como o Vue setup não suporta opções de configuração, precisamos configurar em um <script> separado:

<script>
    export default {
        inheritAttrs: false
    }
</script>

  1. Para o binding de dados bidirecional (v-model) e modificadores, consulte: https://vuejs.org/guide/components/v-model.html

3. Definição de dados

Abaixo estão as funções reativas para definição de dados. É importante compreender profundamente essas funções:

4. Eventos personalizados

Componente teste.vue

<template>
    <button @click="instancia.emit('obterInfo', estudante)">Clique para enviar informações do estudante para o componente pai</button>
</template>

<script setup>
    import {
        reactive,
        getCurrentInstance
    } from 'vue'


    var estudante = reactive({
        nome: 'João Silva',
        idade: 18,
        contato: {
            telefone: '21987654321',
            whatsapp: '21987654322',
            email: 'joao.silva@example.com'
        }
    })

    // Definição: evento personalizado
    defineEmits(['obterInfo'])

    // Definição de evento com função de validação
    // Mesmo que a validação falhe, o componente pai ainda será executado. Apenas um aviso é exibido no console: [Vue warn]: Invalid event arguments: event validation failed for event "obterInfo".
    // Portanto, a validação tem utilidade limitada.
    //defineEmits({
    //    'obterInfo': estudante => {
    //        return estudante.idade > 18 ? true : false
    //    }
    //})

    // Obtenção da instância atual
    var instancia = getCurrentInstance()
</script>

Componente pai chamando o evento:

<template>
    <teste ref="estudante" @obterInfo="imprimirEstudante"></teste>
</template>

<script setup>
    function imprimirEstudante(dados) {
        console.log(dados.nome);
    }
</script>

5. Definição de métodos do componente

Os métodos do componente são definidos como funções JavaScript comuns:

function metodo1(param1, param2) {
    // lógica do método...
}

const metodo2 = (param1, param2)=>{
    // lógica do método...
}

6. Definição de propriedades computadas

Sintaxe básica:

const contadorIncrementado = computed(() => contador.value + 1)

Sintaxe completa:

const propriedadeComputada = computed({
    get() {
        return contador.value
    },
    set(valor) {
        contador.value = valor
    }
})

Para mais informações sobre computed(), consulte: https://vuejs.org/api/reactivity-core.html#computed

Métodos relacionados a efeitos e escopos: effectScope(), getCurrentScope(), onScopeDispose()

Consulte: https://vuejs.org/api/reactivity-advanced.html#effectscope

7. Definição de observadores de dados

No setup, é possível usar watch() ou watchEffect() para observar mudanças nos dados. Ambas as funções precisam ser importadas.

<script setup>
    import {
        watch,
        watchEffect
    } from 'vue'
</script>

Para mais informações sobre watch() e watchEffect(), consulte: https://vuejs.org/api/reactivity-core.html#watch

Métodos relacionados a efeitos e escopos: effectScope(), getCurrentScope(), onScopeDispose()

Consulte: https://vuejs.org/api/reactivity-advanced.html#effectscope

8. Ciclo de vida do componente

onBeforeMount(), onMounted(), onBeforeUnmount(), onUnmounted()

Descrição: Ciclos de vida de montagem e desmontagem do componente

Consulte: https://vuejs.org/api/composition-api-lifecycle.html

onBeforeUpdate(), onUpdated()

Descrição: Ciclos de vida de atualização de visualização

Consulte: https://vuejs.org/api/composition-api-lifecycle.html

onActivated(), onDeactivated()

Descrição: Ciclos de vida de componentes mantidos em cache pelo

Consulte: https://vuejs.org/api/composition-api-lifecycle.html#onactivated

9. Exposição de interface do componente

Um componente pode expor seus dados e métodos internos para o componente chamador através da função defineExpose().

A função defineExpose() não precisa ser importada e pode ser usada diretamente.

Em , o defineExpose() está desativado por padrão.

<script setup>
    import {
        ref
    } from 'vue'
    
   const quantidade = ref(0)
   const processar = ()=>{
       // lógica do método...
   }
    
   defineExpose({
       quantidade, // exposição de dados
       processar  // exposição de métodos
   })
</script>

Tags: Vue.js Setup API Reatividade

Publicado em 6-13 21:09 por Thomas