Ву.js передает данные из слота в экземпляр компонента
Я пытаюсь создать многоразовый компонент для работы с отправкой форм через AJAX с помощью Vue.JS. В идеале, то , что я хочу сделать, - это иметь общий компонент, который может использоваться вместо form
, в котором может содержаться неизвестный набор элементов формы, таких как input
, select
, textarea
и т. д.
У меня есть следующий код для моего компонента, который называется ajax-form
:
<template>
<form class="form" :action="action" :method="method" v-on:submit.prevent="ajaxSubmit">
<slot></slot>
</form>
</template>
<script>
module.exports = {
props: {
action: {
required: true,
type: String
},
method: {
default: 'post',
required: false,
type: String
}
},
data() {
return {
formData: {}
}
},
methods: {
ajaxSubmit() {
// Do ajax
}
}
}
</script>
И в моем HTML, у меня было бы что-то вроде следующего:
<ajax-form action="http://example.com/do/something">
<input name="first_name" type="text">
<textarea name="about_you"></textarea>
</ajax-form>
В идеале я хотел бы, чтобы все элементы формы, размещенные внутри моего компонента, использовали его слот для сопоставления с data.formData
свойство formData в моем экземпляре компонента Vue. Поэтому в этом случае свойство data
будет выглядеть следующим образом:
data: {
formData: {
first_name: '',
about: ''
}
}
Если бы я должен был добавить другое поле к компоненту в моем HTML, я ожидал бы, что это также будет сопоставлено data
.
Есть ли способ добиться этого? Есть ли способ, которым я могу сказать Vue, помещая мои элементы формы в компонент через слот, что я хочу, чтобы этот элемент был сопоставлен с чем-то в data
?
Я попытался добавить v-model
и v-bind
на каждый элемент формы, чтобы увидеть, будет ли он каким-то образом передавать данные в данные компонента:
<ajax-form action="http://example.com/do/something">
<input name="first_name" type="text" v-model="formData.first_name">
</ajax-form>
Однако Vue жалуется, что свойства реактивных данных должны быть объявлены до их использования в шаблоне:
[Vue warn]: свойство или метод "formData" не определены в экземпляре, но ссылаются во время визуализации. Обязательно объявите свойства реактивных данных в параметре data.



Ответы - Ву.js передает данные из слота в экземпляр компонента / Vue.js pass data from slot into component instance

23.02.2017 06:31:33
Вы не можете сделать то, что вы просите, поскольку область слотов ограничена родительской областью.
Вы можете определить formData на глобальном экземпляре Vue, так что теперь он доступен из родительской области.
const app = new Vue({
el: '#app',
data: {
formData : {}
}
});
Теперь вы можете передать его в форму в качестве опоры:
<ajax-form action="#" :form-data="formData>
<input name="first_name" type="text" v-model="formData.first_name">
</ajax-form>


21.04.2017 03:46:57
Вы можете сделать это с помощью scopedSlots.
Api выглядит так:
<ajax-form action="http://example.com/do/something">
<template scope="{formData}">
<input name="first_name" type="text" v-model="formData.first_name">
</template>
</ajax-form>
И в компоненте ajax-form
:
<form class="form" :action="action" :method="method" v-on:submit.prevent="ajaxSubmit">
<slot :formData="formData">
</form>


scope
, который можно использовать для любого элемента, а не только slot-scope
. Так что в этом примере вы могли бы иметь template
вместо упаковки входных данных в тег шаблона.



18.09.2019 02:20:43
Вы можете передать данные от родителя к ребенку в качестве параметра следующим образом:
у родителей:
<child-component ref="child">
<h1 slot="heading">Test passing data to child</h1>
<form slot="content">
<input type="text" v-model="name" placeholder="Type your name" class="half">
<input type="text" v-model="email" placeholder="Type your email" class="half">
<div class="actions">
<button data-role="submit" @click.prevent="callAddRep($event)">Add</button>
</div>
</form>
</child-component>
data() {
return {
name: '',
email: ''
}
},
methods: {
callAddRep: function(e) {
let name = this.name,
email = this.email
this.$refs.child.addRep(e, {
name,
email
})
}
в ребенке:
methods: {
addRep: function(e, data) {
//Data passed successfully
console.log(data)
}
}