# Plugin
Maneira de conectar recursos globais a um aplicativo e estendê-los para nosso uso
# Usar um plugin
Algumas categorias que os plugins se enquadram são:
- Adicionar alguns métodos ou propriedades globais.
- Adicionar um ou mais ativos globais: diretivas, filtros,*transições e outros.
- Adicionar algumas opções de componentes por mixin global.
- Adicionar alguns métodos de instância do Vue anexando-os ao Vue.prototype.
- Uma biblioteca que fornece uma API própria, ao mesmo tempo em que injeta alguma combinação dos itens acima.
Para criar plugins precisamos definir o diretorio onde vamos centralizar eles.
Eu costumo criar dentro de src um diretorio chamado plugins onde instalo meus plugins e os de terceiros.
Um plugin Vue é basicamente um objeto com uma funcao install que é executada sempre que o aplicativo que o utiliza o inclui em vue.use()
.
Um plugin deve conter um metodo install que aceita dois parâmetros:
- O objeto/construtor global Vue
- Um objeto opcional chamado options que serve para customizar o plugin com opcoes fornecidas pelos usuarios
Entao para usarmos um plugin, no main.js importamos ele e depois usamos com o vue.use().
import Vue from 'vue'
...
import PluginX from '@/plugins/plugin-x'
Vue.use(PluginX)
new Vue({
...
}).$mount('#app')
2
3
4
5
6
7
8
9
Ou passando parametros se o componente permitir
import Vue from 'vue'
...
import PluginX from '@/plugins/plugin-x'
Vue.use(PluginX, {
algumaOpcao: true
})
new Vue({
...
}).$mount('#app')
2
3
4
5
6
7
8
9
10
11
Para usar um plugin globalmente podemos fazer assim (axios como exemplo).
// src/api.js
import axios from 'axios'
export default axios.create({
baseURL: 'http://localhost:5000/api'
});
2
3
4
5
6
// src/main.js
import Vue from "vue";
import App from "./App.vue";
import API from "./api";
Vue.prototype.$http = API;
Vue.config.productionTip = false;
new Vue({
render: (h) => h(App)
}).$mount("#app");
2
3
4
5
6
7
8
9
10
11
12
// Algum componente
methods: {
algumaFuncao () {
$.$http.get("https://jsonplaceholder.typicode.com/posts")
.then(r => { console.log(r) })
.catch(e => { console.log(e) })
}
}
2
3
4
5
6
7
8
# Criar um plugin
Documentacao AQUI (opens new window)
Para criar um plugin de maneira facil basta usar o vue cli e criar um projeto com configuracao default (basico).
Para instalar o @vue/cli globalmente
yarn global add @vue/cli
Depois é só criar um projeto basico
vue create plugin-button
Vue CLI v4.3.1
? Please pick a preset: (Use arrow keys)
❯ default (babel, eslint)
Manually select features
2
3
4
Espera terminar de criar o projeto e inicie o mesmo
yarn serve
Vamos fazer algumas mudancas
Indo no package.json
, inclua um o build-lib script:
vue-cli-service build --target lib --inline-vue --name nome-plugin [entry]
Alterar o nome-plugin para o nome do seu projeto
Altere o [entry] para o arquivo que sera a entrada do plugin, neste caso o src/main.js
. Se nao informado, ficando [entry] será o src/App.vue
O scripts no package.json
ficou mais ou menos assim:
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"build-lib": "vue-cli-service build --target lib --inline-vue --name plugin-button src/main.js",
"lint": "vue-cli-service lint"
}
2
3
4
5
6
Se voce rodar yarn build-lib
vera isso:
DONE Compiled successfully in 4866ms 2:14:44 PM
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.
2
3
4
5
6
7
8
9
10
11
12
O resultado retornado Significa que a construção foi bem-sucedida.
Se olharmos para a pasta dist podemos ver varios arquivos, precisamos definir qual arquivo vai ser usado por qualquer aplicativo que importe nosso plugin.
Vamos escolher o terminado com ```.common.js````
Indo no package.json
adicione o a sessao main:
"main": "./dist/plugin-button.common.js"
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 plugin-button src/main.js",
"lint": "vue-cli-service lint"
}
2
3
4
5
6
7
Para exemplo, vamos seguir criando um plugin de botao.
Indo na pasta components crie um componente chamado SimpleButton.vue
e coloque este conteudo
<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>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
O vue nos permite ver este componente funcionando, rode o seguinte:
vue serve src/components/SimpleButton.vue
Ao abrir o navegador podemos testar o botao.
Agora para que possamos usar este plugin em outros lugares temos que informar o que sera exportado.
Indo no main.js
e apagando tudo que contem nele, cole o seguinte
import SimpleButton from './components/SimpleButton.vue'
export default SimpleButton
2
3
Não esqueca de fazer o rebuild sempre que terminar de atualizar alguma coisa
Se compartilhamos este projeto sem publicar no NPM/YARN, podemos fazer a instalacao de um pacote local com o yarn
Estando em outro projeto podemos fazer assim
yarn add ../plugin-button
Para usar por exemplo no APP.vue
de um outro projeto
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<simple-button />
</div>
</template>
<script>
import SimpleButton from 'plugin-button'
export default {
name: 'app',
components: {
SimpleButton
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Se rodar seu projeto poderar testar o plugin
yarn serve
Caso o seu plugin precise trabalhar com vuex, devemos lembrar que o vue só permite apenas uma instancia do vuex.
Para usar a nossa store precisamos apenas definir a estrutura dela e informar que nosso projeto depende do vuex instalado no projeto.
Para usarmos, primeiro precisamos criar a estrutura da store, se voce usa em um arquivo unico OK, se usa modular OK, precisamos apenas do caminho depois.
Vou criar aqui um arquivo chamado store.js
na raiz do plugin com este conteudo
const store = {
state: {
contador: 0
},
getters: {
contador: state => state.contador
},
mutations: {
increment (state) {
state.contador += 1
}
}
}
export default store
2
3
4
5
6
7
8
9
10
11
12
13
14
Atualize o plugin SimpleButton.vue
com este conteudo
<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>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Precisamos atualizar o main.js do plugin para isso
import SimpleButton from './components/SimpleButton.vue'
import store from './store.js'
export default {
install (Vue, options) {
// Precisamos que vuex seja passada como opcao para que possamos registrar a vuex do plugin
if (!options || !options.store) {
throw new Error('Please initialise plugin with a Vuex store.')
}
options.store.registerModule('simplebutton', store)
Vue.component('simple-button', SimpleButton)
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Precisamos fazer pois exportar nao era o suficiente, precisavamos torna-lo um plugin
Agora podemos usar ele assim no main.js do projeto que queremos ele
import DummyButton from 'dummylib';
Vue.use (MyPlugin, {someOption: someValue})
// ou
Vue.use(DummyButton);
2
3
4
5
6
Esta segunda forma é para quando o plugin nao precisa de opcoes para funcionar, no caso deste plugin que criamos ele precisa, entao usariamos o primeiro Vue.use
import DummyButton from 'dummylib';
Vue.use (MyPlugin, {someOption: someValue})
2
3
A estrutura um pouco mais detalhada do que se pode fazer no install
de um plugin/componente vamos ver no decorrer, o install é assim:
export default {
install(vue, opts){
// Alguma coisa
}
}
2
3
4
5
Quando construimos um plugin queremos que ele seja configurável, permitindo que qualquer pessoa que o use em seu próprio aplicativo possa o aprimorar.
Fora que também queremos torna nosso plug-in mais versátil.
Para recebermos os opcoes podemos fazer assim:
export default {
install(Vue, options) {
const { job = "" } = options || {};
}
};
2
3
4
5
Neste exemplo estamos desconstruindo 0 options para o que realmente recebemos, desta forma evitamos receber alguma coisa que não queremos no nosso plugin.
Setei como vazio para os casos em que a opcao não é setada evitando erros internos em locais que precisaremos desta propriedade.
Exemplo de plugin:
import ComponentX from "@/components/Component.vue";
import ComponentY from "@/components/Component.vue";
import AnnoyingBackground from "@/components/aaa";
const Components = {
"component-plugin": ComponentX,
ComponentY
};
const Directives = {
"annoying-background": AnnoyingBackground
};
export default {
// The install method will be called with the Vue constructor as the first argument, along with possible options
install(Vue, options) {
// se a opcao job nao for passada sera definida como vazio
// se options nao for passado vai ser definido como vazio
const { job = "", car = "" } = options || {};
// Adicione a instância do vue componentes
Object.keys(Components).forEach(name => {
Vue.component(name, Components[name]);
});
// Adicione a instância do vue componentes
Object.keys(Directives).forEach(name => {
Vue.directive(name, Directives[name]);
});
// Injetanco Mixin
Vue.mixin({
// Created lifecycle hooks
created() {
console.log("Hello from created hook plugin!");
}
});
Vue.filter("capitalize", function(value) {
if (!value) return "";
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1);
});
// Quando usado o prototype o que esta sendo disponibilizado vai estar disponivel desde de o beforeCreate da instancia Vue
// Adicione a instância do vue o método $myInfo=
Vue.prototype.$myInfo = (name, age) => mensagem(name, age, job, car);
// Adicione a instância do vue a variavel $surname
Vue.prototype.$surname = "Smith";
// Adicione metodos globais
Vue.metodoGlobal = function() {
// Faz alguma logica
};
// Adicione propriedades globais
Vue.propriedadeGlobal = "Alguma coisa";
}
};
// Retorna uma string
const mensagem = (name = "John", age = 22, job = "student", car = "") =>
`My name is ${name} and I am a ${age} years old ${job}. My car is ${car}.`;
// Para pessoas que usam seu plug-in fora de um sistema de módulos, geralmente é esperado que, se ele for incluído após a tag de script do Vue, ele se instale automaticamente sem a necessidade de chamar Vue.use ()
if (typeof window !== 'undefined' && window.Vue) {
window.Vue.use(MyPlugin)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
No main.js posso chamar assim:
import Vue from "vue";
import App from "./App.vue";
import PluginX from "@/plugins/nomePlugin";
// Nao passano opcao
Vue.use(PluginX);
// Passano opcao
Vue.use(PluginX, {
job: "Web Dev"
});
Vue.config.productionTip = false;
new Vue({
render: h => h(App)
}).$mount("#app");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18