terça-feira, 18 de setembro de 2018

Tutorial VUE - Exemplo Formulários

O recurso mais procurado para solução em sistemas de informação é o formulário para entrada de dados.

Neste exemplo, vamos explicar a melhor forma de implementar os formulários utilizando o VUE.

Arquivo de configuração

Para utilizar o VUE, vá se acostumando aos arquivos de configuração sob a forma de arrays objeto. Abaixo listamos o arquivo de configuração para este fim:

var arrOpcoes = [
{ campo: 'Id', tipo: 'N', obrigatorio: 'N', titulo: 'Identificador', tamanho: 6, cor: '#002A36', soLeitura: true, imagem: '', link: '', checked: true, secao: 'form' , destino:'',quadro:''},
{ campo: 'Descri', tipo: 'T', obrigatorio: 'N', titulo: 'Descrição', tamanho: 50, cor: '#003745', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'' ,quadro:''},
{ campo: 'Area', tipo: 'T', obrigatorio: 'S', titulo: 'Área', tamanho: 4, cor: '#003745', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'' ,quadro:''},
{ campo: 'DtNascto', tipo: 'D', obrigatorio: 'N', titulo: 'Data de Nascimento', tamanho: 10, cor: '#003745', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'' ,quadro:''},
{ campo: 'UF', tipo: 'T', obrigatorio: 'N', titulo: 'Uf', tamanho: 2, cor: '#003745', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'' ,quadro:'', multivalue: [{vr:"", descri: "[Escolha a UF]"},{vr:"AC", descri: "Acre"},{vr:"AM", descri: "Amapá"},{vr:"MG", descri: "Minas Gerais"},{vr:"RJ", descri: "Rio de Janeiro"},{vr:"SP", descri: "São Paulo"}]},
{ campo: 'VrNo', tipo: 'N', obrigatorio: 'N', titulo: 'Número', tamanho: 6, cor: '#002A36', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'',quadro:''}
];
var arrCabecalhos = {
form:{nome:"ENTRADA DE DADOS PADRÃO", acao: "" },
traj:{ nome:"MAPA", acao:""}
};

arrOpcoes - contém as informações de configuração de cada campo do formulário, de acordo com as seguintes convenções:

campo: nome do campo na tabela do banco de dados;
tipo: "N"umérico, "T"exto ou "D"ata;
obrigatório: "N"ão obrigatório ou "S" obrigatório;
título: Descrição que aparece à frente do campo INPUT no formulário;
tamanho: Tamanho do campo na tabela do banco de dados;
cor: cor da letra usada para descrição do campo no formulário;
soLeitura: Diz se o campo será somente leitura no INPUT do formulário;
imagem: Para uso futuro;
link: Para uso futuro;
checked: Seleção dos campos a serem exibidos;
secao: campo para filtragem de grupos de campos para diversos fins do formulário;
destino: Para uso futuro;
quadro: Para uso futuro;
multivalue: Array para armazenamento de opções de campos do tipo HTML Select;

Como o VUE exibe conteúdos de arranjos

O recurso mais utilizado pelo VUE é justamente o de prover conteúdo dinâmico a partir de arranjos. E justamente será este arranjo de opções, mostrado anteriormente, o ponto de apoio para isto. O trecho mais importante para este fim é:

<table border=0>
<tr v-for="opcao in opcoes" v-if="opcao.checked && opcao.secao == action">
<td>
<label v-bind:style="{fontWeight:negrito, color: opcao.cor}">{{ opcao.titulo }}</label>
</td>
<td>
 <input v-bind:id="opcao.campo" v-bind:size="opcao.tamanho" v-bind:readonly="opcao.soLeitura" />
</td>
</tr>
</table>

Explicação

Os campos serão, cada um, linhas de uma tabela HTML. Para enumerá-los, estabelecemos um loop na tag TR, que corresponde à linha da tabela.

A explicação se inicia a partir da variável opcoes. Esta é uma variável a ser declarada no corpo do javascript, no momento da instanciação do objeto Vue:

var v1 = new Vue({ 
el: '#app', 
data: data,
watch: {
action: {
handler: function (linque) {
console.log("w: "+arguments.callee.name+" vis: "+this.action)
},
deep: true
},
opcoes: {
handler: function (linque) {
console.log("w: "+arguments.callee.name)
},
deep: true
}
},
methods: {
goLink: function (linque,quadro) {
this.action = linque;
if( quadro != '' ){
houveQuadro = true;
} else {
houveQuadro = false;
}
},
viraPagina: function(){ 
this.mostraForm=true; 
}
}
});

Estando na seção watch do Vue, informamos a ele para manter um monitoramento dinâmico desta variável. Mas qual é o protótipo da mesma. Vejamos a seção data do mesmo objeto Vue. Ela aponta para outro data, desta vez uma variável, array ou objeto, no corpo do javascript FORA do objeto Vue:

var data = { 
negrito: 'bold',
opcoes: arrOpcoes,
cabecalhos : arrCabecalhos,
cabecalho: 'SUPORTE', 
linque:'',
novoopcao: '',
novoimagem: '',
mostraForm:false,
houveQuadro:false,
action:'form'
};

Aqui verificamos que opcoes aponta para uma variável, array ou objeto arrOpcoes, definido anteriormente (ao final exibiremos o código completo):

var arrOpcoes = [
{ campo: 'Id', tipo: 'N', obrigatorio: 'N', titulo: 'Identificador', tamanho: 6, cor: '#002A36', soLeitura: true, imagem: '', link: '', checked: true, secao: 'form' , destino:'',quadro:''},
{ campo: 'Descri', tipo: 'T', obrigatorio: 'N', titulo: 'Descrição', tamanho: 50, cor: '#003745', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'' ,quadro:''},
{ campo: 'Area', tipo: 'T', obrigatorio: 'S', titulo: 'Área', tamanho: 4, cor: '#003745', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'' ,quadro:''},
{ campo: 'DtNascto', tipo: 'D', obrigatorio: 'N', titulo: 'Data de Nascimento', tamanho: 10, cor: '#003745', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'' ,quadro:''},
{ campo: 'UF', tipo: 'T', obrigatorio: 'N', titulo: 'Uf', tamanho: 2, cor: '#003745', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'' ,quadro:'', multivalue: [{vr:"", descri: "[Escolha a UF]"},{vr:"AC", descri: "Acre"},{vr:"AM", descri: "Amapá"},{vr:"MG", descri: "Minas Gerais"},{vr:"RJ", descri: "Rio de Janeiro"},{vr:"SP", descri: "São Paulo"}]},
{ campo: 'VrNo', tipo: 'N', obrigatorio: 'N', titulo: 'Número', tamanho: 6, cor: '#002A36', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'',quadro:''}
];

v-for

Como v-for percorre estes valores ? O atributo v-for (v-for="opcao in opcoes") estabelece um loop neste array-objeto, de forma que a coleção de itens existente possa ser escaneada

v-if

Em qualquer contexto do Vue podemos fazer uma filtragem dos elementos a serem considerados. Como isto é feito ? O atributo v-if ( v-if="opcao.checked && opcao.secao == action") condiciona a escolha destes itens.

Conclusão intermediária

Portanto, a tag

<tr v-for="opcao in opcoesv-if="opcao.checked && opcao.secao == action">

percorre os valores de arrOpcoes (devido às ligações estabelecidas pelo data) colocando cada item na variável opcao, caso a propriedade (ou atributo) secao tenha o valor armazenado na variável action:

var data = { 
negrito: 'bold',
opcoes: arrOpcoes,
cabecalhos : arrCabecalhos,
cabecalho: 'SUPORTE', 
linque:'',
novoopcao: '',
novoimagem: '',
mostraForm:false,
houveQuadro:false,
action:'form'
};

v-bind:style

O modificador v-bind, em conjunto com qualquer atributo HTML, faz com que o valor seja obtido em segundo nível. O que vem a ser isto ? Ao invés de encarar o conteúdo do atributo tal como está, ele executa um "eval" da expressão. Ou seja, se a expressão é uma chamada de função, a função é chamada, e o valor aproveitado é o resultado dela. Se for uma variável, o valor considerado será o conteúdo desta última variável:

v-bind:style="{fontWeight:negrito, color: opcao.cor}"

Como o atributo aqui discutido é o style, deduzimos que toda a expressão sofrerá um "eval" do Javascript. Mas existem algumas observações a serem feitas, neste caso:

O style está realmente no formato JSON;
Não foi utilizada a cláusula de style "font-weight" do CSS3, e sim uma forma já interna do VUE. Todas as cláusulas compostas do CSS3, separadas por hifens, deverão ser expressas nesta notação (primeira letra que sucede o hífen será maiúscula);
O conjunto de estilos estará entre chaves;
Os estilos estarão separados por "," (vírgula) e não ";" (ponto e vírgula);

v-bind no INPUT

O que aconteceu em relação ao estilo na tag LABEL também se dará com a tag INPUT:

<input v-bind:id="opcao.campo" v-bind:size="opcao.tamanhov-bind:readonly="opcao.soLeitura" />

v-bind:id - Terá como valor o conteúdo da propriedade opcao.campo;
v-bind:size - Terá como valor o conteúdo da propriedade opcao.tamanho;
v-bind:readonly - Terá como valor o conteúdo da propriedade opcao.soLeitura;
Código completo
<html>
<head>
<title>Menu Vert.</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript" src="CRUD_menuOpcoes.js"></script>
<script type="text/javascript">
function init(){
// Comando 1
var data = { 
negrito: 'bold',
opcoes: arrOpcoes,
cabecalhos : arrCabecalhos,
cabecalho: 'SUPORTE', 
linque:'',
novoopcao: '',
novoimagem: '',
mostraForm:false,
houveQuadro:false,
action:'form'
};
// Comando 2
var v1 = new Vue({ 
el: '#app', 
data: data,
watch: {
action: {
handler: function (linque) {
console.log("w: "+arguments.callee.name+" vis: "+this.action)
},
deep: true
},
opcoes: {
handler: function (linque) {
console.log("w: "+arguments.callee.name)
},
deep: true
}
},
methods: {
goLink: function (linque,quadro) {
this.action = linque;
if( quadro != '' ){
houveQuadro = true;
} else {
houveQuadro = false;
}
},
viraPagina: function(){ 
this.mostraForm=true; 
}
}
});
setTimeout(function(){v1.viraPagina();}, 1500);
}
</script>
<style>
A,A:link { color: midnightblue; text-decoration: none; }
BIG { font-size: 22px; }
BUTTON {
background-color: white; border-width: 0px; color: midnightblue;
font-weight: bold; width: 200px;
}
DIV#app { font-family: Arial; font-size: 16px; width: 320px; }
H2 { color: midnightblue; font-weight: bold; }
P { color: midnightblue; }
</style>
</head>
<body onload="init();">
<div id="app" class="container">
<div id="cabecalho" v-show="!mostraForm">
<center><h1>CRUD</h1></center>
</div>
<div id="menus" v-show="mostraForm">
<center>
<h2>{{cabecalhos["form"].nome}}</h2>
</center>
<center>
<table border=0>
<tr v-for="opcao in opcoes" v-if="opcao.checked && opcao.secao == action">
<td>
<label v-bind:style="{fontWeight:negrito, color: opcao.cor}">{{ opcao.titulo }}</label>
</td>
<td>
<input v-bind:id="opcao.campo" v-bind:size="opcao.tamanho" v-bind:readonly="opcao.soLeitura" />
</td>
</tr>
</table>
</center>
<div class="footer">
<hr/>
</div>
</div>
</div>
</body>
</html>

CRUD_menuOpcoes.js

var arrOpcoes = [
{ campo: 'Id', tipo: 'N', obrigatorio: 'N', titulo: 'Identificador', tamanho: 6, cor: '#002A36', soLeitura: true, imagem: '', link: '', checked: true, secao: 'form' , destino:'',quadro:''},
{ campo: 'Descri', tipo: 'T', obrigatorio: 'N', titulo: 'Descrição', tamanho: 50, cor: '#003745', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'' ,quadro:''},
{ campo: 'Area', tipo: 'T', obrigatorio: 'S', titulo: 'Área', tamanho: 4, cor: '#003745', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'' ,quadro:''},
{ campo: 'DtNascto', tipo: 'D', obrigatorio: 'N', titulo: 'Data de Nascimento', tamanho: 10, cor: '#003745', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'' ,quadro:''},
{ campo: 'UF', tipo: 'T', obrigatorio: 'N', titulo: 'Uf', tamanho: 2, cor: '#003745', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'' ,quadro:'', multivalue: [{vr:"", descri: "[Escolha a UF]"},{vr:"AC", descri: "Acre"},{vr:"AM", descri: "Amapá"},{vr:"MG", descri: "Minas Gerais"},{vr:"RJ", descri: "Rio de Janeiro"},{vr:"SP", descri: "São Paulo"}]},
{ campo: 'VrNo', tipo: 'N', obrigatorio: 'N', titulo: 'Número', tamanho: 6, cor: '#002A36', soLeitura: false, imagem: '', link: '', checked: true, secao: 'form' , destino:'',quadro:''},
{ campo: '', titulo: 'Caminhante', imagem: 'caminhante.jpg', link: 'none', checked: true, secao: 'traj' ,destino:'' ,quadro:''},    
{ campo: '', titulo: 'Ciclista', imagem: 'ciclista.jpg', link: 'none', checked: true, secao: 'traj' ,destino:'' ,quadro:''}, 
{ campo: '', titulo: 'Cavaleiro', imagem: 'cavaleiro.jpg', link: 'none', checked: true, secao: 'traj' ,destino:'' ,quadro:''},
{ campo: '', titulo: 'SAIR', imagem: '', link: 'main', checked: true, secao: 'traj' ,destino:'' ,quadro:''}
];
var arrCabecalhos = {
form:{nome:"ENTRADA DE DADOS PADRÃO", acao: "" },
traj:{ nome:"MAPA", acao:""}

};

Recomendações

Faça testes com trechos pequenos de HTML5 combinados com o VUE, para ter domínio de seu uso.




























Nenhum comentário:

Postar um comentário