首页 > 解决方案 > 如何正确继承 Typescript 中的父组件?

问题描述

我正在将 Vue v2 与 Typescript 一起使用,并且正在尝试扩展父类:

我的父类被调用BaseSelect,看起来像这样:

<template>
  <select :value="value" @change="$emit('change', $event.target.value)">
    <option value="">default option</option>
    <slot />
  </select>
</template>

<script lang="ts">
import { Component, Model, Vue } from 'vue-property-decorator';

@Component({})
export default class BaseSelect extends Vue {
  @Model('change', { type: String, required: false, default: '' })
  private readonly value!: string

  private valid = true;

  validate(): boolean {
    this.valid = !!this.value;
    return this.valid;
  }
}
</script>

我的孩子班BaseSelectGender看起来像这样:

<template>
  <base-select :value="value" @change="$emit('change', $event)">
    <option value="male">I'm male</option>
    <option value="female">I'm female</option>
  </base-select>
</template>

<script lang="ts">
import { Component } from 'vue-property-decorator';
import { BaseSelect } from '@/components/base';

@Component({
  components: { BaseSelect }
})
export default class BaseSelectGender extends BaseSelect {}
</script>

当我<base-select-gender>在我的代码中使用时,有两个BaseSelect组件实例(因此有两个不同的valid变量实例):

  1. 由于继承而创建的第一个实例
  2. 由于<base-select>在孩子中使用而创建的第二个实例

当变量发生变化时,这会导致一些问题,valid因为变量的错误实例反映在 DOM 中。

所以我现在的问题是:我如何扩展一个基类并使用它,或者至少在我的子组件的模板部分扩展 html 代码?

标签: typescriptvuejs2vue-class-components

解决方案


解决方法

所以我找到了一种解决方法,我使用该ref属性来访问“内部”组件(本template节中的那个)的属性和方法。

这允许我手动同步我需要的所有属性(确保所需的属性没有private修饰符)。

我的BaseSelectGender组件现在看起来像这样:

<template>
  <base-select 
    :value="value" 
    @change="$emit('change', $event)"
    v-bind="{ ...$attrs, ...$props }"
    ref="inner"
  >
    <option value="male">I'm male</option>
    <option value="female">I'm female</option>
  </base-select>
</template>

<script lang="ts">
import { Component } from 'vue-property-decorator';
import { BaseSelect } from '@/components/base';

@Component({
  components: { BaseSelect }
})
export default class BaseSelectGender extends BaseSelect {
  get inner() {
    return this.$refs.inner as BaseSelect;
  }

  setValid(valid: boolean) {
    this.valid = valid;
    this.inner.setValid(valid);
  }

  validate(): boolean {
    this.valid = this.inner.validate();
    return this.valid;
  }
}
</script>

专业提示:用于v-bind="{ ...$attrs, ...$props }"将所有属性和道具从外部组件传递到内部组件。


推荐阅读