Как упростить и сбросить реквизиты с родительских на дочерние компоненты?
Я пытаюсь сбросить данные, передаваемые в качестве реквизитов дочерним компонентам. Как я должен написать это?
Контекст: я конвертирую реализацию ThreeJS в Vue/Typescript. Он включает в себя панель управления, состоящую из ползунковых входов, управляющих параметрами Три холста. Я разделил этот огромный монолитный исходный код на 3 компонента: - child1: controlsPanel, содержит ползунки и кнопку сброса - child2: холст Vue-GL, генерирующий события мыши - parent: компонент, содержащий исходные данные, и сброс.
родитель:
<template>
<div>
<child1 :prop1="prop1" :prop2="prop2" :child1Prop="child1Prop" :reset="reset" />
<child2 :prop1="prop1" :prop2="prop2" :child2Prop="child2Prop" />
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import Child1 from './components/Child1.vue';
import Child2 from './components/Child2.vue';
const initialState = {
prop1: 1,
prop2: 2,
child1Prop: 'some text',
child2Prop: 'another text',
}
export type InitialState = typeof initialState;
@Component({
components: {
Child1,
Child2,
},
})
export default class App extends Vue {
public prop1!: InitialState['prop1'];
public prop2!: InitialState['prop2'];
public child1Prop!: InitialState['child1Prop'];
public child2Prop!: InitialState['child2Prop'];
public beforeMount() {
Object.assign(this, initialState);
}
public reset() {
Object.assign(this, initialState);
}
}
</script>
Код ребенка:
<template>
...
<!-- this button is only in Child1 -->
<button type="button" @click="resetCamera">Reset</button>
</template>
<script lang="ts">
// import VueAsyncComputed, { IAsyncComputedProperty } from 'vue-async-computed';
import { Component, Prop, Vue } from 'vue-property-decorator';
import { InitialState } from '../App.vue';
@Component
export default class ChildX extends Vue {
@Prop() public prop1!: InitialState['prop1'];
@Prop() public prop2!: InitialState['prop2'];
@Prop() public childXProp!: InitialState['childXProp']; // Specific prop
// computed getters and methods using this.prop1 etc...
// this method is only in Child1
public resetCamera() {
this.reset();
}
}
</script>
Свойства prop1 и prop2 контролируются компонентом Child1 и используются Child2. Child2 также может обновить эти реквизиты (через события мыши), что должно соответствующим образом обновить ползунки в Child1.
Мне удалось сделать Typescript счастливым, но ценой набора текста везде...
Вопрос 1: есть ли способ упростить, сохраняя 2way-привязки между дочерним и родительским приложениями? (2way-привязки не работают с приведенным выше кодом)
Вопрос2: Как сбросить все реквизиты? Мой child1.resetCamera, кажется, вызывает parent reset(), но реквизиты не сбрасываются...
1 ответ
Когда вы используете props
Вы должны быть осторожны с точкой зрения такого рода данных: ее основная цель - просто передавать данные от родителя к потомку, то есть.
Как вы могли бы понять это позже, обычно это не очень хорошая идея, чтобы изменить props
как у родителя, так и у ребенка. Зачем? Рассмотрим следующий пример:
Родительский компонент называется mainComponent
проходит currentID
всем своим детям: headerComponent
а также footerComponent
, Тем не менее, если вы разработали свой props
должны быть изменены как родителями, так и детьми, если footerComponent
изменения currentID
это также меняется в headerComponent
чего нельзя ожидать Как насчет третьего дочернего компонента, добавляемого к вашему родительскому компоненту, который использует currentID
также? Это тоже будет затронуто.
Используя приведенный выше пример, я предлагаю: использовать props
только в одностороннем порядке. Другими словами, mainComponent
проходит currentID
всем своим детям. Если что-то из этого нужно изменить, props
, создать событие, используя $emit("updateCurrentID", newCurrentID)
и догонять это в mainComponent
и, наконец, изменить currentID
и это отразится на всех детях. Но теперь вы уверены, что обновляете это props
данные только в одном месте (mainComponent
).
Чтобы испустить это, я могу думать о двух возможностях: $emit
сам ( документы) или путем создания собственных пользовательских событий, как вы можете видеть здесь - учебник по MDN.
Надеюсь, поможет