vuejs vue versiones que logo framework certification javascript mvvm vue.js

javascript - versiones - vue.js que es



Vue JS Observando el objeto anidado profundo (4)

Descargo de responsabilidad: Este es mi primer intento de crear una aplicación MVVM. Tampoco he trabajado con vue.js anteriormente, por lo que podría ser que mi problema sea el resultado de un problema más fundamental.

En mi opinión, tengo dos tipos de bloques con casillas de verificación:

  • Tipo 1: bloque / casillas de verificación
  • Tipo 2: bloque / encabezados / casillas de verificación

El objeto subyacente está estructurado así:

{ "someTopLevelSetting": "someValue", "blocks": [ { "name": "someBlockName", "categryLevel": "false", "variables": [ { "name": "someVarName", "value": "someVarValue", "selected": false, "disabled": false } ] }, { "name": "someOtherBlockName", "categryLevel": "true", "variables": [ { "name": "someVarName", "value": "someVarValue", "categories": [ { "name": "SomeCatName", "value": "someCatValue", "selected": false, "disabled": false } ] } ] } ] }

Mis objetivos

Seleccionar casillas de verificación:

  1. El usuario hace clic en la casilla de verificación, la casilla de verificación está seleccionada (seleccionada = verdadera)
  2. Se dispara un método para verificar si hay otras casillas de verificación que se deben deshabilitar (deshabilitado = verdadero). (Si este método ha desactivado algo, también se llama a sí mismo de nuevo, porque otros elementos podrían ser a su vez dependientes del elemento desactivado)
  3. Otro método actualiza algunas otras cosas, como iconos, etc.

Borrar casillas de verificación

Un usuario puede hacer clic en un botón "borrar", que desmarca todas las casillas de verificación de una lista (seleccionado = falso). Esta acción también debe desencadenar los métodos que inhabilitan casillas de verificación y actualizaciones de iconos, etc.

Mi método actual (que no parece del todo correcto)

  • El atributo seleccionado del modelo de datos está vinculado al estado verificado del elemento casilla de verificación a través de la directiva v-model .
  • El atributo deshabilitado (del modelo) está vinculado a la clase del elemento y al atributo deshabilitado. Este estado se establece mediante el método mencionado anteriormente.
  • Para inicializar los métodos que deshabilitan las casillas de verificación y cambiar algunos iconos, estoy usando una directiva v-on="change: checkboxChange(this)" . Creo que necesito hacer esta parte de manera diferente
  • El método clearList se llama a través de v-on="click: clearList(this)"

Los problemas con mi configuración actual es que el evento de cambio no se activa cuando las casillas de verificación se borran programáticamente (es decir, no por la interacción del usuario).

Lo que me gustaría en cambio
Para mí, lo más lógico sería usar this.$watch y realizar un seguimiento de los cambios en el modelo, en lugar de escuchar los eventos DOM.

Una vez que haya un cambio, necesitaría identificar qué elemento exacto cambió y actuar en consecuencia. Intenté crear una función $watch que observe la matriz de blocks . Esto parece captar bien los cambios, pero devuelve el objeto completo, a diferencia del atributo individual que ha cambiado. Además, este objeto carece de algunos atributos de ayuda útiles, como $parent .

Puedo pensar en algunas formas extravagantes para hacer que la aplicación funcione (como activar manualmente eventos de cambio en mi método clearList, etc.), pero mi caso de uso parece bastante estándar, por lo que espero que haya una forma mucho más elegante de manejar esto.


Como nadie respondió y ya resolví / resolví el problema, pensé que sería útil publicar mi solución. Tenga en cuenta que no estoy seguro de que mi solución sea cómo abordar este tipo de cosas, aunque funciona.

En lugar de usar este detector de eventos v-on="change: checkboxChange(this)" Ahora estoy usando una directiva personalizada que escucha los atributos del modelo seleccionado y deshabilitado, así: v-on-filter-change="selected, disabled" .

La directiva se ve así:

directives: { ''on-filter-change'': function(newVal, oldVal) { // When the input elements are first rendered, the on-filter-change directive is called as well, // but I only want stuff to happen when a user does someting, so I return when there is no valid old value if (typeof oldVal === ''undefined'') { return false; } // Do stuff here // this.vm is a handy attribute that contains some vue instance information as well as the current object // this.expression is another useful attribute with which you can assess which event has taken place } },

La cláusula if parece un poco hacky, pero no pude encontrar otra manera. Al menos todo funciona.

Quizás esto sea útil para alguien en el futuro.


Otra solución no mencionada aquí: use la opción deep .

watch:{ block: { handler: function () {console.log("changed") }, deep: true } }


Puede usar el método de "observación", por ejemplo, si sus datos son:

data: { block: { checkbox: { active:false }, someotherprop: { changeme: 0 } } }

Podrías hacer algo como esto:

data: {...}, watch: { ''block.checkbox.active'': function() { // checkbox active state has changed this.block.someotherprop.changeme = 5; } }


Si desea ver el objeto como un todo con todas sus propiedades, y no solo una propiedad, puede hacerlo en su lugar:

data() { return { object: { prop1: "a", prop2: "b", } } }, watch: { object: { handler(newVal, oldVal) { // do something with the object }, deep: true, }, },

handler aviso y deep: true