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). Хотя свойства дочернего компонента являются реактивными в инструментах разработки (counter = 9), они не отражаются при отправке формы. Но это действительно работает, если я отправляю форму с помощью кнопки отправки в дочернем компоненте (т.е. отправляю в /test.php?counter=9).
Ваша помощь очень ценится. Пожалуйста, помогите мне понять, почему проявляется такое поведение, а также поиск решений.
Заранее спасибо.
1 ответ
Быстрая заметка
Поскольку вы используете запросы 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
}
}
})