¿Por qué yo no puedo enlazar las propiedades del objeto en el Vue? El objeto addr es no reactiva de inmediato, pero test es reactivo, ¿cómo? En este caso, ¿cómo debo enlazar?

HTML

<div id="app">

   <input type="text" id="contactNum" v-model="addr.contactNum" name="contactNum">

   <input type="text" id="test" v-model="test" name="test">
   <br/>
   {{addr}}<br/>
   {{addr.contactNum}}<br/>
   {{test}}
</div>

Javascript

var vm = new Vue({
    el: '#app',
    data: {
      addr: {},
      test: ""
    }
});

Jsfiddle

  • Consulte el detección de cambio de advertencias sección de VueJS docs. Que se están ejecutando en este asunto porque addr es reactiva, pero addr.contactNum es no, ya que no es declarado cuando el componente está montado. No hay otra manera (debido a las limitaciones en JS sí mismo) que declarar explícitamente, ya sea cuando se inicializa el data objeto o el uso de Vue.set(). Aunque usted puede tener un número arbitrario de entradas, usted sabrá que la clave que se hace referencia en el addr objeto, así que usted puede utilizar que en Vue.set().
  • Una forma alternativa es en realidad para componer un genérico elemento de entrada, decir <my-input-component> con su propio v-model de asignación, y usted sólo tiene que incluir en su aplicación como un componente. Estos componentes pueden emitir los valores actualizados a los padres de la aplicación (en este caso), por lo que los padres siempre tienen los valores actualizados de todas las entradas en sí mismo.
  • por cierto, en mi entorno que funciona bien. he copiado el código para el proyecto generado por vue-cli. también estoy usando vue 2.5.2
InformationsquelleAutor GMsoF | 2017-10-25

3 Comentarios

  1. 11

    Durante la inicialización Vue establece los métodos getter y setter para cada propiedad. Desde contactNum no está inicialmente, Vue no sabe acerca de que la propiedad y no se puede actualizar correctamente. Esto puede ser fácil fija mediante la adición de contactNum a su addr objeto.

    var vm = new Vue({
      el: '#app',
      data: {
        addr: {
          contactNum: "" //<-- this one
        },
        test: ""
      }
    });

    El de arriba se llama reactividad en Vue. Desde Vue no admite la adición de propiedades dinámicamente a su reactividad del sistema, se puede necesitar algún tipo de solución. Una posible solución es proporcionada por la API. En caso de agregar dinámicamente las propiedades que podemos utilizar Vue.set(vm.someObject, 'b', 2).

    Hacerlo el marcado que se necesita para obtener alguna actualización. En lugar de utilizar v-model mejor sería utilizar un detector de eventos como @input. En este caso nuestro marcado este aspecto.

    <input type="text" id="contactNum" @input="update(addr, 'contactNum', $event)" name="contactNum">

    Así que, básicamente, la función de activar cada vez que los elementos de entrada se cambia el valor. Obviamente hacerlo también requerirá algunos ajustes en el JS parte.

    var vm = new Vue({
      el: '#app',
      data: {
        addr: {},
        test: ""
      },
      methods: {
        update: function(obj, prop, event) {
          Vue.set(obj, prop, event.target.value);
        }
      }
    });

    Desde Vue desencadena Vue.set() en cualquier reactivo elemento, simplemente llamamos a nosotros mismos porque Vue no reconoce una dinámica añadido a la propiedad como un reactivo. Por supuesto, esta es sólo una de las posibles soluciones, y pueden haber muchas otras soluciones. Un completo ejemplo de trabajo puede ser visto aquí.

    • oh no, tengo una mejor manera? Tengo un lote de propiedad de la addr objeto, no quiero inicializar ellos uno por uno.
    • Puede asignar addr sí mismo con objeto nuevo y va a ser la instalación correctamente.
    • ¿Qué significa asignar un nuevo objeto? Objeto vacío?
  2. 4

    Como por mis comentarios, hay varias cosas que usted desea considerar:

    • La razón por la que el código no funciona es debido a la imposibilidad inherente de JS para observar los cambios en las propiedades del objeto. Esto significa que aunque addr es reactivo, las propiedades añadido a addr que no se hace cuando se la declara hará que sea no reactivo. Consulte la VueJS docs para más detalles: https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
    • Si usted va a tener un número arbitrario de los campos de entrada, usted es probablemente mejor de componer una costumbre de entrada de componente, y simplemente utilizar v-for iterativa inyectar campos de entrada basado en el número de campos de entrada que tiene.

    Ahora al segundo punto, si usted sabe qué campos addr tendrá, usted puede simplemente declarar en su aplicación. Vamos a crear una nueva updateFormData método, el cual es llamado por el componente:

    data: {
      addrFields: ['contactNum', ...],
      addr: {},
      test: ""
    },
    methods: {
      updateFormData: function(id, value) {
        this.$set(this.addr, id, value);
      }
    }

    Todavía podemos almacenar los datos de su formulario en el addr objeto, el cual será actualizado por la updateFormData método basado en el recibido de carga utilizando .$set(). Ahora, podemos crear un custom Vue componente de su elemento de entrada.

    En el ejemplo de abajo, el componente que se va a iterar a través de todos sus addrFields, y transmitir la addrField como una proposición mediante :id="addrField". También queremos asegurarnos de capturar el denominado personalizado updated evento emitida desde dentro del componente.

    <my-input
         v-for="(addrField, i) in addrFields"
         :key="i"
         :id="addrField"
         v-on:inputUpdated="updateFormData"></my-input>

    La plantilla puede ser algo como lo siguiente. Simplemente utiliza el id la proposición, tanto por su id, name, y placeholder atributo (el último, para facilitar la identificación en la demo). Nos unen la @change y @input eventos, lo que obligó a activar la updated de devolución de llamada:

    <script type="text/template" id="my-input">
        <input
        type="text"
        :id="id"
        :name="id"
        :placeholder="id"
        @input="updated"
        @change="updated">
    </script>

    En el componente de la lógica, saber que va a recibir id como un apoyo, y que se debería emitir un inputUpdated evento utilizando $.emit(). Se adjunta el ID y el valor de las cargas, por lo que podemos informar a los padres de familia, que se ha actualizado:

    var myInput = Vue.component('my-input', {
        template: '#my-input',
      props: {
        id: {
            type: String
        }
      },
      methods: {
        updated: function() {
            this.$emit('inputUpdated', this.id, this.$el.value);
        }
      }
    });

    Con el código de arriba, tenemos un ejemplo de trabajo. En este caso, he creado una arbirary matriz de campos de entrada: contactNum, a, b, y c:

    JS:

    var myInput = Vue.component('my-input', {
    	template: '#my-input',
      props: {
      	id: {
        	type: String
        }
      },
      methods: {
      	updated: function() {
        	this.$emit('updated', this.id, this.$el.value);
        }
      }
    });
    
    var vm = new Vue({
        el: '#app',
        data: {
          addrFields: ['contactNum', 'a', 'b', 'c'],
          addr: {},
          test: ""
        },
        methods: {
        	updateFormData: function(id, value) {
          	this.$set(this.addr, id, value);
          }
        }
    });

    HTML:

    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
    <div id="app">
       
       <my-input
         v-for="(addrField, i) in addrFields"
         :key="i"
         :id="addrField"
         v-on:updated="updateFormData"></my-input>
       
       <input type="text" id="test" v-model="test" name="test" placeholder="test">
       <br/>
       <strong>addr:</strong> {{addr}}<br/>
       <strong>addr.contactNum:</strong> {{addr.contactNum}}<br />
       <strong>test:</strong> {{test}}
    </div>
    
    <script type="text/template" id="my-input">
    	<input
      	type="text"
        :id="id"
        :name="id"
        :placeholder="id"
        @input="updated"
        @change="updated">
    </script>

  3. 0

    Editar su Vue data con esto ya que los métodos getter y setter no están configurados. Además, echa un vistazo Declarativa Reactivo de Representación en Vue docs aquí:

    data: {
        addr: {
          contactNum: "" //<-- this one
        },
        test: ""
      }
    • consiguió la mejor manera? Tengo gran cantidad de propiedades, prefieren no inicializar uno por uno.
    • Sí, usted puede establecer Vue con las propiedades de la Vue.establecer fuera de vue alcance.

Dejar respuesta

Please enter your comment!
Please enter your name here