如何正确继承Typescript中的父组件?

如何正确继承Typescript中的父组件?,typescript,vuejs2,vue-class-components,Typescript,Vuejs2,Vue Class Components,我将Vue v2与Typescript一起使用,并尝试扩展父类: 我的父类称为BaseSelect,如下所示: <template> <select :value="value" @change="$emit('change', $event.target.value)"> <option value="">default option</option> <slo

我将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>
<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>
<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>
当我在代码中使用
时,有两个
BaseSelect
组件的实例(因此有两个不同的
valid
变量实例):

  • 由于继承而创建的第一个实例
  • 第二个实例是由于在子对象中使用
    而创建的
  • valid
    变量更改时,这会导致一些问题,因为DOM中反映了错误的变量实例

    因此,我现在的问题是:如何扩展基类并同时使用它,或者至少扩展子组件模板部分中的html代码?

    解决方法 因此,我找到了一个解决方法,使用
    ref
    属性访问“内部”组件(在
    模板
    部分中)的属性和方法

    这允许我手动同步我需要的所有属性(确保这些属性不是私有的)

    我的
    BaseSelectGender
    组件现在如下所示:

    <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>
    
    <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>
    
    <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>
    
    
    我是男性
    我是女性
    从“vue属性装饰器”导入{Component};
    从“@/components/base”导入{BaseSelect};
    @组成部分({
    组件:{BaseSelect}
    })
    导出默认类BaseSelect扩展BaseSelect{
    获取内部(){
    将此.$refs.inner作为BaseSelect返回;
    }
    setValid(有效值:布尔值){
    this.valid=有效;
    this.inner.setValid(有效);
    }
    validate():布尔值{
    this.valid=this.internal.validate();
    返回此文件。有效;
    }
    }
    

    Pro提示:使用
    v-bind=“{…$attrs,$props}”
    将所有属性和道具从外部组件传递到内部组件。

    你找到答案了吗?:)@伯恩:是的,但这只是一个解决办法。我将在下面添加它作为一个答案。