- Aprender
-
Ecosistema
Ayuda
Herramientas
Librerías Oficiales
Noticias
Lista de Recursos
- Equipo
- Apoyar Vue
- Traducciones
Guía
Conocimientos Esenciales
- Instalación
- Introducción
- La instancia Vue
- Sintaxis de Template
- Propiedades Computadas y Observadores
- Enlace Clases y Estilos
- Renderización Condicional
- Renderizado de lista
- Manejo de eventos
- Binding en Formularios
- Conceptos Básicos de Componentes
Transiciones & Animaciones
- Efectos de Transición
Componentes en Profundidad
- Registro de Componente
- Propiedades
- Eventos personalizados
- Slots
- Componentes Dinámicos & Asíncronos
- Handling Edge Cases
- Transiciones de estado
Reusabilidad & Composición
- Mixins
- Directivas Personalizadas
- Funciones de renderizado & JSX
- Plugins
- Filtros
- Publicación en Producción
Herramientas
- Componentes de un Solo Archivo (Single File Components)
- Testing Unitario
- Soporte TypeScript
Escalando la Aplicación
- Enrutamiento
- Administración del Estado
- Renderizado del lado de Servidor
Funcionamiento Interno
- Reactividad en profundidad
Migraciones
- Migración desde Vue 1.x
- Migración desde Vue Router 0.7.x
- Migración de Vuex 0.6.x a 1.0
Meta Documentación
- Comparación con otros frameworks
- Únete a la comunidad Vue.js!
- Conozca al equipo
Migración desde Vue 1.x
Preguntas frecuentes
Woah - ¡esta página es súper larga! ¿Eso significa que la versión 2.0 es completamente diferente y tendré que aprender los conceptos básicos una y otra vez y la migración será prácticamente imposible?
¡Me alegra que lo pregunte! La respuesta es no. Alrededor del 90% de la API es la misma y los conceptos básicos no han cambiado. Es largo porque nos gusta ofrecer explicaciones muy detalladas e incluir muchos ejemplos. Quédese tranquilo, ¡esto no es algo que tenga que leer de arriba abajo!
¿Por dónde debería comenzar una migración?
Comience ejecutando el asistente de migración en un proyecto actual. Hemos minimizado y comprimido cuidadosamente un desarrollador de Vue senior en una interfaz de línea de comando simple. Así, cada vez que se reconoce una característica obsoleta, le informa, ofrece sugerencias y proporciona enlaces a más información.
Después de eso, navegue por la tabla de contenido de esta página en la barra lateral. Si ve un tema que puede afectarle, pero que el asistente de migración no captó, compruébelo.
Si usted tiene algunos tests, ejecútelos y vea los que aún fallan. Si no tiene tests, solo abra la aplicación en su navegador y esté atento a las advertencias o errores mientras navega.
En este punto, su aplicación debería estar migrada por completo. Si aún tiene ganas de más, puede leer el resto de esta página desde el principio. Muchas partes serán demasiado fáciles, ya que ya está familiarizado con los conceptos básicos.
¿Cuánto tiempo me llevará migrar una aplicación de Vue 1.x a 2.0?
Depende de algunos factores:
El tamaño de su aplicación (en las aplicaciones pequeñas y medianas probablemente será menos de un día)
Cuantas veces se distrae y comienza a jugar con una nueva función genial.😉 No le juzgamos, ¡a nosotros también nos pasó mientras construíamos 2.0!
Las funciones obsoletas que esté usando. La mayoría se pueden actualizar con Buscar y Reemplazar, pero otras pueden tardar unos minutos. Si actualmente no está siguiendo las mejores prácticas, Vue 2.0 también intentará forzarle más a hacerlo. Esto es algo bueno a largo plazo, pero también podría significar una actualización significativa (aunque posiblemente le retrase).
Si actualizo a Vue 2, ¿también tendré que actualizar Vuex y Vue Router?
Solo Vue Router 2 es compatible con Vue 2, así que sí, también tendrá que seguir la ruta de migración de Vue Router. Afortunadamente, la mayoría de aplicaciones no tienen mucho código de rutas, por lo que probablemente no le tome más de una hora.
En cuanto a Vuex, incluso la versión 0.8 es compatible con Vue 2, por lo que no está obligado a actualizar. La única razón por la que es posible que desee actualizar de inmediato es aprovechar las nuevas funciones de Vuex 2, como los módulos y el boilerplate reducido.
Plantillas
Fragmentos de instancias quitada
Cada componente debe tener exactamente un elemento raíz. Las instancias de fragmentos ya no están permitidas. Si tienes una plantilla como esta:
<p>foo</p> |
Se recomienda envolver todo el contenido en un nuevo elemento, como este:
<div> |
Ruta de actualización
Ejecute sus pruebas de extremo a extremo o su aplicación después de la actualización y busque advertencias en la consola sobre varios elementos raíz en una plantilla.
Hooks del ciclo de vida
beforeCompile
quitado
Utilice el hook created
en su lugar.
Ruta de actualización
Ejecute el asistente de migraciones en su código base para encontrar usos de este hook.
compiled
sustituido
En cambio use el nuevo hook mounted
.
Ruta de actualización
Ejecute el asistente de migraciones en su código base para encontrar usos de este hook.
attached
quitado
Utilice un chequeo personalizado en el DOM en otros hooks. Por ejemplo, para reemplazar:
attached: function () { |
Usted podría usar:
mounted: function () { |
Ruta de actualización
Ejecute el asistente de migraciones en su código base para encontrar usos de este hook.
detached
quitado
Utilice un chequeo personalizado en el DOM en otros hooks. Por ejemplo, para reemplazar:
detached: function () { |
Usted podría usar:
destroyed: function () { |
Ruta de actualización
Ejecute el asistente de migraciones en su código base para encontrar usos de este hook.
init
renombrado
Use el hook beforeCreate
hook en su lugar, que es esencialmente lo mismo. Se cambió su nombre por coherencia con otros métodos de ciclo de vida.
Ruta de actualización
Ejecute el asistente de migraciones en su código base para encontrar usos de este hook.
ready
sustituido
Use el nuevo hook mounted
en su lugar. Se debe tener en cuenta que con mounted
, no hay garantía de estar en el documento. Para eso, también incluya Vue.nextTick
/vm.$NextTick
. Por ejemplo:
mounted: function () { |
Ruta de actualización
Ejecute el asistente de migraciones en su código base para encontrar usos de este hook.
v-for
v-for
Orden de argumento para Arreglos cambiado
Cuando se incluye un índice
, el orden de los argumentos para los arreglos solía ser (índice, valor)
. Ahora es (valor, índice)
para ser más coherente con los métodos de matriz nativos de JavaScript, como forEach
ymap
.
Ruta de actualización
Ejecute el asistente de migración para encontrar ejemplos del orden de argumentos obsoleto. Tenga en cuenta que si nombra su argumento de índice con algún nombre inusual como position
o num
, el asistente no los encontrará.
v-for
Orden de argumento para Objetos cambiado
Cuando se incluye una clave
, el orden de los argumentos para los objetos solía ser (clave, valor)
. Ahora es (valor, clave)
para ser más consistente con iteradores de objetos comunes como lodash.
Ruta de actualización
Ejecute el asistente de migración para encontrar ejemplos del orden de argumento obsoleto. Tenga en cuenta que si nombra sus argumentos clave como name
o property
, el asistente no los encontrará.
$index
y $key
removido
Las variables implícitamente asignadas $index
y $key
se han eliminado a favor de definirlas explícitamente en v-for
. Esto hace que el código sea más fácil de leer para los desarrolladores con menos experiencia en Vue y también da como resultado un comportamiento mucho más claro cuando se trata de bucles anidados.
Ruta de actualización
Ejecute el asistente de migración para encontrar ejemplos de estas variables removidas en su código. Si usted se olvida de alguna, debería ver errores de consola como: Uncaught ReferenceError: $index is not defined
track-by
reemplazado
track-by
ha sido reemplazado por key
, que funciona como cualquier otro atributo: sin el prefijo v-bind:
o :
, se trata como una cadena de texto literal. En la mayoría de los casos, usted desearía utilizar un enlace dinámico que espera una expresión completa en lugar de una clave. Por ejemplo, en lugar de:
<div v-for="item in items" track-by="id"> |
Usted debería escribir:
<div v-for="item in items" v-bind:key="item.id"> |
Ruta de actualización
Ejecute el asistente de migración para encontrar ejemplos de track-by
en su código.
v-for
Valores de rango cambiado
Previamente, v-for="number in 10"
tenía number
empezando en 0 y terminando en 9. Ahora, comienza en 1 y termina en 10.
Ruta de actualización
Busque en su código con la expresión regular /\w+ in \d+/
. Donde sea que aparezca en un v-for
, verifique si puede verse afectado.
Props
Opción coerce
de Props removido
Si usted quiere forzar una propiedad a retonar un valor diferente, configure un valor local computado basado en esta. Por ejemplo, en lugar de:
props: { |
Usted podría escribir:
props: { |
Hay algunas ventajas:
- Usted todavía tiene acceso al valor original de la propiedad.
- Usted se ve forzado a ser más explícito, dándole a su valor un nombre que lo diferencie del valor pasado en la propiedad.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar casos de la opción coerce
.
Opción twoWay
de Props removido
Las propiedades ahora son siempre en un sentido. Para producir efectos colaterales en el scope del padre, un componente debe emitir un evento explícitamente en vez de depender de una vinculación implícita. Por más información, vea:
- Eventos Personalizados
- Componentes
input
personalizados (utilizando eventos de componentes) - Administración del Estado
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar casos de la opción twoWay
.
Modifcadores .once
y .sync
en v-bind
removido
Las propiedades ahora son siempre en un sentido. Para producir efectos colaterales en el scope del padre, un componente debe emitir un evento explícitamente en vez de depender de una vinculación implícita. Por más información, vea:
- Eventos Personalizados
- Componentes
input
personalizados (utilizando eventos de componentes) - Administración del Estado
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar casos de los modificadores .once
y .sync
.
Mutación de Propiedades deprecado
Ahora, mutar una propiedad local es considerado un anti-patrón. por ejemplo, declarar una propiedad y luego mutar la misma mediante this.myProp = someOtherValue
en el componente. Dado el nuevo mecanismo de renderizado, siempre que el componente padre se re-renderice, los cambios locales de los componentes hijo se sobreescribirán.
La mayoría de los casos de uso que requieren mutar una propiedad pueden ser reemplazados por una de las siguientes opciones:
- una propiedad
data
, con la propiedad utilizada para indicar su valor por defecto - una propiedad computada
Ruta de actualización
Ejecute sus tests de punta a punta y luego de la actualización busque por advertencias en consola sobre mutación de propiedades.
Props on a Root Instance reemplazado
En las instancias raíz de Vue (creadas con new Vue({ ... })
), usted debe utilizar propsData
en vez de props
.
Ruta de actualización
Ejecute sus tests de punta a punta, si tiene. Los tests fallidos deberían alertarle que las propiedades pasadas a la instancia raíz ya no funcionan.
Propiedades computadas
cache: false
obsoleta
La invalidación del almacenamiento en caché de las propiedades computadas se eliminará en futuras versiones principales de Vue. Reemplace las propiedades computadas no almacenadas en caché con métodos, que tendrán el mismo resultado.
Por ejemplo:
template: '<p>message: {{ timeMessage }}</p>', |
O con métodos de componentes:
template: '<p>message: {{ getTimeMessage }}</p>', |
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de cache: false
.
Directivas incorporadas
Veracidad/falsedad con v-bind
cambiado
Cuando se usa con v-bind
, los únicos valores falsos son ahora: null
, undefined
y false
. Esto significa 0
y las cadenas de texto vacías evaluarán como verdaderas y se renderizarán. Entonces, por ejemplo, v-bind:draggable="''"
se representará como draggable="true"
.
Para los atributos enumerados, además de los valores falsos anteriores, la cadena "false"
también se representará como attr="false"
.
Tenga en cuenta que para otras directivas (por ejemplo, v-if
y v-show
), la veracidad normal de JavaScript aún se aplica.
Ruta de actualización
Ejecute sus pruebas de extremo a extremo, si tiene una. Las pruebas fallidas le alertarán sobre cualquier parte de su aplicación que pueda ser afectada por este cambio.
Escuchar eventos nativos en componentes con v-on
cambiado
Cuando se usa en un componente, v-on
ahora solo escucha eventos personalizados ($emit
) emitidos por ese componente. Para escuchar un evento del DOM nativo en el elemento raíz, usted puede usar el modificador .native
. Por ejemplo:
<my-component v-on:click.native="doSomething"></my-component> |
Ruta de actualización
Ejecute sus pruebas de extremo a extremo, si tiene una. Las pruebas fallidas le alertarán sobre cualquier parte de su aplicación que pueda ser afectada por este cambio.
debounce
Atributo de parámetro para v-model
eliminado
Debouncing se usa para limitar la frecuencia con la que ejecutamos solicitudes Ajax y otras operaciones costosas. El parámetro de atributo debounce
de Vue para v-model
lo hizo fácil para casos muy simples, pero en realidad no dio lugar a actualizaciones de estado en lugar de las costosas operaciones en sí mismas. Es una diferencia sutil, pero viene con limitaciones a medida que aumenta la complejidad de la aplicación.
Estas limitaciones se hacen evidentes al diseñar un indicador de búsqueda, como este, por ejemplo:
Usando el atributo debounce
, no habría forma de detectar el estado “Escribiendo”, porque perdemos el acceso al estado en tiempo real de la entrada. Sin embargo, al desacoplar la función debounce de Vue, solo podemos eliminar la operación que queremos limitar, eliminando los límites de las funciones que podemos desarrollar:
<!-- |
new Vue({ |
Otra ventaja de este enfoque es que habrá momentos en que debouncing no será la función de envoltura correcta. Por ejemplo, al llamar a una API para buscar sugerencias, esperar para ofrecer sugerencias hasta después de que el usuario haya dejado de escribir por un período de tiempo no es una experiencia ideal. Lo que probablemente quieras es una función de throttling. Ahora, como ya está utilizando una biblioteca de utilidades como lodash, la refactorización para usar su función throttle
en su lugar solo lleva unos segundos.
Ruta de actualización
Ejecute el asistente de migración en su código fuente para encontrar usos de debounce
.
lazy
o number
Atributos de parámetro para v-model
cambiado
Los atributos de parámetro lazy
y number
ahora son modificadores, para que quede más claro lo que eso significa, veamos el siguiente ejemplo:
En vez de:
<input v-model="name" lazy> |
Usted usará:
<input v-model.lazy="name"> |
Ruta de actualización
Ejecute el asistente de migración en su código base para encontrar ejemplos de estos atributos de parámeto.
Atributo value
con v-model
eliminado
v-model
ya no se preocupa por el valor inicial de un atributo en línea value
. Para la previsibilidad, siempre tratará los datos de la instancia de Vue como la fuente de la verdad.
Eso significa que este elemento:
<input v-model="text" value="foo"> |
respaldado por estos datos:
data: { |
se renderizará con un valor de “bar” en lugar de “foo”. Lo mismo ocurre con un <textarea>
con contenido existente. En lugar de:
<textarea v-model="text"> |
Usted debe asegurarse de que su valor inicial para text
sea “Hola mundo”.
Ruta de actualización
Ejecute sus pruebas de extremo a extremo o su aplicación luego de la actualización, y busque advertencias de consola sobre valores en línea para atributos con v-model
.
v-model
con v-for
Valores primitivos iterados eliminados
Casos como este ya no funcionan:
<input v-for="str in strings" v-model="str"> |
La razón es que este es el código JavaScript equivalente que compilaría el <input>
:
strings.map(function (str) { |
Como usted puede ver, el enlace bidireccional de v-model
no tiene sentido aquí. Establecer str
en otro valor en la función de iterador no hará nada porque es solo una variable local en el alcance de la función.
En su lugar, usted debe utilizar un arreglo de Objetos para que v-model
pueda actualizar el campo en el objeto. Por ejemplo:
<input v-for="obj in objects" v-model="obj.str"> |
Ruta de actualización
Ejecute su conjunto de pruebas, si tiene uno. Las pruebas fallidas deberían alertarlo sobre cualquier parte de su aplicación que pueda verse afectada por este cambio.
v-bind:style
con sintaxis de Objeto y !important
eliminado
Esto ya no funcionará:
<p v-bind:style="{ color: myColor + ' !important' }">hola</p> |
Si usted realmente necesita anular otro !Important
, debe usar la sintaxis de cadena de texto:
<p v-bind:style="'color: ' + myColor + ' !important'">hola</p> |
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de estilos unidos con !important
en los Objetos.
v-el
y v-ref
cambiado
Para simplificar, v-el
y v-ref
se han fusionado en el atributo ref
, accesible en una instancia de componente a través de $refs
. Eso significa que v-el:my-element
se convertiría en ref="myElement"
y v-ref:my-component
se convertiría en ref="myComponent"
. Cuando se usa en un elemento normal, la ref
será el elemento DOM, y cuando se use en un componente, la ref
será la instancia del componente.
Como v-ref
ya no es una directiva, sino un atributo especial, también se puede definir dinámicamente. Esto es especialmente útil en combinación con v-for
. Por ejemplo:
<p v-for="item in items" v-bind:ref="'item' + item.id"></p> |
Anteriormente, v-el
/v-ref
combinado con v-for
produciría una serie de elementos/componentes, porque no había forma de darle a cada elemento un nombre único. Usted todavía puede lograr este comportamiento si le da a cada elemento la misma ref
:
<p v-for="item in items" ref="items"></p> |
A diferencia de 1.x, estos $refs
no son reactivos, porque están registrados/actualizados durante el proceso de renderización. Hacerlos reactivos requeriría renders duplicados para cada cambio.
Por otro lado, los $refs
están diseñados principalmente para el acceso programático en JavaScript; no se recomienda confiar en ellos en las plantillas, porque eso significaría referirse al estado que no pertenece a la instancia en sí. Esto violaría el modelo de vista basado en datos de Vue.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de v-el
y v-ref
.
v-else
con v-show
eliminado
v-else
ya no funciona con v-show
. Utilice v-if
con una expresión de negación en su lugar. Por ejemplo, en lugar de:
<p v-if="foo">Foo</p> |
Usted puede usar:
<p v-if="foo">Foo</p> |
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de v-else
con v-show
.
Directivas personalizadas simplificado
Las directivas tienen un alcance de responsabilidad muy reducido: ahora solo se usan para aplicar manipulaciones del DOM de bajo nivel. En la mayoría de los casos, debería preferir usar componentes como la abstracción principal de reutilización de código.
Algunas de las diferencias más notables incluyen:
- Las directivas ya no tienen instancias. Esto significa que no hay más
this
dentro de los hooks de la directiva. En cambio, reciben todo lo que puedan necesitar como argumentos. Si realmente debe persistir el estado a través de los hooks, puede hacerlo en el elementoel
. - Opciones como
acceptStatement
,deep
,priority
, etc han sido removidas. Para reemplazar directivastwoWay
, vea este ejemple. - Algunos de los hooks actuales tienen un comportamiento diferente y también algunos hooks nuevos.
Afortunadamente, dado que las nuevas directivas son mucho más simples, puede dominarlas más fácilmente. Lea la nueva Guía de directivas personalizadas para obtener más información.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de directivas definidas. El asistente las marcará a todas, ya que es probable que en la mayoría de los casos desee refactorizar a un componente.
Directiva .literal
Modificador removido
Se ha eliminado el modificador .literal
, ya que se puede lograr fácilmente proporcionando una cadena de texto como valor.
Por ejemplo, puede cambiar:
<p v-my-directive.literal="foo bar baz"></p> |
por:
<p v-my-directive="'foo bar baz'"></p> |
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos del modificador `.literal` en una directiva.
Transiciones
Atributo transition
reemplazado
El sistema de transición de Vue ha cambiado drásticamente y ahora usa elementos de envoltura <transition>
y <transition-group>
, en lugar del atributo transition
. Se recomienda leer la nueva Guía de transiciones para obtener más información.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos del atributo transition
.
Vue.transition
para transiciones reutilizables reemplazado
Con el nuevo sistema de transición, ahora puede usar componentes para transiciones reutilizables.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplose de Vue.transition
.
Atributo de Transición stagger
removido
Si necesita escalonar las transiciones de la lista, puede controlar el tiempo configurando y accediendo a un data-index
(o atributo similar) en un elemento. Vea un ejemplo aquí.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos del atributo transition
. Durante su actualización, usted puede hacer la transición (juego de palabras muy intencionado) a la nueva estrategia asombrosa también.
Eventos
Opción events
removido
La opción events
ha sido removida. Ahora, Los manejadores de eventos deben ser registrados en el hook created
. Vea la guía de migración de $dispatch
y $broadcast
para un ejemplo detallado.
Vue.directive('on').keyCodes
reemplazado
La nueva forma más concisa de configurar keyCodes
es a través de Vue.config.keyCodes
. Por ejemplo:
// habilitar v-on:keyup.f1 |
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de la vieja sintaxis de configuración de keyCode
.
$dispatch
y $broadcast
reemplazado
$dispatch
y $broadcast
han sido removidos en favor de una comunicación más explícita entre componentes y soluciones de manejo de estado más mantenibles, así como Vuex.
El problema son los flujos de eventos que dependen de la estructura del árbol de componentes, pueden ser difíciles de razonar y muy frágiles cuando el árbol se vuelve grande. No escala bien y no queremos prepararnos para sufrir luego. $dispatch
y $broadcast
tampoco resuelven la comunicación entre componentes hermanos.
Uno de los casos de uso más común para estos métodos es para la comunicación directa entre un componente padre y sus hijos. En estos casos, usted pueden escuchar a un $emit
desde un componente hijo con v-on
. Esto le permite mantener la conveniencia de los eventos.
Sin embargo, cuando se quiere comunicar descendientes/antepasados distantes, $emit
no le será de ayuda. En cambio, la forma más simple de resolver este problema sería utilizando un event hub centralizado. Esto tiene la ventaja de que permite comunicar componente sin importar dónde estén en el árbol de componentes - ¡incluso si son hermanos! Dado que las instancias de Vue implementan una interfaz de emisión de eventos, usted puede utilizar una instancia de Vue vacía para este propósito.
Por ejemplo, digamos que tenemos una aplicación de todo estructurada de la siguiente manera:
Todos |
Podríamos manejar la comunicación entre componentes con un simple event hub:
// Este es el event hub que usaremos en cada |
Luego, en nuestros componentes, podemos utilizar $emit
, $on
, $off
para emitir eventos, escuchar por eventos y para limpiar listeners respectivamente:
// NewTodoInput |
// DeleteTodoButton |
// Todos |
Este patrón puede servir como reemplazo para $dispatch
y $broadcast
en escenarios simples, pero para casos más complejos, se recomienda el uso de una capa dedicada al manejo de estado, tal como Vuex.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de $dispatch
y $broadcast
.
Filtros
Filtros fuera de interpolaciones de texto removido
Los filtros ahora solo pueden usarse dentro de interpolaciones de texto (etiquetas {{ }}
). En el pasado, descubrimos que usar filtros dentro de directivas como v-model
,v-on
, etc. conducía a una mayor complejidad que conveniencia. Para el filtrado de listas en v-for
, también es mejor mover esa lógica a JavaScript como propiedades computadas, para que pueda reutilizarse en todo su componente.
En general, cada vez que se puede lograr algo en JavaScript simple, queremos evitar la introducción de una sintaxis especial como filtros para atender la misma preocupación. Así es como puede reemplazar los filtros de directiva incorporados de Vue:
Reemplazando el Filtro debounce
En lugar de:
<input v-on:keyup="doStuff | debounce 500"> |
methods: { |
Use el debounce
de lodash (o posiblemente throttle
) para limitar directamente la llamada al método costoso. Puede lograr lo mismo que arriba así:
<input v-on:keyup="doStuff"> |
methods: { |
Para obtener más información sobre las ventajas de esta estrategia, consulte [el ejemplo aquí con v-model
]
(#debounce-Param-Attribute-for-v-model-removed).
Reemplazando el Filtro limitBy
En lugar de:
<p v-for="item in items | limitBy 10">{{ item }}</p> |
Use el .slice
de JavaScript en una propiedad computada:
<p v-for="item in filteredItems">{{ item }}</p> |
computed: { |
Reemplazando el Filtro filterBy
En lugar de:
<p v-for="user in users | filterBy searchQuery in 'name'">{{ user.name }}</p> |
Use el .filter
de JavaScript en una propiedad computada:
<p v-for="user in filteredUsers">{{ user.name }}</p> |
computed: { |
El .filter
nativo de JavaScript también puede manejar operaciones de filtrado mucho más complejas, porque tiene acceso a todo el poder de JavaScript dentro de las propiedades computadas. Por ejemplo, si desea encontrar todos los usuarios activos, filtrando por nombre y correo electrónico sin hacer distinción entre mayúsculas y minúsculas:
var self = this |
Reemplazando el Filtro orderBy
En lugar de:
<p v-for="user in users | orderBy 'name'">{{ user.name }}</p> |
Use el orderBy
de lodash (o posiblemente sortBy
) en una propiedad computada:
<p v-for="user in orderedUsers">{{ user.name }}</p> |
computed: { |
Incluso puede ordenar por múltiples columnas:
_.orderBy(this.users, ['name', 'last_login'], ['asc', 'desc']) |
Ruta de actualización
Ejecute el asistente de migración sobre su código para encontrar ejemplos de filtros que se utilizan dentro de las directivas. Si pierde alguno, también puede ver errores de consola .
Sintaxis de argumentos para filtros modificado
La sintaxis de los filtros para argumentos ahora se alinea mejor con la invocación de la función de JavaScript. Entonces, en lugar de tomar argumentos delimitados por espacios:
<p>{{ date | formatDate 'YY-MM-DD' timeZone }}</p> |
Rodeamos los argumentos con paréntesis y delimitamos los argumentos con comas:
<p>{{ date | formatDate('YY-MM-DD', timeZone) }}</p> |
Ruta de actualización
Ejecute el asistente de migración sobre su código para encontrar ejemplos de la sintaxis del filtro anterior. Si usted se olvida de alguno, debería ver errores de consola.
Filtros de texto incorporados removido
Aunque los filtros dentro de las interpolaciones de texto todavía están permitidos, todos los filtros se han eliminado. En cambio, se recomienda usar librerías más especializadas para resolver problemas en cada dominio (por ejemplo, date-fns
para formatear fechas y accounting
para monedas).
Para cada uno de los filtros de texto integrados de Vue, vamos a ver cómo puede reemplazarlos a continuación. El código de ejemplo podría existir en funciones auxiliares personalizadas, métodos o propiedades computadas.
Replacing the json
Filter
You actually don’t need to for debugging anymore, as Vue will nicely format output for you automatically, whether it’s a string, number, array, or plain object. If you want the exact same functionality as JavaScript’s JSON.stringify
though, then you can use that in a method or computed property.
Replacing the capitalize
Filter
text[0].toUpperCase() + text.slice(1) |
Replacing the uppercase
Filter
text.toUpperCase() |
Replacing the lowercase
Filter
text.toLowerCase() |
Replacing the pluralize
Filter
The pluralize package on NPM serves this purpose nicely, but if you only want to pluralize a specific word or want to have special output for cases like 0
, then you can also easily define your own pluralize functions. For example:
function pluralizeKnife (count) { |
Replacing the currency
Filter
For a very naive implementation, you could do something like this:
'$' + price.toFixed(2) |
In many cases though, you’ll still run into strange behavior (e.g. 0.035.toFixed(2)
rounds up to 0.04
, but 0.045
rounds down to 0.04
). To work around these issues, you can use the accounting
library to more reliably format currencies.
Upgrade Path
Run the migration helper on your codebase to find examples of the obsolete text filters. If you miss any, you should also see console errors.
Filtros bidireccionales reemplazado
Algunos usuarios han disfrutado el uso de filtros bidireccionales con v-model
para crear entradas o inputs interesantes con muy poco código. Sin embargo, aunque aparentemente son simples, los filtros bidireccionales también pueden ocultar una gran complejidad e incluso fomentar una mala experiencia de usuario al retrasar las actualizaciones de estado. En cambio, los componentes que envuelven una entrada se recomiendan como una forma más explícita y rica en características de crear entradas personalizadas.
Como ejemplo, ahora veremos la migración de un filtro bidireccional de moneda:
En su mayoría funciona bien, pero las actualizaciones de estado demoradas pueden causar un comportamiento extraño. Por ejemplo, haga clic en la pestaña Result
e intente ingresar 9.999
en una de esas entradas. Cuando la entrada pierde el foco, su valor se actualizará a $10.00
. Sin embargo, al observar el total calculado, verá que ‘9.999’ es lo que se almacena en nuestros datos. ¡La versión de la realidad que ve el usuario no está sincronizada!
Para comenzar la transición hacia una solución más robusta usando Vue 2.0, primero envolvamos este filtro en un nuevo componente <currency-input>
:
Esto nos permite agregar comportamiento que un filtro por sí solo no podría encapsular, como seleccionar el contenido de una entrada en foco. Ahora el siguiente paso será extraer la lógica de negocios del filtro. A continuación, sacamos todo a un objeto currencyValidator
externo:
Esta mayor modularidad no solo facilita la migración a Vue 2, sino que también permite que el análisis y el formato de moneda sean:
- probado como unidad aislada de su código Vue
- utilizado por otras partes de su aplicación, como para validar el payload de un endpoint de API
Una vez extraído este validador, también lo hemos convertido más cómodamente en una solución más robusta. Se han eliminado las peculiaridades del estado y en realidad es imposible que los usuarios ingresen algo incorrecto, similar a lo que intenta hacer la entrada number nativa del navegador.
Sin embargo, todavía estamos limitados por los filtros y por Vue 1.0 en general, así que completemos la actualización a Vue 2.0:
Puede notar que:
- Cada aspecto de nuestra entrada es más explícito, utilizando hooks de ciclo de vida y eventos DOM en lugar del comportamiento oculto de los filtros bidireccionales.
- Ahora podemos usar
v-model
directamente en nuestras entradas personalizadas, lo que no solo es más consistente con las entradas normales, sino que también significa que nuestro componente es compatible con Vuex. - Dado que ya no usamos opciones de filtro que requieren que se devuelva un valor, nuestro trabajo de monedas podría hacerse asincrónicamente. Eso significa que si tuviéramos muchas aplicaciones que tuvieran que funcionar con monedas, podríamos refactorizar fácilmente esta lógica en un microservicio compartido.
Ruta de actualización
Ejecute el asistente de migración sobre su código para encontrar ejemplos de filtros usados en directivas como v-model
. Si usted se olvida de alguno, debería ver errores de consola.
Slots
Slots Duplicados removido
Ya no se admite tener <slot>
s con el mismo nombre en la misma plantilla. Cuando se renderiza un slot, se “agota” y no se puede procesar en otro lugar del mismo árbol de procesamiento. Si debe representar el mismo contenido en varios lugares, pase ese contenido como propiedad.
Ruta de actualización
Ejecute su suite o aplicación de prueba de extremo a extremo después de la actualización y busque advertencias en la consola sobre slots v-model
duplicados.
slot
Atributo de Estiloremovido
El contenido insertado mediante el nombre <slot>
ya no conserva el atributo slot
. Utilice un elemento contenedor para aplicarles estilo, o para casos de uso avanzados, modifique el contenido insertado mediante programación utilizando funciones de renderizado.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar selectores CSS haciendo referencia a slots con nombres (ej: [slot="mi-nombre -de-slot"]
).
Atributos especiales
Atributo keep-alive
reemplazado
keep-alive
ya no es un atributo especial, sino más bien un componente contenedor, similar a <transition>
.
Por ejemplo:
<keep-alive> |
Esto hace posible usar <keep-alive>
en múltiples hijos condicionales:
<keep-alive> |
Cuando <keep-alive>
tiene varios hijos, eventualmente debería evaluar a un solo hijo. Cualquier hijo que no sea el primero será ignorado.
Cuando se usa junto con <transition>
, asegúrese de anidarlo dentro:
<transition> |
Ruta de actualización
Ejecutar el asistente de migración en su código para encontrar atributos keep-alive
.
Interpolaciones
Interpolaciones dentro de Atributos removido
La interpolación dentro de atributos ya no es válida. Por ejemplo:
<button class="btn btn-{{ size }}"></button> |
Debería actualizarse para utilizar una expresión inline:
<button v-bind:class="'btn btn-' + size"></button> |
O una propiedad data o computada:
<button v-bind:class="buttonClasses"></button> |
computed: { |
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de interpolaciones dentro de atributos.
Interpolación HTML removido
Las interpolaciones HTML ({{{ foo }}}
) han sido removidas en favor de la directiva v-html
.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar interpolaciones HTML.
Enlaces One-Time reemplazado
Los enlaces one-time ({{* foo }}
) han sido reemplazados por la nueva directiva v-once
.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar enlaces one-time.
Reactividad
vm.$watch
cambiado
Los watchers creados a través de vm.$watch
ahora se disparan antes de que el componente asociado se vuelva a renderizar. Esto le brinda la oportunidad de actualizar el estado antes de que el componente vuelva a renderizarse, evitando así actualizaciones innecesarias. Por ejemplo, puede observar una propiedad y actualizar sus propios datos cuando la propiedad cambia.
Si anteriormente usted dependía de vm.$watch
para hacer algo con el DOM después de las actualizaciones de un componente, usted puede hacerlo en el hook de ciclo de vida updated
.
Ruta de actualización
Ejecute su conjunto de pruebas de extremo a extremo, si tiene uno. Las pruebas que fallen les deberían de alertar sobre el hecho que un watcher dependía de un comportamiento anterior.
vm.$set
cambiado
vm.$set
ahora es un alias de Vue.set
.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de uso obsoleto.
vm.$delete
cambiado
vm.$delete
ahora es un alias de Vue.delete
.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de uso obsoleto.
Array.prototype.$set
removido
Use Vue.set
en su lugar.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de .$set
en un arreglo. Si usted se olvida de alguno, debería ver errores de consola en el método que falta.
Array.prototype.$remove
removido
Use Array.prototype.splice
en su lugar. Por ejemplo:
methods: { |
O mejor aún, pase los métodos de eliminación a un índice:
methods: { |
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de .$remove
en un arreglo. Si usted se olvida de alguno, debería ver errores de consola en el método que falta.
Vue.set
y Vue.delete
en las instancias de Vue removido
Vue.set
y Vue.delete
ya no se pueden utilizar en instancias de Vue. Ahora es obligatorio declarar correctamente todas las propiedades reactivas de nivel superior en la opción de datos. Si desea eliminar propiedades en una instancia de Vue o su $data
, configúrelo como nulo (null).
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de Vue.set
o Vue.delete
en su instancia de Vue. Si usted se olvida de alguno, ellos dispararán advertencias en la consola.
Reemplazando vm.$data
removido
Ahora está prohibido reemplazar los datos ($data) raíz de una instancia de componente. Esto evita algunos casos borde en el sistema de reactividad y hace que el estado del componente sea más predecible (especialmente con los sistemas de verificación de tipo).
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de reemplazo de vm.$data
.Si usted se olvida de alguno, ellos dispararán advertencias en la consola.
vm.$get
removido
En cambio, recupere datos reactivos directamente.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de reemplazo de vm.$data
.Si usted se olvida de alguno, ellos dispararán advertencias en la consola.
Métodos de instancia centrados en el DOM
vm.$appendTo
removido
Use la API nativa del DOM:
myElement.appendChild(vm.$el) |
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de vm.$appendTo
. En caso de omitir alguno, verá errores en la consola.
vm.$before
removido
Use la API nativa del DOM:
myElement.parentNode.insertBefore(vm.$el, myElement) |
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de vm.$before
. En caso de omitir alguno, verá errores en la consola.
vm.$after
removido
Use la API nativa del DOM:
myElement.parentNode.insertBefore(vm.$el, myElement.nextSibling) |
O si myElement
es el último hijo:
myElement.parentNode.appendChild(vm.$el) |
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de vm.$after
. En caso de omitir alguno, verá errores en la consola.
vm.$remove
removido
Use la API nativa del DOM:
vm.$el.remove() |
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de vm.$remove
. En caso de omitir alguno, verá errores en la consola.
Métodos de meta instancia
vm.$eval
removida
Sin uso real. Si de alguna manera confía en esta característica y no está seguro de cómo solucionarla, publique en el foro para obtener ideas.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de vm.$eval
. En caso de omitir alguno, usted verá errores en la consola.
vm.$interpolate
removida
Sin uso real. Si de alguna manera confía en esta característica y no está seguro de cómo solucionarla, publique en el foro para obtener ideas.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de vm.$interpolate
. En caso de omitir alguno, usted verá errores en la consola.
vm.$log
removida
Use las Vue Devtools para obtener una experiencia de depuración óptima.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de vm.$log
. En caso de omitir alguno, usted verá errores en la consola.
Opciones de la instancia DOM
replace: false
removido
Los componentes ahora siempre reemplazan al elemento al que están vinculados. Para simular el comportamiento de replace: false
, usted puede ajustar su componente raíz con un elemento similar al que está reemplazando. Por ejemplo:
new Vue({ |
O con una función de renderizado:
new Vue({ |
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de replace: false
.
Global Config
Vue.config.debug
removido
Ya no es necesario, ya que ahora las advertencias vienen con seguimiento de pila por defecto.
Ruta de actualización
Ejecute el asistente de migración sobre su código para encontrar ejemplos de Vue.config.debug
.
Vue.config.async
removido
Ahora async es requerido para el rendimiento de la renderización.
Ruta de actualización
Ejecute el asistente de migración sobre su código para encontrar ejemplos de Vue.config.async
.
Vue.config.delimiters
reemplazado
Esto se ha modificado como una opción a nivel de componente. Esto le permite usar delimitadores alternativos dentro de su aplicación sin romper componentes de terceros.
Ruta de actualización
Ejecute el asistente de migración sobre su código para encontrar ejemplos de Vue.config.delimiters
.
Vue.config.unsafeDelimiters
removido
La interpolación HTML ha sido removida en favor de v-html
.
Ruta de actualización
Ejecute el asistente de migración sobre su código para encontrar ejemplos de Vue.config.unsafeDelimiters
. Después de esto, el asistente encontrará también instancias de interpolación HTML para que pueda reemplazarlas con `v-html`.
API Global
Vue.extend
con el
removido
La opción el
ya no se puede usar en Vue.extend
. Solo es válido como una opción de creación de instancia.
Ruta de actualización
Ejecute su suite o aplicación de prueba de extremo a extremo después de la actualización y busque advertencias en la consola sobre el
con Vue.extend
.
Vue.elementDirective
removido
Use componentes en su lugar.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de Vue.elementDirective
.
Vue.partial
removido
Se han eliminado los parciales a favor de un flujo de datos más explícito entre los componentes, utilizando propiedades. A menos que esté usando un parcial en un área de rendimiento crítico, la recomendación es usar un componente normal en su lugar. Si usted vinculaba dinámicamente el nombre (name)
de un parcial, puede usar un componente dinámico.
Si utiliza parciales en una parte crítica de su aplicación, entonces debe actualizar a componentes funcionales. Deben estar en un archivo JS/JSX simple (en lugar de en un archivo .vue
) y no tienen estado ni instancia, como los parciales. Esto hace que el renderizado sea extremadamente rápido.
Una ventaja de los componentes funcionales sobre los parciales es que pueden ser mucho más dinámicos, ya que le otorgan acceso a todo el poder de JavaScript. Sin embargo, hay un costo para este poder. Si nunca antes ha usado un framework de componentes con funciones de renderizado, puede tardar un poco más en aprender.
Ruta de actualización
Ejecute el asistente de migración en su código para encontrar ejemplos de Vue.partial
.