¿Qué hay de nuevo en Vue 3?

 

 

 

  • ¡Registro!

  • Índice
    1. provide / inject
    2. Teletransportarse
    3. Fragmentos
    4. API globales
    5. API de eventos
    6. Conclusión
      1. Recursos adicionales

    Vue 3 viene con muchas características nuevas e interesantes y cambios en algunas de las existentes que tienen como objetivo hacer que el desarrollo con el marco sea mucho más fácil y fácil de mantener. En este artículo, veremos algunas de estas nuevas funciones y cómo empezar a utilizarlas. También veremos algunos de los cambios realizados en las funciones existentes.

     

    Con el lanzamiento de Vue 3, los desarrolladores deben realizar la actualización desde Vue 2, ya que viene con un puñado de características nuevas que son muy útiles para crear componentes fáciles de leer y fáciles de mantener y formas mejoradas de estructurar nuestra aplicación en Vue. En este artículo veremos algunas de estas características.

    Al final de este tutorial, los lectores podrán;

    1. Conozca cómo usarlo provide / injecty cómo usarlo.
    2. Tener conocimientos básicos de Teleport y cómo utilizarlo.
    3. Conozca los fragmentos y cómo utilizarlos.
    4. Conozca los cambios realizados en la API de Global Vue.
    5. Conozca los cambios realizados en la API de Eventos.

    Este artículo está dirigido a aquellos que tienen un conocimiento adecuado de Vue 2.x. Puedes encontrar todo el código utilizado en este ejemplo en GitHub .

    provide / inject

    En Vue 2.x, facilitamos propsla transferencia de datos (cadenas, matrices, objetos, etc.) desde un componente principal directamente a su componente secundario. Pero durante el desarrollo, a menudo encontramos casos en los que necesitábamos pasar datos del componente principal a un componente profundamente anidado con el que era más difícil hacerlo props. Esto resultó en el uso de Vuex Store, Event Hub y, en ocasiones, el paso de datos a través de componentes profundamente anidados. Veamos una aplicación sencilla;

    Es importante tener en cuenta que Vue 2.2.0 también viene con un provide / injectcódigo que no se recomienda para aplicaciones genéricas.

    # parentComponent.vuetemplate div img alt="Vue logo" src="../assets/logo.png" / HelloWorld msg="Vue 3 is liveeeee!" :color="color" / select name="color" v-model="color" option value="" disabled selected Select a color/option option :value="color" v-for="(color, index) in colors" :key="index"{{ color }}/option/select /div/templatescript import HelloWorld from "@/components/HelloWorld.vue"; export default { name: "Home", components: { HelloWorld, }, data() { return { color: "", colors: ["red", "blue", "green"], }; }, };/script
    # childComponent.vuetemplate div h1{{ msg }}/h1 color-selector :color="color"/color-selector /div/templatescript import colorSelector from "@/components/colorComponent.vue"; export default { name: "HelloWorld", components: { colorSelector, }, props: { msg: String, color: String, }, };/script!-- Add "scoped" attribute to limit CSS to this component only --style scoped h3 { margin: 40px 0 0; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0 10px; } a { color: #42b983; }/style
    # colorComponent.vuetemplate p :class="[color]"This is an example of deeply nested props!/p/templatescript export default { props: { color: String, }, };/scriptstyle .blue { color: blue; } .red { color: red; } .green { color: green; }/style

    Aquí, tenemos una página de inicio con un menú desplegable que contiene una lista de colores y pasamos el seleccionado colorcomo childComponent.vueaccesorio. Este componente secundario también tiene un msgaccesorio que acepta un texto para mostrar en la sección de plantilla. Finalmente, este componente tiene un componente secundario ( colorComponent.vue) que acepta un coloraccesorio del componente principal que se utiliza para determinar la clase del texto en este componente. Este es un ejemplo de cómo pasar datos a través de todos los componentes.

     

    Pero con Vue 3, podemos hacer esto de una manera más limpia y breve usando el nuevo par Provide and Inject. Como su nombre lo indica, utilizamos provideas una función o un objeto para hacer que los datos estén disponibles desde un componente principal a cualquiera de sus componentes anidados, independientemente de qué tan profundamente anidado esté dicho componente. Hacemos uso de la forma de objeto cuando pasamos valores codificados para que provideme guste esto;

    # parentComponent.vuetemplate div img alt="Vue logo" src="../assets/logo.png" / HelloWorld msg="Vue 3 is liveeeee!" :color="color" / select name="color" v-model="color" option value="" disabled selected Select a color/option option :value="color" v-for="(color, index) in colors" :key="index"{{ color }}/option/select /div/templatescript import HelloWorld from "@/components/HelloWorld.vue"; export default { name: "Home", components: { HelloWorld, }, data() { return { colors: ["red", "blue", "green"], }; }, provide: { color: 'blue' } };/script

    Pero para los casos en los que necesita pasar una propiedad de instancia de componente a provide, usamos el modo de función para que esto sea posible;

    # parentComponent.vuetemplate div img alt="Vue logo" src="../assets/logo.png" / HelloWorld msg="Vue 3 is liveeeee!" / select name="color" v-model="selectedColor" option value="" disabled selected Select a color/option option :value="color" v-for="(color, index) in colors" :key="index"{{ color }}/option/select /div/templatescript import HelloWorld from "@/components/HelloWorld.vue"; export default { name: "Home", components: { HelloWorld, }, data() { return { selectedColor: "blue", colors: ["red", "blue", "green"], }; }, provide() { return { color: this.selectedColor, }; }, };/script

    Como no necesitamos los coloraccesorios tanto en como childComponent.vueen colorComponent.vue, nos desharemos de ellos. Lo bueno de usarlo providees que el componente principal no necesita saber qué componente necesita la propiedad que proporciona.

     

    Para hacer uso de esto en el componente que lo necesita en este caso colorComponent.vuehacemos esto;

    # colorComponent.vuetemplate p :class="[color]"This is an example of deeply nested props!/p/templatescript export default { inject: ["color"], };/scriptstyle .blue { color: blue; } .red { color: red; } .green { color: green; }/style

    Aquí usamos injectque toma una matriz de las variables requeridas que necesita el componente. En este caso, solo necesitamos la colorpropiedad, por lo que solo la pasamos. Después de eso, podemos usarlo de colorla misma manera que lo usamos cuando usamos accesorios.

    Podríamos notar que si intentamos seleccionar un nuevo color usando el menú desplegable, el color no se actualiza colorComponent.vuey esto se debe a que, de forma predeterminada, las propiedades provideno son reactivas. Para solucionarlo, utilizamos el computedmétodo.

    # parentComponent.vuetemplate div img alt="Vue logo" src="../assets/logo.png" / HelloWorld msg="Vue 3 is liveeeee!" / select name="color" v-model="selectedColor" option value="" disabled selected Select a color/option option :value="color" v-for="(color, index) in colors" :key="index"{{ color }}/option/select /div/templatescript import HelloWorld from "@/components/HelloWorld.vue"; import { computed } from "vue"; export default { name: "Home", components: { HelloWorld, }, data() { return { selectedColor: "", todos: ["Feed a cat", "Buy tickets"], colors: ["red", "blue", "green"], }; }, provide() { return { color: computed(() = this.selectedColor), }; }, };/script

    Aquí, importamos computedy pasamos nuestro selectedColorpara que pueda ser reactivo y actualizarse cuando el usuario selecciona un color diferente. Cuando pasa una variable al método calculado, devuelve un objeto que tiene una extensión value. Esta propiedad contiene el valor de su variable, por lo que para este ejemplo tendríamos que actualizar colorComponent.vuepara lucir así;

    # colorComponent.vuetemplate p :class="[color.value]"This is an example of deeply nested props!/p/templatescript export default { inject: ["color"], };/scriptstyle .blue { color: blue; } .red { color: red; } .green { color: green; }/style

    Aquí, cambiamos colora color.valuepara representar el cambio después de hacer colorreactivo usando el computedmétodo. En este punto, el classtexto en este componente siempre cambiará cada vez que selectedColorcambie el componente principal.

     

    Teletransportarse

    Hay casos en los que creamos componentes y los colocamos en una parte de nuestra aplicación debido a la lógica que utiliza la aplicación, pero están destinados a mostrarse en otra parte de nuestra aplicación. Un ejemplo común de esto sería un modal o una ventana emergente destinada a mostrar y cubrir toda la pantalla. Si bien podemos crear una solución alternativa para esto usando positionla propiedad de CSS en dichos elementos, con Vue 3, también podemos hacerlo usando Teleport.

    Teleport nos permite sacar un componente de su posición original en un documento, desde el #appcontenedor predeterminado en el que están empaquetadas las aplicaciones Vue, y moverlo a cualquier elemento existente en la página que se está utilizando. Un buen ejemplo sería usar Teletransporte para mover un componente de encabezado desde dentro del #appdiv a un. headerEs importante tener en cuenta que solo puede teletransportarse a elementos que existen fuera de Vue DOM.

    Mensaje de error de teletransporte en la consola: Mensaje de error de destino de teletransporte no válido en la terminal. ( Vista previa grande )
    Todos sobre el antiguo egipto

    El componente Teleport acepta dos accesorios que determinan el comportamiento de este componente y son;

    1. to
      Este accesorio acepta un nombre de clase, una identificación, un elemento o un atributo de datos-* . También podemos hacer que este valor sea dinámico pasando un :toaccesorio en lugar de tocambiar el elemento Teleport de forma dinámica.
    2. :disabled
      Este accesorio acepta Booleany se puede usar para alternar la función Teletransporte en un elemento o componente. Esto puede resultar útil para cambiar dinámicamente la posición de un elemento.

    Un ejemplo ideal del uso de Teleport se ve así;

    # index.html**!DOCTYPE htmlhtmlhead meta charset="utf-8" / meta http-equiv="X-UA-Compatible" content="IE=edge" / meta name="viewport" content="width=device-width,initial-scale=1.0" / link rel="icon" href="%= BASE_URL %favicon.ico" / title %= htmlWebpackPlugin.options.title % /title/head!-- add container to teleport to --header/headerbody noscript strong We're sorry but %= htmlWebpackPlugin.options.title % doesn't work properly without JavaScript enabled. Please enable it to continue./strong /noscript div/div !-- built files will be auto injected --/body/html

    En el archivo predeterminado index.htmlde su aplicación Vue, agregamos un headerelemento porque queremos teletransportar nuestro componente de encabezado a ese punto en nuestra aplicación. También agregamos una clase a este elemento para darle estilo y facilitar la referencia en nuestro componente Teleport.

     

    # Header.vue**template teleport to="header" h1Vue 3 /h1 nav router-link to="/"Home/router-link /nav /teleport/templatescript export default { name: "app-header", };/scriptstyle .header { display: flex; align-items: center; justify-content: center; } .logo { margin-right: 20px; }/style

    Aquí, creamos el componente de encabezado y agregamos un logotipo con un enlace a la página de inicio de nuestra aplicación. También agregamos el componente Teleport y le damos al toaccesorio un valor de headerporque queremos que este componente se represente dentro de este elemento. Finalmente, importamos este componente a nuestra aplicación;

    # App.vuetemplate router-view / app-header/app-header/templatescript import appHeader from "@/components/Header.vue"; export default { components: { appHeader, }, };/script

    En este archivo, importamos el componente del encabezado y lo colocamos en la plantilla para que pueda ser visible en nuestra aplicación.

    Ahora, si inspeccionamos el elemento de nuestra aplicación, notaremos que nuestro componente de encabezado está dentro del headerelemento;

    Componente de encabezado en DevTools ( vista previa grande )

    Fragmentos

    Con Vue 2.x, era imposible tener varios elementos raíz en el templatearchivo y, como solución alternativa, los desarrolladores comenzaron a agrupar todos los elementos en un elemento principal. Si bien esto no parece un problema grave, hay casos en los que los desarrolladores quieren renderizar un componente sin un contenedor que envuelva dichos elementos, pero tienen que conformarse con eso.

    Con Vue 3, se introdujo una nueva característica llamada Fragmentos y esta característica permite a los desarrolladores tener múltiples elementos en su archivo de plantilla raíz. Entonces, con Vue 2.x, así es como se vería un componente contenedor de campo de entrada;

    # inputComponent.vuetemplate div label :for="label"label/label input :type="type" :id="label" :name="label" / /div/templatescript export default { name: "inputField", props: { label: { type: String, required: true, }, type: { type: String, required: true, }, }, };/scriptstyle/style

    Aquí, tenemos un componente de elemento de formulario simple que acepta dos accesorios, labely type, y la sección de plantilla de este componente está envuelta en un div. Esto no es necesariamente un problema, pero si desea que la etiqueta y el campo de entrada estén directamente dentro de su formelemento. Con Vue 3, los desarrolladores pueden reescribir fácilmente este componente para que tenga este aspecto;

    # inputComponent.vuetemplate label :for="label"{{ label }}/label input :type="type" :id="label" :name="label" //template

    Con un único nodo raíz, los atributos siempre se atribuyen al nodo raíz y también se conocen como atributos no relacionados . Son eventos o atributos pasados ​​a un componente que no tienen las propiedades correspondientes definidas en propso emits. Ejemplos de tales atributos son classy id. Sin embargo, es necesario definir explícitamente a cuál de los elementos de un componente de nodo multiraíz se debe atribuir.

     

    Esto es lo que significa usar el inputComponent.vuede arriba;

    1. Al agregar classa este componente en el componente principal, se debe especificar a qué componente se le classatribuiría; de lo contrario, el atributo no tendrá ningún efecto.
    template div div input-component label="name" type="text" /input-component /div /div/templatestyle .awesome__class { border: 1px solid red; }/style

    Cuando haces algo como esto sin definir dónde se deben atribuir los atributos, recibes esta advertencia en tu consola;

    Mensaje de error en la terminal cuando los atributos no están distribuidos ( vista previa grande )

    Y borderno tiene ningún efecto sobre el componente;

    Componente sin distribución de atributos ( vista previa grande )

    1. Para solucionar este problema, agregue un v-bind="$attrs"elemento al que desea que se distribuyan dichos atributos;
    template label :for="label" v-bind="$attrs"{{ label }}/label input :type="type" :id="label" :name="label" //template

    Aquí, le decimos a Vue que queremos que los atributos se distribuyan al labelelemento, lo que significa que queremos que awesome__classse le apliquen. Ahora, si inspeccionamos nuestro elemento en el navegador, veremos que la clase ya ha sido agregada labely, por lo tanto, ahora hay un borde alrededor de la etiqueta.

    Componente con distribución de atributos ( vista previa grande )

    API globales

    No era raro ver una aplicación Vue Vue.componenten Vue.useel archivo. main.jsEste tipo de métodos se conocen como API globales y hay bastantes de ellos en Vue 2.x. Uno de los desafíos de este método es que hace imposible aislar ciertas funcionalidades en una instancia de su aplicación (si tiene más de una instancia en su aplicación) sin que afecte a otras aplicaciones porque todas están montadas en Vue. Esto es lo que quiero decir;

    Vue.directive('focus', { inserted: el = el.focus()})Vue.mixin({ /* ... */})const app1 = new Vue({ el: '#app-1' })const app2 = new Vue({ el: '#app-2' })

    Para el código anterior, es imposible indicar que la Directiva Vue esté asociada app1y el Mixin, app2pero en cambio, ambos están disponibles en las dos aplicaciones.

    Vue 3 viene con una nueva API global en un intento de solucionar este tipo de problema con la introducción de createApp. Este método devuelve una nueva instancia de una aplicación Vue. Una instancia de aplicación expone un subconjunto de las API globales actuales. Con esto, todas las API (componente, mixin, directiva, uso, etc.) que mutan Vuedesde Vue 2.x ahora se moverán a instancias de aplicaciones individuales y ahora, cada instancia de su aplicación Vue puede tener funcionalidades que son únicas para ellas. sin afectar otras aplicaciones existentes.

     

    Ahora, el código anterior se puede reescribir como;

    const app1 = createApp({})const app2 = createApp({})app1.directive('focus', { inserted: el = el.focus()})app2.mixin({ /* ... */})

    Sin embargo, es posible crear funcionalidades que desee compartir entre todas sus aplicaciones y esto se puede hacer utilizando una función de fábrica .

    API de eventos

    Una de las formas más comunes que adoptaron los desarrolladores para pasar datos entre componentes que no tienen una relación padre-hijo aparte de usar Vuex Store es el uso de Event Bus . Una de las razones por las que este método es común es por lo fácil que es comenzar con él;

    # eventBus.jsconst eventBus = new Vue()export default eventBus;

    Después de esto, lo siguiente sería importar este archivo para main.jsque esté disponible globalmente en nuestra aplicación o importarlo en los archivos que necesite;

    # main.jsimport eventBus from 'eventBus'Vue.prototype.$eventBus = eventBus

    Ahora puedes emitir eventos y escuchar eventos emitidos como este;

    this.$eventBus.$on('say-hello', alertMe)this.$eventBus.$emit('pass-message', 'Event Bus says Hi')

    Hay una gran cantidad de código base de Vue que está lleno de códigos como este. Sin embargo, con Vue 3, sería imposible hacerlo porque $on, $offy $oncese han eliminado, pero $emitaún están disponibles porque es necesario que el componente secundario emita eventos a sus componentes principales. Una alternativa a esto sería utilizar provide / injectcualquiera de las bibliotecas de terceros recomendadas .

    Conclusión

    En este artículo, hemos cubierto cómo puede pasar datos desde un componente principal a un componente secundario profundamente anidado utilizando el provide / injectpar. También hemos analizado cómo podemos reposicionar y transferir componentes de un punto de nuestra aplicación a otro. Otra cosa que analizamos es el componente de nodo multiraíz y cómo asegurarnos de distribuir los atributos para que funcionen correctamente. Finalmente, también cubrimos los cambios en la API de eventos y la API global.

    Recursos adicionales

    • “ Funciones de fábrica de JavaScript con ES6+ ”, Eric Elliott, medio
    • " Uso de Event Bus para compartir accesorios entre componentes de Vue ", Kingsley Silas, CSS-Tricks
    • Uso de múltiples teletransportes en el mismo objetivo , Vue.js Docs
    • Atributos no relacionados con la propiedad , documentos Vue.js
    • Trabajando con reactividad , Vue.js Docs
    • teleport, Documentos de Vue.js
    • Fragmentos , Documentos Vue.js
    • Sintaxis 2.x , Documentos de Vue.js

    (ks, ra, il)Explora más en

    • vista
    • javascript
    • Marcos





    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    ¿Qué hay de nuevo en Vue 3?

    ¿Qué hay de nuevo en Vue 3?

    ¡Registro! Índice provide / inject Teletran

    programar

    es

    https://aprendeprogramando.es/static/images/programar-que-hay-de-nuevo-en-vue-3ja-1072-0.jpg

    2024-05-21

     

    ¿Qué hay de nuevo en Vue 3?
    ¿Qué hay de nuevo en Vue 3?

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20