Я борюсь с правильным решением, которое требует расширенного общения между родителями и детьми в vuejs. Может быть много разных родительских компонентов, у которых есть логика c как сохранять данные. С другой стороны, будет только один дочерний компонент, у которого есть список элементов и форма для создания новых элементов, но он не знает, как сохранить данные.
Вопрос : Есть ли другой способ (лучший подход), чтобы иметь такую же функциональность, кроме как избавиться от this.$refs.child
ссылок. Например, мне интересно, могу ли я просто передать функцию (SaveParent1(...)
или SaveParent2(...)
) дочернему компоненту. Но проблема в том, что функция содержит некоторые родительские переменные, которые не будут доступны в дочернем контексте, и эти переменные могут быть изменены во время выполнения.
Несколько пояснений:
- Методы
SaveParent1
и SaveParent2
в реальной жизни возвращают Promise (топор ios). child-component
похож на CRUD, который используется повсюду.
На данный момент сообщение выглядит так: РЕБЕНОК -event->
РОДИТЕЛЬ -ref->
РЕБЕНОК *
Ниже приведен пример сильфона:
<div id="app">
<h2>😀Advanced Parent-Child Communication:</h2>
<parent-component1 param1="ABC"></parent-component1>
<parent-component2 param2="XYZ"></parent-component2>
</div>
Vue.component('parent-component1', {
props: { param1: { type: String, required: true } },
methods: {
onChildSubmit(p) {
// Here will be some logic to save the param. Many different parents might have different logic and all of them use the same child component. So child-component contains list, form and validation message but does not know how to save the param to the database.
var error = SaveParent1({ form: { p: p, param1: this.param1 } });
if (error)
this.$refs.child.paramFailed(error);
else
this.$refs.child.paramAdded(p);
}
},
template: `<div class="parent"><p>Here is parent ONE:</p><child-component ref="child" @submit="onChildSubmit"></child-component></div>`
});
Vue.component('parent-component2', {
props: { param2: { type: String, required: true } },
methods: {
onChildSubmit(p) {
// Here is a different logic to save the param. In prictice it is gonna be different requests to the server.
var error = SaveParent2({ form: { p: p, param2: this.param2 } });
if (error)
this.$refs.child.paramFailed(error);
else
this.$refs.child.paramAdded(p);
}
},
template: `<div class="parent"><p>Here is parent TWO:</p><child-component ref="child" @submit="onChildSubmit"></child-component></div>`
});
Vue.component('child-component', {
data() {
return {
currentParam: "",
allParams: [],
errorMessage: ""
}
},
methods: {
submit() {
this.errorMessage = "";
this.$emit('submit', this.currentParam);
},
paramAdded(p) {
this.currentParam = "";
this.allParams.push(p);
},
paramFailed(msg) {
this.errorMessage = msg;
}
},
template: `<div><ol><li v-for="p in allParams">{{p}}</li></ol><label>Add Param: <input v-model="currentParam"></label><button @click="submit" :disabled="!currentParam">Submit</button><p class="error">{{errorMessage}}</p></div>`
});
function SaveParent1(data) {
// Axios API to save data. Bellow is a simulation.
if (Math.random() > 0.5)
return null;
else
return 'Parent1: You are not lucky today';
}
function SaveParent2(data) {
// Axios API to save data. Bellow is a simulation.
if (Math.random() > 0.5)
return null;
else
return 'Parent2: You are not lucky today';
}
new Vue({
el: "#app"
});
Также доступна живая демонстрация: https://jsfiddle.net/FairKing/novdmcxp/