Esquema

Introdução

O esquema do FormKit é um formato de dados serializável em JSON para armazenar estruturas DOM e implementações de componentes, incluindo formulários do FormKit. Embora criado especificamente para implementar e gerar formulários, o formato é capaz de gerar qualquer marcação HTML ou usar quaisquer componentes de terceiros.

Esquemas são renderizados usando o componente <FormKitSchema> do FormKit, que não é registrado globalmente por padrão. Você precisará importá-lo:

import { FormKitSchema } from '@formkit/vue'

Exemplo de geração de formulário

O FormKit vem com suporte de primeira classe para gerar formulários usando esquema. Isso torna possível armazenar formulários gerados em bancos de dados, arquivos ou até mesmo códigos QR! Para gerar um formulário, passe sua matriz de esquema para o componente <FormKitSchema> usando a propriedade :schema.

<FormKitSchema :schema="yourSchemaArray" />

Vamos olhar um exemplo rápido:

Carregar exemplo ao vivo

Vemos muitos recursos acima, incluindo as propriedades $el e $cmp, o atalho da propriedade $formkit, validação, renderização condicional, rótulos, texto de ajuda e vários tipos de entradas. Vamos desempacotar todos esses recursos no restante desta página.

Matriz de esquema

Um esquema é uma matriz de objetos ou strings (chamados de "nós de esquema"), onde cada item da matriz define um único nó de esquema. Existem 3 tipos de nós de esquema:

  1. Nós de texto — produzidos por strings.
  2. Elementos HTML — definidos pela propriedade $el.
  3. Componentes — definidos pela propriedade $cmp.
  4. Componentes do FormKit — definidos pela propriedade $formkit. Açúcar sintático para o formato completo $cmp.

Esquemas suportam recursos avançados como lógica condicional, operadores booleanos, laços, slots e escopo de dados — todos garantidos para serializar em uma string.

Elementos HTML ($el)

Elementos HTML são definidos usando a propriedade $el. Você pode usar $el para renderizar qualquer elemento HTML. Atributos podem ser adicionados com a propriedade attrs, e o conteúdo é atribuído com a propriedade children:

Carregar exemplo ao vivo
tip

Note no exemplo acima que o atributo style é único no sentido de que deve ser definido como um objeto de pares de estilo para valor em vez de uma string.

Componentes ($cmp)

Componentes podem ser definidos com a propriedade $cmp. A propriedade $cmp deve ser uma string que referencia um componente globalmente definido ou um componente passado para FormKitSchema com a prop library:

Carregar exemplo ao vivo
Componentes como props

Para passar componentes concretos via prop library, é melhor envolver sua biblioteca com a assinatura markRaw do Vue.

Referências

Além do array de esquema (e da biblioteca opcional), o objeto FormKitSchema também pode incluir uma prop data. Valores do objeto data podem então ser referenciados diretamente no seu esquema — e seu esquema manterá a reatividade do objeto de dados original.

Para referenciar um valor do objeto data, você simplesmente usa um cifrão $ seguido pelo nome da propriedade do objeto de dados. Referências podem ser usadas em attrs, props, condicionais e como children:

Carregar exemplo ao vivo
Nota importante

Note no exemplo acima que usamos um array para concatenar "Hello" e "$location". Fizemos isso porque referências de dados e expressões lógicas no esquema devem sempre começar com um cifrão $ — caso contrário, são tratadas como literais de string não analisadas.

Referenciando funções

Esquemas suportam a chamada de funções que estão nos seus dados de referência originais — e você pode até passar referências de dados como argumentos dessa função!

Carregar exemplo ao vivo

Referências profundas

Assim como em JavaScript — você pode acessar propriedades de um objeto profundamente aninhado usando a sintaxe de ponto object.property:

Carregar exemplo ao vivo
Palavras reservadas

Referências de esquema podem ter qualquer estrutura ou propriedades, mas na raiz do objeto de referência de dados existem 2 palavras reservadas: $slots e $get.

Expressões

Esquemas também suportam lógica na forma de lógica booleana, comparação e expressões aritméticas. Essas expressões podem ser usadas em qualquer lugar onde uma referência de dados possa ser usada (attrs, props, condicionais e children):

Carregar exemplo ao vivo
Rotulando expressões

Expressões devem sempre começar com um $. Se o primeiro elemento de uma expressão é uma referência de dados (ex: $count + 2), então ela já começa com um $ e nenhum outro rótulo é necessário. No entanto, muitas vezes o primeiro caractere de uma expressão não é um cifrão — essas expressões precisam ser "rotuladas" com $: — por exemplo $: ($count * 3) - 7.

Embora pareça muito com JavaScript — expressões de esquema não são JavaScript. É melhor pensar nelas como uma linguagem de template. Expressões são compiladas para JavaScript funcional no setup, mas a sintaxe não é compatível 1-1 com JavaScript. Isso melhora o desempenho e fornece uma camada crítica de segurança, pois apenas dados e funcionalidades explicitamente expostos podem ser executados.

Expressões de esquema são limitadas aos seguintes operadores e parênteses:

OperadorCaso de uso
+Adição
-Subtração
*Multiplicação
/Divisão
%Módulo
&&E lógico (AND)
||OU lógico (OR)
===Igualdade estrita
!==Desigualdade estrita
==Igualdade solta
!=Desigualdade solta
>=Maior ou igual
<=Menor ou igual
>Maior que
<Menor que

Condicionais

O esquema do FormKit pode aproveitar referências e expressões para tornar nós e atributos do esquema condicionais. Esses condicionais podem ser adicionados de duas maneiras:

  • A propriedade if nos nós $el e $cmp.
  • O objeto if/then/else

A propriedade if

Tanto os nós de esquema $el quanto $cmp podem aproveitar uma propriedade if que se assemelha aproximadamente a um v-if no Vue. Se a expressão atribuída à propriedade if for verdadeira, o nó é renderizado, caso contrário, não é:

Carregar exemplo ao vivo
Garanta a re-renderização com uma chave

Nós de esquema condicionais ou iterativos (quando usando if ou for) devem sempre incluir uma propriedade key explícita. Sem essa propriedade, o Vue pode reutilizar os nós do DOM da renderização anterior, o que pode levar a comportamentos inesperados, erros e problemas de desempenho.

O objeto if/then/else

O objeto if/then/else permite uma lógica condicional mais complexa. Ele pode ser usado para renderizar condicionalmente nós, uma lista de nós de esquema, valores do objeto attrs ou valores do objeto props. Também é possível aninhar objetos if/then/else para criar estruturas mais complexas — semelhante a uma declaração else if em JavaScript.

Usando if/then/else em nós de esquema

Você pode usar o objeto if/then/else em qualquer lugar onde normalmente usaria um nó de esquema. Isso inclui o array de esquema raiz ou a propriedade children de outro nó de esquema:

Garanta a re-renderização com uma chave

Nós de esquema condicionais ou iterativos (quando usando if ou for) devem sempre incluir uma propriedade key explícita. Sem essa propriedade, o Vue pode reutilizar os nós do DOM da renderização anterior, o que pode levar a comportamentos inesperados, erros e problemas de desempenho.

Carregar exemplo ao vivo

Usando if/then/else em attrs e props

Você também pode usar declarações if/then/else para produzir condicionalmente os valores de attrs ou props:

Carregar exemplo ao vivo

Laços

Tanto os nós de esquema $el quanto $cmp suportam laços. A sintaxe do laço é semelhante a v-for no Vue e espera um objeto ou array para iterar e uma propriedade para atribuir o valor da iteração atual. Opcionalmente, você também pode capturar o índice ou a propriedade da iteração atual:

Garanta a re-renderização com uma chave

Nós de esquema condicionais ou iterativos (quando usando if ou for) devem sempre incluir uma propriedade key explícita. Sem essa propriedade, o Vue pode reutilizar os nós do DOM da renderização anterior, o que pode levar a comportamentos inesperados, erros e problemas de desempenho.

Carregar exemplo ao vivo

Slots

Esquemas podem renderizar o conteúdo do slot do componente <FormKitSchema> em qualquer lugar dentro do esquema onde um nó de esquema normal possa ser renderizado. Todos os slots com escopo são automaticamente fornecidos ao esquema sob o objeto de referência $slots:

Carregar exemplo ao vivo
Slots de entrada do FormKit

Dentro de um nó de esquema $formkit, também é possível passar conteúdo para slots preexistentes do FormKit como label ou prefix dentro da propriedade do nó __raw__sectionsSchema. Leia mais sobre valores brutos abaixo, e sectionsSchema na documentação de entradas.

Vinculando attrs e props

Às vezes pode ser necessário passar um objeto de atributos ou props variáveis ou desconhecidos para um $cmp ou $el. No Vue faríamos isso usando v-bind — no mundo dos esquemas usamos a propriedade bind:

Carregar exemplo ao vivo

Valores brutos

Às vezes pode ser necessário impedir que um dado atributo ou prop seja analisado. Isso pode ser feito prefixando um atributo ou prop com __raw__:

{
  $cmp: 'PriceComponent',
  props: {
    __raw__price: '$2.99'
  }
}

No exemplo acima, o prefixo __raw__ será removido, e o valor não analisado de $2.99 será passado como a prop price para o PriceComponent.

Outro cenário onde isso é útil é na renderização de componentes FormKit. O componente <FormKit> tem uma prop sections-schema que permite aos usuários passar partes de esquemas para mesclar com várias seções de sua entrada. Neste caso específico, queremos passar os pedaços do esquema para o componente <FormKit> como um objeto JavaScript bruto. Para fazer isso, mais uma vez prefixamos a prop sectionsSchema com __raw__:

Carregar exemplo ao vivo

Note que se você remover o prefixo __raw__ do exemplo acima, o prefixo não terá mais efeito — isso ocorre porque o valor da prop sectionsSchema foi analisado ao criar o componente em vez de ser passado como um objeto JavaScript.

Entradas FormKit

Embora os esquemas possam ser usados para quase qualquer finalidade — o objetivo principal é capacitar os desenvolvedores a construir formulários complexos e dinâmicos usando um formato de dados serializável. Usar o esquema com as Entradas FormKit cobre bem esse caso de uso.

Assumindo que você registrou globalmente o componente FormKit — você pode renderizar suas entradas FormKit a partir do esquema usando o nó de esquema do tipo $cmp:

Carregar exemplo ao vivo

Abreviação

Embora a sintaxe cmp seja generalizada e funcione para qualquer componente Vue, ela é um tanto verbosa para os Inputs do FormKit. Para facilitar isso, o FormKit suporta um quarto tipo de nó $formkit, que é um açúcar sintático para o formato completo $cmp.

Ao usar a abreviação $formkit, o objeto props é achatado com as propriedades de nível superior (irmãos de $formkit) Por exemplo:

Carregar exemplo ao vivo

Acessando outros inputs

O formato do esquema tem uma função embutida específica para os Inputs do FormKit: a função $get. Esse builtin permite que o esquema acesse o objeto de contexto de qualquer outro Input do FormKit (mesmo fora do formulário imediato) — desde que o input em questão tenha uma propriedade id explicitamente declarada. Isso permite que o esquema responda condicionalmente ao estado dos seus próprios inputs:

Carregar exemplo ao vivo

Formulários

Para renderizar um elemento de formulário, você pode usar o nó de esquema $formkit: 'form', ou envolver seu componente <FormKitSchema> em um componente <FormKit type="form">:

Carregar exemplo ao vivo