
Como usar Web Components no Vue 2 e 3 + API de Composição
Tempo de leitura: 10 minutos
Este post abordará como incorporar um Web Component em uma aplicação Vue. Os exemplos incluirão as versões 2 e 3 do Vue, além da Composition API. A versão 3 acabara de ser lançada no momento da redação deste artigo. É tão recente que uma pequena notificação do tipo “Novo conteúdo disponível” aparece com frequência na documentação. Em seguida, a aplicação de demonstração é ampliada para utilizar a Verify API do Vonage Verify.
Test results from custom-elements-everywhere.com showing Vue 2.6.12 scored 100%, passed 16/16 Basic tests, and 14/14 advanced tests with an explanation.
Resultados dos testes do site custom-elements-everywhere.com
Observação: Isso se aplica ao Vue 2. O Vue 3 ainda não foi testado até o momento desta publicação.
O Vue é aprovado em todos os testes do custom-elements-everywhere.com, obtém 100% em compatibilidade e deixa seu laptop feliz. Como desenvolvedores, não é deixar os computadores felizes o objetivo principal?
Isso não deveria ser muito surpreendente, já que na documentação do Vue afirma-se:
"Você deve ter percebido que os componentes do Vue são muito semelhantes aos Elementos Personalizados, que fazem parte da Especificação de Componentes da Web. Isso ocorre porque a sintaxe dos componentes do Vue é vagamente inspirada nessa especificação."
Aspectos a serem considerados ao usar um componente da Web em um framework de JavaScript como o Vue. Como o framework:
Como saber, para começar, que você está usando um componente da Web?
Como lidar com a passagem de dados para o componente da Web?
Lidar com eventos personalizados provenientes do Web Component?
obter uma referência a um Componente Web para que um desenvolvedor possa ter acesso a elementos como os métodos desse Componente Web?
Existem várias maneiras de configurar e instalar um aplicativo Vue. (Consulte os guias para v2 e para a v3.) O código de exemplo apresentado nesta postagem é bastante comum.
Felizmente, o Vue lida com dados e eventos por meio da sintaxe do modelo, que permanece a mesma nas diferentes versões.
Passando dados para um componente da Web
No artigo anterior (/blog/using-web-components-in-a-react-application-dr), um dos problemas ao usar um Web Component em um aplicativo React era a forma como o React passava os dados. Independentemente do tipo de dados (por exemplo, strings, arrays, objetos, booleanos etc.), o React convertia os valores em strings. Para informar ao Vue que os dados que estão sendo passados não são strings, v-bind ou : , para abreviar, é usado conforme indicado na documentação.
Por exemplo, para acessar e definir o placeholder no componente teclado, este trecho de código é adicionado à tag do componente:
:placeholder="placeholder"Então, na seção de dados do aplicativo Vue, a configuração do valor inicial do placeholder é feita da seguinte forma:
placeholder: "Enter Security Code"Para alterar o valor, o código é
this.placeholder = "SUCCESS!!!";Esse é o funcionamento padrão de um aplicativo Vue.
Recentemente, adicionei a possibilidade de personalizar as teclas nos componentes do teclado; assim, eu poderia adicionar o seguinte à minha tag e reorganizar o teclado:
:keys = “[‘0’,’9’,’8’,’7’,’6’,’5’,’4’,’3’,’2’,’1’,’#’,’*’]”Um exemplo disso será apresentado em uma próxima postagem no blog, utilizando outra estrutura.
Ouvindo eventos a partir do componente da Web
O Vue pode detectar eventos do DOM (por exemplo, clique, rolagem, envio etc.) com v-on ou a sintaxe abreviada @. Como os Web Components são tratados como elementos HTML comuns, seus eventos personalizados também funcionarão. Para escutar o evento digits-sent , o código adicionado ao elemento ficaria assim:
@digit-sent=”digitsSent”digitsSent é a função que irá lidar com o que for gerado pelo evento.
Agora, informar ao Vue que existe um Web Component e as formas de interagir com ele variam um pouco, dependendo da versão do Vue e se a API de Composição está sendo usada ou não. De qualquer forma, o Vue avisará se você estiver fazendo algo errado, exibindo um aviso no console.
Vue console warning that it failed to resolve a component.
Vue 2
Veja o Pen Componentes da Web x Vue 2 por conshus do OUR show (@conshus) no CodePen.
Para que uma aplicação Vue 2 saiba que um Web Component está presente, usamos ignoredElements. Trata-se de um array que contém strings e/ou expressões regulares que identificam os nomes das tags dos Web Components. Esse ignoredElements é passado para a configuração do Vue para que ele saiba que deve “ignorar” esses “elementos”. No código de exemplo, fica assim:
Vue.config.ignoredElements = [/dwanes-\w*/];Às vezes, podemos precisar chamar um método de um componente web. Por exemplo, para limpar a tela do componente teclado, o cancelAction método é chamado. Antes que o método possa ser usado, é preciso criar uma referência ao elemento teclado. O Vue possui uma maneira semelhante de o React para fazer isso: adicionando uma ref tag ao componente web.
No componente do teclado, fica assim:
<dwanes-keypad ref="keypad" ...>
Então, o cancelAction é chamado com:
this.$refs.keypad.cancelAction(); Vue 3
Veja o Pen Componentes da Web x Vue 3 por conshus do OUR show (@conshus) no CodePen.
O Vue 3 acaba de ser lançado! Ainda está novinho em folha (e em constante evolução)!
Conforme mencionado anteriormente, a sintaxe dos componentes do Vue é vagamente baseada na especificação de Web Components. Então, usar um Web Component no Vue 3 seria igual ao Vue 2, certo? Não! Há uma mudança que quebra a compatibilidade ao informar ao aplicativo que um Web Component está sendo usado.
Mais detalhes sobre a mudança podem ser encontrados no Guia de Migração, na seção: config.ignoredElements Agora é config.isCustomElement
Interoperabilidade de Elementos Personalizados.
Em resumo, o ignoredElements no Vue 2 passa a ser isCustomElement no Vue 3. Em vez de um array, isCustomElement espera-se uma função que descreva o que deve ser procurado. Além disso, agora no Vue 3, a verificação para saber se o elemento é um elemento personalizado externo (ou seja, um Web Component) é feita durante a compilação do modelo.
Se essa compilação do modelo for feita “em tempo real”, isCustomElement é passado na configuração do aplicativo. No código de demonstração, fica assim:
const app = Vue.createApp(App);
app.config.isCustomElement = tag => tag.startsWith('dwanes-')
app.mount('#app');
Se o projeto tiver .vue arquivos, então uma etapa de compilação é usada para compilar o aplicativo em código que o navegador possa entender. Nesse caso, o isCustomElement é passado para as opções da biblioteca responsável pela compilação. A biblioteca depende do que o desenvolvedor decidir usar. Na próxima seção, o código de demonstração usa o webpack e mostrará como incluí-lo isCustomElement no arquivo de configuração.
Como obter uma referência a um Web Component no Vue 3 é, felizmente, feito da mesma maneira que no Vue 2, no momento da publicação deste post.
API de composição
A API de Composição do Vue foi criada para ajudar a superar algumas limitações que os desenvolvedores enfrentavam à medida que as applications cresciam com o tempo e se tornavam mais complexas. De acordo com a documentação:
"As APIs propostas neste RFC oferecem aos usuários maior flexibilidade na organização do código dos componentes. Em vez de serem obrigados a organizar o código sempre por opções, agora ele pode ser organizado em funções, cada uma delas lidando com um recurso específico. As APIs também facilitam a extração e a reutilização de lógica entre componentes, ou mesmo fora deles."
Recomendo vivamente a leitura da documentação da API de Composição documentação para entender melhor o assunto. Aqui, vou me concentrar em fazer um Web Component funcionar com ela. Isso diz respeito à forma como a referência ao componente é utilizada.
A forma de informar a um aplicativo Vue que existe um Web Component mudou da versão 2 para a 3.
Dependendo de como o aplicativo compila o modelo, ele determina onde colocar a configuração. No exemplo anterior, a compilação do modelo foi feita “em tempo real”. Este exemplo da API de Composição está usando o Webpack para compilar o modelo. Isso significa que a isCustomElement configuração fica no webpack.config.js arquivo. Lá você encontrará este código:
{
test: /\.vue$/,
use: {
loader: "vue-loader",
options: {
compilerOptions: {
isCustomElement: (tag) => {
return /^dwanes-/.test(tag);
}
}
}
}
}
Independentemente do mecanismo de compilação, provavelmente existe um .config.js arquivo, e é nele que você colocaria o trecho de código acima.
Na API de Composição, o ref foi ampliada para incluir o rastreamento de outros valores, não apenas de elementos do DOM.
O ref adicionado ao componente do teclado permanece o mesmo:
<dwanes-keypad ref="keypad" ...>
A primeira alteração é que ref precisa ser importado:
import { ref } from 'vue';Em seguida, a referência precisa ser inicializada dentro da função setup():
const keypad = ref(null);Não se esqueça de adicionar keypad ao return.
Veja como acessar o cancelAction() método no componente:
keypad.value.cancelAction();Não se esqueça de anotar value.
O mesmo procedimento é seguido para definir e alterar o placeholder texto.
Vonage Vuerify
Uma coisa que aprendi ao pesquisar para este post no blog é que os projetos baseados no Vue adoram incluir o nome “Vue” no título, sempre que possível. Veja o Vuetify, o Vuex, o Revue, o Vuedo, etc. Então, como eu poderia deixar passar a oportunidade de adotar a API da Vonage Verify API e criar o Vonage Vuerify?!
Experimente!
Quer experimentar por conta própria? Primeiro, faça um fork do código em codesandbox.io.
Observação: você precisará estar conectado.
É assim que funciona:
A Configuração
Primeiro, você precisará de um account de desenvolvedor da Vonage. Anote sua chave de API e seu segredo de API, que podem ser encontrados no painel de controle; você precisará desses valores para a autenticação.
Em seguida, no seu projeto recém-criado a partir de um fork codesandbox.io , clique no “Painel de Controle do Servidor”.
Screen capture of codesandbox.io code editor with the icon for the server control panel circled in red with a red arrow pointing to it.
Na parte inferior, há a seção “Chaves secretas”. Clique no API Key e API Secret no Painel da Vonage e insira-as nos campos correspondentes. Brand Name é a sequência de caracteres que será enviada junto com o código de segurança ao usuário. Neste caso, é VonageVuerify.
O App.vue código parece quase igual ao da API de Composição, exceto pela forma como os dígitos enviados pelo Componente Web são processados e encaminhados para o backend do Node Express.
Solicitação do código de segurança
Se o usuário solicitar o código de segurança, uma POST é enviada uma solicitação ao /request ponto de extremidade no servidor, enviando o número de telefone inserido no corpo da solicitação.
Assim que a resposta for recebida e for válida, o ID da solicitação é salvo, o modo é alterado, parte do texto no componente do teclado é alterado e a tela é apagada. Caso contrário, é exibida uma mensagem de erro.
Aqui está o código:
App.vue
if (mode === "request") {
// Request security code
postData("https://qtebx-8081.sse.codesandbox.io/request", {
number: entered,
})
.then((data) => {
if (data.status === "0") {
requestId = data.request_id;
mode = "verify";
placeholder.value = "Enter verification code.";
actionText.value = "Verify Code";
keypad.value.cancelAction();
} else {
keypad.value.cancelAction();
status.value = data.error;
}
})
.catch((error) => {
console.error("Error: ", error);
});
}
server.js
app.post("/request", (request, response) => {
console.log("request.body: ", request.body);
nexmo.verify.request(
{
number: request.body.number,
brand: process.env.BRAND_NAME,
workflow_id: 6
},
(err, result) => {
if (err) {
console.error(err);
response.json(err);
} else {
console.log("request result: ", result);
if (result.status === 0) {
response.json({
status: result.status,
request_id: result.request_id
});
} else {
response.json({
status: result.status,
request_id: result.request_id,
error: result.error_text
});
}
}
}
);
});
Observação: O
workflow_idé a estratégia alternativa usada para fornecer o código de segurança ao usuário. Consulte as diversas opções na documentação. Este aplicativo está utilizando o Workflow 6, que envia apenas uma mensagem SMS.
Verificação do código
Quando o usuário tenta se autenticar com o código que recebeu, outra POST solicitação é enviada para o /check ponto de extremidade no servidor com o requestId salvo anteriormente e o código de segurança.
Se o status for de sucesso, o modo é alterado, a imagem é atualizada, o texto do componente do teclado é alterado e a tela é zerada. Se o status for de erro, ele é exibido.
Aqui está o código:
App.vue
else if (mode === "verify") {
// verify code
postData("https://qtebx-8081.sse.codesandbox.io/check", {
request_id: requestId,
code: entered,
})
.then((data) => {
if (data.status === "0") {
//verified!!!
mode = "success";
placeholder.value = "Woohoo!!";
actionText.value = "SUCCESS!!!";
image.value = {
src: "https://media.giphy.com/media/oobNzX5ICcRZC/source.gif",
alt: "minion giving the thumbs up",
};
keypad.value.cancelAction();
} else {
keypad.value.cancelAction();
status.value = data.error;
}
})
.catch((error) => {
console.error("Error: ", error);
});
}
server.js
app.post("/check", (request, response) => {
console.log("check request.body: ", request.body);
nexmo.verify.check(
{
request_id: request.body.request_id,
code: request.body.code
},
(err, result) => {
if (err) {
console.error(err);
response.json(err);
} else {
console.log("check result: ", result);
if (result.status === 0) {
response.json({ status: result.status });
} else {
response.json({ status: result.status, error: result.error_text });
}
}
}
);
});
Observação: Se você criar um fork do código de demonstração, os endpoints chamados no
App.vueprecisarão ser alterados para corresponder ao servidor do seu projeto.
Para saber mais sobre a Verify API do Vonage, você pode consultar a documentação.
Alguma dúvida sobre o que foi abordado neste post? Você já incorporou Web Components em uma aplicação Vue de outra maneira? Tem algum exemplo de como está usando a Verify API do Vonage? Conte para a gente no nosso canal da Comunidade no Slack.
img.alignnone { border-width: 0px !important; }