Encontrar componentes Vue.js que bata 100% com os requisitos do nosso layout sem termos que modificar ele em nosso próprio projeto não é nada fácil. Em 99,99% dos casos precisamos replicar e manter estas mesmas modificações em outros projetos nossos, tornando a manutenção um trabalho árduo e cansativo.
A forma mais fácil de manter um componente deste porte seria criando nosso próprio componente. Além de podermos usar em outros projetos vamos estar a poucos passos de disponibilizar online e ajudarmos outras pessoas que possam ter tido o mesmo problema.
Este artigo engloba as seguintes tecnologias:
Obs.: Eu uso o Yarn mas caso você prefira o NPM e quer usá-lo, fique atento apenas aos comandos que utilizam yarn e adeque conforme for necessário.
Vou procurar ser bem didático para que vocês não fiquem em um loop infinito de dúvidas.
Então, sem mais delongas, Let’s Go e vamos criar um componente Vue.js!
Tendo em mente que vocês já possuem o Yarn/NPM devidamente instalados, vamos seguir para a instalação do Vue Cli.
Abra o terminal e digite o seguinte comando:
yarn global add @vue/cli
Verifique se foi instalado corretamente com o comando:
vue --version
Se tudo ocorreu bem vamos visualizar a versões do Vue Cli conforme este exemplo
@vue/cli 4.3.1
Ainda com o terminal aberto, navegue até o diretório onde você quer criar o seu componente.
Para este exemplo vamos criar um componente de um botão bem simples, porém, você poderá seguir este artigo para criar coisas mais complexas.
Seguindo, tendo navegado até o diretório desejado digite o seguinte comando:
vue create my-simple-button
O Vue Cli vai perguntar qual preset queremos. Escolha o default. Ele já basta para este exemplo.
Vue CLI v4.3.1
? Please pick a preset: (Use arrow keys)
❯ default (babel, eslint)
Manually select features
Ele vai fazer as instalações necessárias e, após finalizar, digite o seguinte comando para iniciar o projeto:
yarn serve
Verifique se está tudo funcionando e finalize a aplicação para que possamos alterar algumas coisas na configuração.
Vamos até o arquivo package.json
Na sessão de Scripts, inclua um novo chamado build-lib
E coloque o seguinte conteúdo:
vue-cli-service build --target lib --inline-vue --name nome-plugin [entry]
Altera onde está nome-plugin para o nome do nosso projeto que no caso é my-simple-button
Vamos precisar alterar também o [entry]. É nele que informamos qual será o ponto de entrada do componente.
Se não informarmos ficando [entry], o ponto de entrada vai ser src/App.vue, mas precisamos que o ponto de entrada seja src/main.js.
Ficando mais ou menos assim a sessão de Scripts
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"build-lib": "vue-cli-service build --target lib --inline-vue --name my-simple-button src/main.js",
"lint": "vue-cli-service lint"
}
Rodando o novo comando vamos obter uma resposta parecida com esta:
DONE Compiled successfully in 4866ms
File Size Gzipped
dist/plugin-button.umd.min.js 70.49 KiB 25.14 KiB
dist/plugin-button.umd.js 222.08 KiB 60.92 KiB
dist/plugin-button.common.js 221.69 KiB 60.81 KiB
dist/plugin-button.css 0.33 KiB 0.23 KiB
Images and other types of assets omitted.
✨ Done in 7.16s.
Isso significa que a construção foi bem-sucedida.
Olhando para a pasta dist podemos ver vários arquivos, precisamos definir qual vai ser usado por qualquer aplicação que importe nosso componente.
Vamos escolher o terminado com .common.js
Então voltando para o package.json adicione o a sessão main, ficando assim:
"main": "./dist/plugin-button.common.js",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"build-lib": "vue-cli-service build --target lib --inline-vue --name my-simple-button src/main.js",
"lint": "vue-cli-service lint"
}
Agora vamos desenvolver nosso botão.
Indo em components vamos criar um arquivo chamado MeuBotaopersonalizado.vue com este conteúdo:
<template>
<div>
<button @click="incremento">{{ texto }}</button>
</div>
</template>
<script>
export default {
data () {
return {
contador: 0
}
},
computed: {
vezes () {
return this.contador === 1 ? 'vez' : 'vezes'
},
texto () {
return `Clicado ${this.contador} ${this.vezes}`
}
},
methods: {
incremento () {
this.contador += 1
}
}
}
</script>
Esse botão, ao ser acionado, informa a quantidade de vezes que já foi clicado.
Conforme falei, nada complexo e de fácil entendimento.
O Vue nos permite visualizar apenas este componente. Rode o seguinte comando:
vue serve src/components/MeuBotaopersonalizado.vue
Agora, para que possamos usar este componente em outros lugares, temos que informar o que será exportado.Indo no main.js e apagando tudo que contem nele, cole o seguinte código:
import botaoSimples from './components/MeuBotaopersonalizado.vue'
export default {
install (Vue, options) {
Vue.component('simple-button', botaoSimples)
}
}
Não podemos esquecer de fazer o rebuild sempre que terminar de atualizar alguma coisa.
Se o componente precisar trabalhar com Vuex, vamos precisar de um pouquinho mais de código.
Temos que ter em mente que o Vue só permite uma instância do Vuex, logo, não vamos poder instalar esse plugin em nosso componente.
Mas para usar a store, precisamos apenas definir a estrutura dela e informar que nosso componente depende do Vuex instalado no projeto para funcionar.
Tanto faz se vamos usar a store de arquivo único ou modular. No final, será o mesmo processo de apenas informar o caminho do arquivo principal da store.
Para este exemplo, vou assumir a criação da store em um único arquivo para facilitar o entendimento.
Vamos entrar no diretório src e criar um arquivo chamado store.js com o seguinte conteúdo:
const store = {
state: {
contador: 0
},
getters: {
contador: state => state.contador
},
mutations: {
increment (state) {
state.contador += 1
}
}
}
export default store
Volte para o arquivo MeuBotaopersonalizado.vue e altere seu código para este:
<template>
<div>
<button @click="incremento">{{ texto }}</button>
</div>
</template>
<script>
export default {
data () {
return {}
},
computed: {
vezes () {
return this.$store.getters.contador === 1 ? 'vez' : 'vezes'
},
texto () {
return `Clicado ${this.$store.getters.counter} ${this.vezes}`
}
},
methods: {
incremento () {
this.$store.commit('increment')
}
}
}
</script>
Precisamos alterar o main.js para este código:
import botaoSimples from './components/MeuBotaopersonalizado.vue'
import store from './store.js'
export default {
install (Vue, options) {
// Precisamos que vuex seja passada como opção para que possamos registrar a vuex do componente
if (!options || !options.store) {
throw new Error('Inicie o componente com Vuex.')
}
options.store.registerModule('simplebutton', store)
Vue.component('simple-button', botaoSimples)
}
}
Devemos fazer o rebuild novamente.
Após fazermos o build, o componente já está pronto para ser usado em qualquer projeto nosso.
Se não publicarmos no NPM podemos usar da seguinte forma:
Estando em um projeto que queremos usar o componente, devemos abrir um terminal neste diretório e rodar o comando:
yarn add ../my-simple-button
Não esqueça de passar o caminho correto. Esse foi somente para exemplo.
Depois devemos ir no arquivo main.js deste projeto e fazer a instalação do nosso componente.
import mySimpleButton from my-simple-button;
// Podemos usar assim, passando as opcoes
Vue.use(mySimpleButton, {algumaOpcao: algumValor})
// ou assim, sem opcoes
Vue.use(mySimpleButton)
Temos duas formas de usar: a com opção e a sem opção.
O nosso componente precisa da store, logo temos que usar a primeira opção.
import Vue from 'vue'
import App from './App.vue'
import store from './store';
import mySimpleButton from my-simple-button;
Vue.config.productionTip = false
Vue.use (mySimpleButton, { store });
new Vue({
store,
render: h => h(App),
}).$mount('#app')
Desta forma, o nosso componente está definido no nível da aplicação como o Vuex e não no componente que formos usar ele dentro.
Lembrando: ele está global!
<template>
<div id="app">
<h1>Contato</h1>
<p>Algum texto</p>
<my-simple-button />
</div>
</template>
<script>
export default {
name: 'app',
}
</script>
O nome que ele vai ser chamado vai ser sempre o que definimos no main.js do nosso componente.
import botaoSimples from './components/MeuBotaopersonalizado.vue'
import store from './store.js'
export default {
install (Vue, options) {
if (!options || !options.store) {
throw new Error('Inicie o componente com Vuex.')
}
options.store.registerModule('simplebutton', store)
Vue.component('bolacha-doce', botaoSimples)
}
}
Neste exemplo eu alterei o nome para bolacha-doce, logo, para usar:
<template>
<div id="app">
<h1>Contato</h1>
<p>Algum texto</p>
<bolacha-doce />
</div>
</template>
<script>
export default {
name: 'app',
}
</script>
Muito fácil criar e compartilhar componentes/plugins.
Desta mesma forma que criamos o nosso componente, poderíamos ter encapsulado o componente de outra pessoa, como por exemplo uma estilização diferente em um botão do Bootstrap com algumas ações ao clicar ou passar o mouse.
Podemos disponibilizar também com o componente mixins, hooks, filters e muitas outras coisas.
O que vimos aqui foi apenas uma das N’s configurações que podemos fazer no install do nosso componente.
Isso pode ser um plus para um outro artigo.
O que podemos fazer agora é publicar no NPM facilitando para disponibilizar para a comunidade usar.
Bom, isso foi tudo pessoal.
Qualquer dúvida ou sugestão deixe nos comentários, vamos sempre estar de olho! Para conferir outros assuntos no nosso blog, basta clicar aqui. Obrigado pela leitura!
Até a próxima!