VueJS - Função Render
Vimos os componentes e o uso deles. Por exemplo, temos um conteúdo que precisa ser reutilizado em todo o projeto. Podemos converter o mesmo como um componente e usá-lo.
Vamos dar uma olhada em um exemplo de um componente simples e ver o que a função de renderização tem que fazer dentro dele.
Exemplo
<html>
<head>
<title>VueJs Instance</title>
<script type = "text/javascript" src = "js/vue.js"></script>
</head>
<body>
<div id = "component_test">
<testcomponent></testcomponent>
</div>
<script type = "text/javascript">
Vue.component('testcomponent',{
template : '<h1>Hello World</h1>',
data: function() {
},
methods:{
}
});
var vm = new Vue({
el: '#component_test'
});
</script>
</body>
</html>
Considere o exemplo acima de um componente simples que imprime Hello World conforme mostrado na captura de tela a seguir.
Agora, se quisermos reutilizar o componente, podemos fazê-lo apenas imprimindo-o novamente. Por exemplo,
<div id = "component_test">
<testcomponent></testcomponent>
<testcomponent></testcomponent>
<testcomponent></testcomponent>
<testcomponent></testcomponent>
</div>
E a saída será a seguinte.
No entanto, agora precisamos de algumas alterações no componente. Não queremos que o mesmo texto seja impresso. Como podemos mudar isso? Caso digamos algo dentro do componente, isso será levado em consideração?
Vamos considerar o seguinte exemplo e ver o que acontece.
<div id = "component_test">
<testcomponent>Hello Jai</testcomponent>
<testcomponent>Hello Roy</testcomponent>
<testcomponent>Hello Ria</testcomponent>
<testcomponent>Hello Ben</testcomponent>
</div>
O resultado permanece o mesmo que vimos anteriormente. Não altera o texto como desejamos.
O componente fornece algo chamado de slots. Vamos aproveitar e ver se obtemos os resultados desejados.
Exemplo
<html>
<head>
<title>VueJs Instance</title>
<script type = "text/javascript" src = "js/vue.js"></script>
</head>
<body>
<div id = "component_test">
<testcomponent>Hello Jai</testcomponent>
<testcomponent>Hello Roy</testcomponent>
<testcomponent>Hello Ria</testcomponent>
<testcomponent>Hello Ben</testcomponent>
</div>
<script type = "text/javascript">
Vue.component('testcomponent',{
template : '<h1><slot></slot></h1>',
data: function() {
},
methods:{
}
});
var vm = new Vue({
el: '#component_test'
});
</script>
</body>
</html>
Como visto no código acima, no modelo adicionamos slot, portanto, agora leva o valor para enviar dentro do componente, conforme mostrado na imagem a seguir.
Agora, vamos considerar que queremos mudar a cor e o tamanho. Por exemplo, atualmente estamos usando a tag h1 e queremos alterar a tag HTML para tag p ou tag div para o mesmo componente. Como podemos ter flexibilidade para realizar tantas mudanças?
Podemos fazer isso com a ajuda da função render. A função Render ajuda a tornar o componente dinâmico e a usar da maneira necessária, mantendo-a comum e ajudando a passar argumentos usando o mesmo componente.
Exemplo
<html>
<head>
<title>VueJs Instance</title>
<script type = "text/javascript" src = "js/vue.js"></script>
</head>
<body>
<div id = "component_test">
<testcomponent :elementtype = "'div,red,25,div1'">Hello Jai</testcomponent>
<testcomponent :elementtype = "'h3,green,25,h3tag'">Hello Roy</testcomponent>
<testcomponent :elementtype = "'p,blue,25,ptag'">Hello Ria</testcomponent>
<testcomponent :elementtype = "'div,green,25,divtag'">Hello Ben</testcomponent>
</div>
<script type = "text/javascript">
Vue.component('testcomponent',{
render :function(createElement){
var a = this.elementtype.split(",");
return createElement(a[0],{
attrs:{
id:a[3],
style:"color:"+a[1]+";font-size:"+a[2]+";"
}
},
this.$slots.default
)
},
props:{
elementtype:{
attributes:String,
required:true
}
}
});
var vm = new Vue({
el: '#component_test'
});
</script>
</body>
</html>
No código acima, mudamos o componente e adicionamos a função render com a propriedade props usando o seguinte trecho de código.
Vue.component('testcomponent',{
render :function(createElement){
var a = this.elementtype.split(",");
return createElement(a[0],{
attrs:{
id:a[3],
style:"color:"+a[1]+";font-size:"+a[2]+";"
}
},
this.$slots.default
)
},
props:{
elementtype:{
attributes:String,
required:true
}
}
});
Os adereços se parecem com o seguinte.
props:{
elementtype:{
attributes:String,
required:true
}
}
Definimos uma propriedade chamada elementtype, que leva os atributos de campo do tipo string. Outro campo obrigatório, que menciona que o campo é obrigatório.
Na função de renderização, usamos a propriedade elementtype conforme visto no código a seguir.
render :function(createElement){
var a = this.elementtype.split(",");
return createElement(a[0],{
attrs:{
id:a[3],
style:"color:"+a[1]+";font-size:"+a[2]+";"
}
},
this.$slots.default
)
}
A função Render leva createElement como argumento e retorna o mesmo. CreateElement cria o elemento DOM da mesma maneira que em JavaScript. Também dividimos o elementtype por vírgula, usando os valores do campo attrs.
CreateElement está usando o primeiro parâmetro como o elementtag a ser criado. Ele é passado para o componente usando o seguinte trecho de código.
<testcomponent :elementtype = "'div,red,25,div1'">Hello Jai</testcomponent>
O componente precisa ocupar o campo de adereços conforme mostrado acima. Ele começa com: e o nome dos adereços. Aqui, estamos passando a tag do elemento, a cor, o tamanho da fonte e o id do elemento.
Na função render, em createElement, estamos dividindo por vírgula, então o primeiro elemento é o elementtag, que é dado ao createElemet conforme mostrado no seguinte trecho de código.
return createElement(
a[0],{
attrs:{
id:a[3],
style:"color:"+a[1]+";font-size:"+a[2]+";"
}
},
this.$slots.default
)
a[0]é a tag do elemento html. O próximo parâmetro são os atributos da tag do elemento. Eles são definidos no campo attr no seguinte trecho de código.
attrs:{
id:a[3],
style:"color:"+a[1]+";font-size:"+a[2]+";"
}
Definimos dois atributos para a tag do elemento - id e style. Para id, estamos passando a [3], que é o valor que temos após a divisão por vírgula. Usando o estilo, definimos a cor e o tamanho da fonte.
O último é o slot, que é a mensagem que demos no componente no seguinte trecho de código.
<testcomponent :elementtype = "'div,red,25,div1'">Hello Jai</testcomponent>
Definimos o texto a ser impresso no createElement usando o seguinte trecho de código.
this.$slots.default
Ele assume o padrão atribuído no campo do componente.
A seguir está a saída que obtemos no navegador.
Os elementos também mostram a estrutura. Estes são os componentes que definimos -
<div id = "component_test">
<testcomponent :elementtype = "'div,red,25,div1'">Hello Jai</testcomponent>
<testcomponent :elementtype = "'h3,green,25,h3tag'">Hello Roy</testcomponent>
<testcomponent :elementtype = "'p,blue,25,ptag'">Hello Ria</testcomponent>
<testcomponent :elementtype = "'div,green,25,divtag'">Hello Ben</testcomponent>
</div>