Estoy tratando de usar un observador Vue en un objeto computado y no funciona en absoluto. Funciona correctamente si es solo una cadena, pero no si es un objeto. Seguí la documentación de Vue pero todavía no obtengo nada registrado en la consola cuando cambia el objeto. Las propiedades del objeto y la propiedad calculada están cambiando, como he confirmado en Vue Tools. ¿Qué estoy haciendo mal? Gracias
<v-btn small dark @click="test1.asdf = 'blah'">Test</v-btn> data() { return { test1: {}, } }, computed: { test() { return this.test1 } }, watch: { test: { handler: function(val, oldVal) { console.log(oldVal, val); }, deep: true } }Prueba este código, funciona bien
<template> <div id="app"> {{ test1 }} <hr /> <button @click="test1.asdf = 'blah'">Click</button> </div> </template> <script > export default { data() { return { test1: { asdf: "HEY" }, }; }, computed: { test() { return this.test1; }, }, watch: { test: { handler: function (val, oldVal) { console.log(oldVal, val); }, deep: true, }, }, }; </script> Supongo que en su caso debería agregar .native al final de su evento de clic como este @click.native="test1.asdf = 'blah'"
Acabo de intentar reemplazando todo el objeto. Funciona bastante bien y no hay necesidad de inicializar su objeto con la propiedad asdf en sus datos:
<v-btn small dark @click="test1 = { ...test1, asdf: 'blah'}">Test</v-btn> La sintaxis extendida ...test1 ayuda a mantener otras propiedades en el objeto de destino, si las hay, por lo que puede agregar con seguridad la propiedad asdf sin preocuparse por perder nada.
JSFiddle: https://jsfiddle.net/vh72a3bs/22/
@BadCoder Objects and Arrays se pasan por referencia en JavaScript, no se pasan por valor. Esto significa que cuando agrega una clave al objeto como lo está haciendo en su pregunta, solo está agregando al mismo Objeto. Su contenido ha cambiado, pero su variable test1 todavía hace referencia al objeto original y no sabe que su contenido se ha actualizado. El observador no detecta este cambio. Puede agregar deep: true a su observador como sugirió otro respondedor, pero esto solo observa un par de niveles de profundidad, por lo que no es ideal si tiene un objeto grande con muchos datos anidados. La forma más confiable de activar un observador cuando se trata de matrices u objetos es crear una nueva instancia de ese objeto. Puede lograr esto con la destrucción de objetos. Algo como,
<v-btn small dark @click="test1 = { ...test1, asdf: 'blah'}">Test</v-btn>funciona porque está creando un nuevo objeto (usando los atributos de los objetos anteriores, más cualquier cosa nueva), activando el observador.