Как упростить и сбросить реквизиты с родительских на дочерние компоненты? - PullRequest
1 голос
/ 18 мая 2019

Я пытаюсь сбросить данные, передаваемые в качестве реквизитов дочерним компонентам.Как мне написать это?

Контекст: я конвертирую реализацию ThreeJS в Vue / Typescript.Он включает в себя панель управления, состоящую из ползунковых входов, управляющих параметрами Три холста.Я разделил этот огромный монолитный исходный код на 3 компонента: - child1: controlsPanel, содержит ползунки и кнопку сброса - child2: холст Vue-GL, генерирующий события мыши - parent: компонент, содержащий исходные данные, и сброс.

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 Ответ

0 голосов
/ 18 мая 2019

Когда вы используете props, вы должны быть осторожны с точкой зрения такого рода данных: ее основная цель - просто передать данные от родителя к ребенку, то есть.

Как вы можете понять позже, обычно не стоит менять props как в родительском, так и в дочернем элементах. Зачем? Рассмотрим следующий пример:

Родительский компонент с именем mainComponent передает currentID всем своим дочерним элементам: headerComponent и footerComponent. Тем не менее, если вы запланировали изменение props как для родителей, так и для детей, если footerComponent изменит currentID, то также изменится в headerComponent, что может и не ожидаться. Как насчет третьего дочернего компонента, добавляемого к вашему родительскому компоненту, который также использует currentID? Это тоже будет затронуто.

Используя приведенный выше пример, я предлагаю: используйте props только в одностороннем связывании. Другими словами, mainComponent передает currentID всем своим детям. Если что-то из этого нужно изменить, props, сгенерируйте событие, используя $emit("updateCurrentID", newCurrentID), перехватите его в mainComponent и, наконец, измените currentID, и это отразится на всех дочерних элементах. Но теперь вы уверены, что обновляете эти props данные только в одном месте (mainComponent).

Чтобы испустить это, я могу думать о двух возможностях: $emit сам ( документы ) или создавая свои собственные события, как вы можете видеть здесь - учебник по MDN .

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...