如何简化道具并将其从父组件重置为子组件?

时间:2019-05-18 13:06:31

标签: typescript vue.js vuejs2 vue-class-components

我正在尝试重置作为道具传递给子组件的数据。我该怎么写?

上下文:我正在将ThreeJS实现转换为Vue / Typescript。它包括一个控制面板,该面板由用于控制“三个”画布的参数的滑块输入组成。 我将这个庞大的整体原始代码分为三个部分: -child1:controlsPanel,包含滑块和重置按钮 -child2:Vue-GL画布,发出鼠标事件 -父级:托管初始数据并进行重置的组件。

父母:

<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:在保持子代与父代App之间的2way绑定的同时,有没有一种方法可以简化? (2way绑定不适用于以上代码)

问题2:如何重置所有道具?我的child1.resetCamera似乎在调用父reset(),但是道具没有重置...

1 个答案:

答案 0 :(得分:0)

使用props时,请注意此类数据的要点:其主要目的只是将数据从父级传递到子级。

您可能会发现以后,通常更改父母props和孩子mainComponent并不是一个好主意。为什么?考虑以下示例:

名为currentID的父级组件将headerComponent传递给它的所有子级:footerComponentprops。但是,如果您将footerComponent设计为可以由父母和孩子共同更改,则如果currentID更改了headerComponent,则currentID也会更改,这是不可预期的。又如何将第三个子组件添加到使用props的父组件中呢?它也会受到影响。

使用上面的示例,我的建议是:仅在单向绑定中使用mainComponent。换句话说,currentIDprops传递给它的所有子节点。如果其中任何一个需要更改$emit("updateCurrentID", newCurrentID),请使用mainComponent发出一个事件并将其捕获到currentID中,最后更改props,这将反映在所有的孩子。但是现在,您确定只在一个位置(mainComponent)上更新此$emit数据。

为此,我可以想到两种可能性:import mysql.connector def loginsystem(): db = mysql.connector.connect(host="127.0.0.1", user="root", passwd="", db="dbpython") cursor = db.cursor() loop = 'true' while (loop == 'true'): username = str(input("Username : ")) password = str(input("Password : ")) if (cursor.execute("SELECT * FROM users WHERE username = %s AND password = %s"%(username,password))): print("Logged İn") else: print("Failure") db.commit() loginsystem() 本身(docs)或通过创建自己的自定义事件,如您所见here - a tutorial by MDN

希望有帮助