当返回父组件时,Vue动态组件上的数据丢失

时间:2019-01-25 14:23:21

标签: vue.js vuejs2 vue-component vue-dynamic-components

我正在使用Vue-form-wizard创建多步骤表单。在其中一个步骤中,我正在加载动态组件,然后使用v-bind和prop将数据传递给动态组件。当我们使用动态组件时,数据会完美地更新,但是当我进行下一步时,所有丢失的更改都将保留在父组件的默认值上!我试过了,但是什么也没做。这是发生的情况的示例: html:

<div id="app">
<div>
  <form-wizard @on-complete="onComplete">
    <tab-content v-for="tab in tabs"
                v-if="!tab.hide"
                :key="tab.title"
                :title="tab.title"
                :icon="tab.icon">
      <component :is="tab.component" v-bind={'form':form}></component>
    </tab-content>
  </form-wizard>
 </div>
</div>

和js将是:

Vue.use(VueFormWizard)
Vue.component('step1', {
 template:` <div> My first tab content <br>
             </div>`,
 props:['form'],
 created(){
            this.form = 'that other form'; 
      alert(this.form);
 }
 }
)
Vue.component('step2', {
 template:`<div>  My second tab content </div>`
})
Vue.component('step3', {
 template:`<div>  My third tab content </div>`
})
Vue.component('step4', {
template:`<div> Yuhuuu! This seems pretty damn simple </div>`
})
new Vue({
 el: '#app',
 data() {
    return {
  form:'this form',
    tabs: [{title: 'Personal details', icon: 'ti-user', component: 'step1'}, 
    {title: 'Is Logged In?', icon: 'ti-settings', component: 'step2', hide: false}, 
    {title: 'Additional Info', icon: 'ti-location-pin', component: 'step3'},
    {title: 'Last step', icon: 'ti-check', component: 'step4'},
    ],
  }
 },
 methods: {
  onComplete: function(){
      alert(this.form);
   }
  }
})

请帮助我。 非常感谢

1 个答案:

答案 0 :(得分:1)

这里:

 props:['form'],
 created(){
      this.form = 'that other form'; 
      alert(this.form);
 }

您正在更改道具。 Don't do that

  

所有道具在子属性和子属性之间形成单向绑定   父项:父项属性更新时,它将向下流动到   这个孩子,但并非相反。这样可以防止孩子   意外地改变了父母的状态,   使您的应用程序的数据流更难理解。

相反,子级应该发出一个事件,父级将对其进行操作以更新数据项。我喜欢在孩子中创建一个计算机来包装该行为,以便将其视为可以分配给变量的变量。

在下面的代码段中,我使用.sync modifier使更新干净。设置该值以赋予事件处理时间后,我还会调用$nextTick

Vue.use(VueFormWizard)
Vue.component('step1', {
  template: ` <div> My first tab content <br>
             </div>`,
  props: ['form'],
  computed: {
    proxyForm: {
      get() {
        return this.form;
      },
      set(v) {
        this.$emit('update:form', v);
      }
    }
  },
  created() {
    this.proxyForm = 'that other form';
    this.$nextTick(() =>
      alert(this.proxyForm));
  }
})
Vue.component('step2', {
  template: `<div>  My second tab content </div>`
})
Vue.component('step3', {
  template: `<div>  My third tab content </div>`
})
Vue.component('step4', {
  template: `<div> Yuhuuu! This seems pretty damn simple </div>`
})
new Vue({
  el: '#app',
  data() {
    return {
      form: 'this form',
      tabs: [{
          title: 'Personal details',
          icon: 'ti-user',
          component: 'step1'
        },
        {
          title: 'Is Logged In?',
          icon: 'ti-settings',
          component: 'step2',
          hide: false
        },
        {
          title: 'Additional Info',
          icon: 'ti-location-pin',
          component: 'step3'
        },
        {
          title: 'Last step',
          icon: 'ti-check',
          component: 'step4'
        },
      ],
    }
  },
  methods: {
    onComplete: function() {
      alert(this.form);
    }
  }
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-form-wizard@0.8.4/dist/vue-form-wizard.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/vue-form-wizard@0.8.4/dist/vue-form-wizard.min.css" rel="stylesheet" />
<div id="app">
  <div>
    <form-wizard @on-complete="onComplete">
      <tab-content v-for="tab in tabs" v-if="!tab.hide" :key="tab.title" :title="tab.title" :icon="tab.icon">
        <component :is="tab.component" :form.sync="form"></component>
      </tab-content>
    </form-wizard>
  </div>
</div>