
Uso de componentes web en Vue 2 y 3 + API de composición
Tiempo de lectura: 10 minutos
Este post repasará cómo incorporar un Web Component en una aplicación Vue. Los ejemplos incluirán las versiones 2 y 3 de Vue, además de la API de composición. La versión 3 acaba de ser lanzada en el momento de escribir este artículo. Es tan nueva que una pequeña notificación de "Nuevo contenido disponible" aparece frecuentemente en la documentación de Vue. documentación. A continuación, la aplicación de demostración se amplía para utilizar la Verify API de Vonage.
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 de las pruebas de custom-elements-everywhere.com
Nota: Esto es para Vue 2. Vue 3 no ha sido probado en el momento de este post.
Vue pasa todas las pruebas de custom-elements-everywhere.comy hace feliz a tu portátil. Como desarrolladores, ¿no es hacer felices a los ordenadores el objetivo principal?
Esto no debería sorprender demasiado, ya que en la documentación de Vue se indica:
"Puede que hayas notado que los componentes de Vue son muy similares a los Elementos Personalizados, que forman parte de la Especificación de Componentes Web. Esto se debe a que la sintaxis de los componentes de Vue se basa en la especificación".
Cosas a tener en cuenta cuando se utiliza un Web Component en un framework JavaScript como Vue. Cómo funciona el framework:
saber que está utilizando un Web Component?
gestionar la transmisión de datos al Web Component?
gestionar los eventos personalizados procedentes del Web Component?
obtener una referencia a un Web Component para que un desarrollador pueda acceder a cosas como los métodos del Web Component?
Existen múltiples formas de configurar e instalar una aplicación Vue. (Véanse las guías para v2 y para v3.) El código de ejemplo que se muestra en este post es bastante estándar.
Por suerte, Vue maneja los datos y eventos a través de la sintaxis de la plantilla, que se mantiene igual en las diferentes versiones.
Pasar datos a un componente web
En el anterior (/blog/using-web-components-in-a-react-application-dr), un problema con el uso de un Web Component en una aplicación React era la forma en que React pasaba los datos. Independientemente del tipo de datos (por ejemplo, cadenas, matrices, objetos, booleanos, etc.), React encadenaría los valores. Para decirle a Vue que los datos que se pasan no son una cadena, v-bind o : para abreviar, como se indica en la documentación.
Por ejemplo, para acceder y establecer el marcador de posición en el componente del teclado, se añade este fragmento de código a la etiqueta del componente:
:placeholder="placeholder"A continuación, en la sección de datos de la aplicación Vue, el valor inicial del marcador de posición se establece de la siguiente manera
placeholder: "Enter Security Code"Para cambiar el valor, el código es
this.placeholder = "SUCCESS!!!";Esta es la operación estándar para una aplicación Vue.
Recientemente he añadido la posibilidad de personalizar las teclas en los componentes del teclado, por lo que sería capaz de añadir lo siguiente a mi etiqueta y reorganizar el teclado:
:keys = “[‘0’,’9’,’8’,’7’,’6’,’5’,’4’,’3’,’2’,’1’,’#’,’*’]”Un ejemplo de esto se hará en una próxima entrada del blog utilizando otro framework.
Escuchar eventos desde el componente web
Vue puede escuchar eventos DOM (es decir, clic, desplazamiento, enviar, etc.) con v-on o la abreviatura @. Dado que los Web Components se tratan como elementos HTML normales, sus eventos personalizados también funcionarán. Para escuchar el evento digits-sent del componente teclado, el código añadido al elemento tendría el siguiente aspecto:
@digit-sent=”digitsSent”digitsSent es la función que se encargará de lo que salga del evento.
Ahora, hacer que Vue sepa que hay un Web Component y las formas de interactuar con él son ligeramente diferentes dependiendo de la versión de Vue y de si se utiliza la API de composición o no. De cualquier manera, Vue te hará saber si lo estás haciendo mal mostrando una advertencia en la consola.
Vue console warning that it failed to resolve a component.
Vue 2
Ver el Pen Componentes Web x Vue 2 por conshus de OUR show (@conshus) en CodePen.
Para que una aplicación Vue 2 sepa que un Web Component está presente, utilizamos ignoredElements. Es un array que contiene cadenas y/o expresiones regulares que exponen los nombres de las etiquetas de los Web Components. Este ignoredElements se pasa a la configuración de Vue para que sepa que debe "ignorar" esos "elementos". En el código de ejemplo, tiene este aspecto:
Vue.config.ignoredElements = [/dwanes-\w*/];A veces puede ser necesario llamar a un método de un Web Component. Por ejemplo, para borrar la pantalla del componente de teclado, se llama al método cancelAction se llama al método Antes de poder utilizar el método, es necesario crear una referencia al elemento del teclado. Vue tiene una forma similar a React para conseguirlo: añadiendo una etiqueta ref etiqueta al Web Component.
En el componente de teclado, que parece:
<dwanes-keypad ref="keypad" ...>
Entonces el cancelAction se llama con:
this.$refs.keypad.cancelAction(); Vue 3
Ver el Pen Componentes Web x Vue 3 por conshus de OUR show (@conshus) en CodePen.
Vue 3 acaba de salir. Sigue siendo brillante y nueva (y cambiante).
Como se ha dicho antes, la sintaxis de los componentes Vue se basa libremente en la Web Components Spec. Por lo tanto, utilizar un Web Component en Vue 3 sería lo mismo que en Vue 2, ¿verdad? Pues no. Hay un cambio importante a la hora de hacer saber a la aplicación que se está utilizando un Web Component.
Encontrará más detalles sobre el cambio en la Guía de Migración: config.ignoredElements Es ahora config.isCustomElement
Interoperabilidad de elementos personalizados.
En resumen, el ignoredElements en Vue 2 se convierte en isCustomElement en Vue 3. En lugar de un array isCustomElement espera una función que describa qué buscar. Además, ahora en Vue 3, la comprobación para ver si el elemento es un elemento personalizado externo (es decir, Web Component) se realiza durante la compilación de la plantilla.
Si la compilación de la plantilla se realiza "sobre la marcha", isCustomElement se pasa en la configuración de la aplicación. En el código de demostración, que se parece:
const app = Vue.createApp(App);
app.config.isCustomElement = tag => tag.startsWith('dwanes-')
app.mount('#app');
Si el proyecto tiene archivos .vue se utiliza un paso de compilación para convertir la aplicación en código comprensible para el navegador. En este caso, el isCustomElement se pasa a las opciones de la biblioteca que realiza la compilación. La librería depende de lo que el desarrollador decida utilizar. En la siguiente sección, el código de demostración utiliza webpack y mostrará cómo incluir isCustomElement en el archivo de configuración.
Obtener una referencia a un Web Component en Vue 3 se hace, afortunadamente, de la misma manera que en Vue 2, en el momento de la publicación de este blog.
Composición API
La API de composición de Vue se creó para ayudar a resolver algunas limitaciones a las que se enfrentaban los desarrolladores a medida que las aplicaciones crecían con el tiempo y se hacían más complejas. En la documentación:
"Las API propuestas en esta RFC proporcionan a los usuarios más flexibilidad a la hora de organizar el código de los componentes. En lugar de verse obligados a organizar siempre el código por opciones, ahora el código puede organizarse como funciones, cada una de las cuales se ocupa de una característica específica. Las API también facilitan la extracción y reutilización de la lógica entre componentes, o incluso fuera de ellos."
Le recomiendo encarecidamente que lea la documentación de la API de composición documentación para obtener una mejor comprensión. Aquí, me centraré en conseguir que un Web Component funcione con ella. Se trata de cómo se utiliza la referencia al componente.
Permitir que una aplicación Vue sepa que hay un Web Component ha cambiado de la versión 2 a la 3.
Dependiendo de cómo la aplicación compila la plantilla, determina dónde colocar la configuración. En el ejemplo anterior, la compilación de la plantilla se hacía "sobre la marcha". Este ejemplo de Composition API utiliza Webpack para compilar la plantilla. Esto significa que la isCustomElement va en el archivo webpack.config.js archivo. Allí encontrarás este código:
{
test: /\.vue$/,
use: {
loader: "vue-loader",
options: {
compilerOptions: {
isCustomElement: (tag) => {
return /^dwanes-/.test(tag);
}
}
}
}
}
Independientemente del motor de compilación, probablemente exista un archivo .config.js y ahí es donde se colocaría el fragmento anterior.
En la API de composición, la función ref ha crecido para incluir el seguimiento de otros valores, no sólo elementos DOM.
La dirección ref añadido al componente del teclado permanece igual:
<dwanes-keypad ref="keypad" ...>
El primer cambio es que ref debe importarse:
import { ref } from 'vue';Entonces, la referencia necesita ser inicializada dentro de setup():
const keypad = ref(null);Asegúrese de añadir keypad al archivo return.
Así es como se accede al método cancelAction() del componente:
keypad.value.cancelAction();Asegúrese de tomar nota de value.
Lo mismo se hace para fijar y cambiar el placeholder texto.
Vonage Vuerify
Una cosa que aprendí cuando investigaba para esta entrada de blog es que a los proyectos basados en Vue les encanta ponerlo en el nombre si pueden. Véase Vuetify, Vuex, Revue, Vuedo, etc. Así que ¿cómo iba a dejar pasar la oportunidad de tomar el Vonage Verify API de Vonage y crear Vonage Vuerify?
Inténtelo.
¿Quieres probarlo por ti mismo? Primero, bifurca el código en codesandbox.io.
Nota: Deberá iniciar sesión.
Así es como funciona:
Configuración
Primero, necesitarás una cuenta de desarrollador de Vonage. Toma nota de tu clave y secreto de API que se encuentran en el panelya que necesitarás estos valores para la autenticación.
A continuación, en su proyecto codesandbox.io haga clic en "Panel de control del 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.
Hacia el final, está la sección "Llaves secretas". Coge las API Key y API Secret del Panel de Vonage y colócalas donde corresponda. Brand Name es la cadena que se enviará junto con el código de seguridad al usuario. En este caso, es VonageVuerify.
El código de App.vue es prácticamente igual que el código de la API de composición, excepto por la forma en que se gestionan los dígitos enviados desde el componente web y se envían al backend de Node Express.
Solicitar el código de seguridad
Si el usuario solicita el código de seguridad, se realiza una POST al punto final /request endpoint en el servidor enviando junto con el número de teléfono introducido en el cuerpo.
Una vez que la respuesta vuelve y es válida, se guarda el ID de la solicitud, se cambia el modo, se modifica algún texto del componente del teclado y se borra la pantalla. En caso contrario, se muestra un error.
Aquí está el 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);
});
}
servidor.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
});
}
}
}
);
});
Nota
workflow_ides la estrategia alternativa utilizada para entregar el código de seguridad al usuario. Encontrará las distintas opciones en la documentación. Esta aplicación utiliza Workflow 6, que sólo envía un mensaje SMS.
Verificación del código
Cuando el usuario intenta verificar con el código que recibió, se envía otra POST solicitud al /check endpoint en el servidor con el requestId guardada anteriormente y el código de seguridad.
Si el estado es correcto, se cambia el modo, se cambia la imagen, se cambia el texto del componente del teclado y se borra la visualización. Si el estado es un error, se muestra.
Aquí está el 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);
});
}
servidor.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 });
}
}
}
);
});
Nota: Si bifurca el código de la demo, los endpoints llamados en el archivo
App.vuepara reflejar el servidor de su proyecto.
Para obtener más información sobre la Verify API de Vonage, puedes consultar la documentación.
¿Alguna pregunta sobre lo tratado en este post? ¿Has incorporado Web Components en una aplicación Vue de otra manera? ¿Tienes un ejemplo de cómo usas Verify API de Vonage? Cuéntanos en nuestro Canal Slack de la comunidad.
img.alignnone { border-width: 0px !important; }