Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

139
Visualizações
Vue Watcher not working on component created with Vue.extend

I have a Parent component with a select input which is bound through v-model to a variable in data.

Besides, I create child components dynamically using Vue.extend, which i pass the propsData which also includes the value of the select.

This components have a watcher for the prop that is related to the select input.

When i create the component it receives the props succesfully, The problem comes when I update the value of the select input that doesn't trigger the watcher on the child component.

I've been looking for similar situations but have not found something that helps me solve this problem, i don't know why it doesn't trigger the watcher on the child component when the select input changes.

Any help would be very preciated.

Here i create the component dynamically:

let PresupuestoFormularioVue = Vue.extend(PresupuestoFormulario)
let instance = new PresupuestoFormularioVue({
  propsData: {
    //The prop related to select input  
    seguro: this.seguro,
  }
})
instance.$mount()
this.$refs.formularioContenedor.appendChild(instance.$el)

And this is the watcher in the component which isn't working:

watch:{
  seguro:{
    handler: function( newVal ){
      console.log(newVal)
    },
  },
},
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

It's not the watch that doesn't work. It's the bindings. You're assigning the current value of this.seguro, not the reactive object itself. However, a new Vue() can add this binding for you.

As a sidenote, whether PresupuestoFormulario is a Vue.extend() doesn't matter. It can be any valid VueConstructor: a Vue.extend(), Vue.component() or a valid SFC (with name and template): export default {...}.

Here's how to do it:

methods: {
  addPresupuestoFormulario() {
    const div = document.createElement('div');
    this.$el.appendChild(div);
    new Vue({
      components: { PresupuestoFormulario },
      render: h => h("presupuesto-formulario", {
        props: {
          seguro: this.seguro
        }
      }) 
    }).$mount(div)
  }
}

The <div> initially appended to the parent will get replaced upon mounting with the actual template of PresupuestoFormulario and the bindings will be set, exactly as if you had <presupuesto-formulario :seguro="seguro" /> in the parent template from the start.

The really cool part about it is that the parent component doesn't need to have PresupuestoFormulario declared in its components.

Here's a working example:

const Test = Vue.component('test', {
  template: `<div>message: {{message}}</div>`,
  props: ['message'],
  watch: {
    message: console.log
  }
})

new Vue({
  el: '#app',
  data: () => ({
    msg: "¯\\_(ツ)_/¯"
  }),
  methods: {
    addComponent() {
      const div = document.createElement("div");
      this.$el.appendChild(div);
      new Vue({
        components: {
          Test
        },
        render: h => h("test", {
          props: {
            message: this.msg
          }
        })
      }).$mount(div);
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<div id="app">
  <input v-model="msg">
  <button @click="addComponent">Add dynamic child</button>
</div>


A separate note, about using this.$el.appendChild(). While this works when you're using a root Vue instance (a so-called Vue app), it will likely fail when using a normal Vue component, as Vue2 components are limited to having only 1 root element.
It's probably a good idea to have an empty container (e.g: <div ref="container" />) in the parent, and use this.$refs.container.appendChild() instead.

about 4 years ago · Juan Pablo Isaza Relatório

0

All of props that you want check in watcher, should be a function. If you want read more about this go to vue document codegrepper.

watch: {
    // whenever seguro changes, this function will run
    seguro: function (newValue, oldValue) {
        console.log(newValue,oldValue)
    }
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda