https://a.storyblok.com/f/270183/27136/1ad839d9a8/blog_webcomponents_vue_1200x600-1.png

Como usar Web Components no Vue 2 e 3 + API de Composição

Publicado em November 2, 2020

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.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 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.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.vue precisarã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; }

Compartilhar:

https://a.storyblok.com/f/270183/384x384/1a06993970/dwanehemmings.png
Dwane HemmingsPromotor de Desenvolvedores de JavaScript