Vue:通过方法从父组件提交子组件形式的最佳方法 快速笔记更长的答案

问题描述

我有2个组成部分。

父项:

 Vue.component('parent',{
              template: '<div><child :counter="counter" :isSubmit="isSubmit" showButton="true"></child>'+
              '<button v-on:click="changeCounter">Change Counter</button></div>',data () {
                return {
                    counter: 2,isSubmit : false
                }
              },methods : {
                changeCounter () {
                    //retrieve value of counter dynamically let's say through ajax call.
                    this.counter = 9;
                    this.isSubmit = true;
                }
              }
            })

子组件:

Vue.component('child',{
          template: '<form action="test.PHP" method="GET" ref="childForm">'+
          '<input type="hidden" v-model="counter" name="counter" />'+
          '<input type="submit" v-if="showButton" /></form>',props: {
            counter : {
                type: Number,default: 0
            },showButton:false,isSubmit: false
          },watch : {
            isSubmit (val) {
                   console.log("Inside watcher");
                    this.submitForm();
            }
          },methods : {
            submitForm () {
                console.log(this.counter);// output-9
                this.$refs.childForm.submit();
            },}

        })

index.html

....
<div id="app>">
   <parent></parent>
   <parent></parent>
</div>
....

在此示例中,当我单击“更改计数器”按钮时,表单以较旧的计数器值提交(即提交给/test.PHP?counter=2)。尽管子组件的道具在开发工具中是响应式的(计数器= 9),但在提交表单时不会反映出来。但是,如果我通过子组件上的“提交”按钮提交表单(即提交到/test.PHP?counter=9),确实可以。

感谢您的帮助。请帮助我理解为什么会出现这种行为,并寻求解决方案。

谢谢。

解决方法

快速笔记

由于您使用的是GET请求,因此可以跳过整个<form>内容,而直接直接转到URL

methods: {
  changeCounter () {
    this.counter = 9
    window.location = `test.php?counter=${this.counter}`
  }
}

更长的答案

您需要等待counter更改以更新DOM才能使用常规表单提交。

要等待状态更改影响DOM,请使用$nextTick。我也建议通过submitForm方法提交表单,而不要看一个布尔值。您可以使用引用来访问该方法。

Vue.component('child',{
  template: `<form action="test.php" method="GET" ref="childForm">
    <input type="hidden" :value="counter" name="counter" />
    <input type="submit" v-if="showButton" />
  </form>`,props: {
    counter : {
      type: Number,default: 0
    },showButton: Boolean
  },methods: {
    async submitForm () {
      await this.$nextTick() // wait for the DOM to update
      this.$refs.childForm.submit()
    }
  }
})
Vue.component("parent",{
  template: `<div>
    <child :counter="counter" :show-button="true" ref="form"></child>
    <button @click="changeCounter">Change Counter</button>
  </div>`,data: () => ({ counter: 2 }),methods: {
    changeCounter () {
      this.counter = 9
      this.$refs.form.submitForm() // call the child component method
    }
  }
})