Vue:通过方法从父组件提交子组件表单的最佳方式

Posted

技术标签:

【中文标题】Vue:通过方法从父组件提交子组件表单的最佳方式【英文标题】:Vue: Best way to submit form of child component from the parent component through method 【发布时间】:2020-12-20 05:02:33 【问题描述】:

我有 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),它确实有效。

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

提前致谢。

【问题讨论】:

如果提交信号来自父组件,为什么你的子组件有提交按钮? 【参考方案1】:

速记

由于您使用的是 GET 请求,因此您可以跳过整个 &lt;form&gt; 内容,直接转到 URL

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


更长的答案

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

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

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
    
  
)

【讨论】:

我知道submitForm() 不是方法 @Phil 没有看到您的代码,除了确保您正确使用ref 之外,我无法提供任何建议。仅供参考,如果您在 v-for 循环中分配 ref="form" 属性,请记住 this.$refs.form 将是一个数组。见vuejs.org/v2/guide/…

以上是关于Vue:通过方法从父组件提交子组件表单的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

使用 Vue js 发布具有多个组件的表单的最佳方式是啥

在Vue.js中从父组件执行子方法

如何使用Vue从父级中的多个子组件中获取值?

从父组件vue访问第三方子组件

如何在 Vue JS 中将更新的值从父组件发送到子组件?

将默认数据传递给 Vue 表单组件