如何正确继承 Typescript 中的 parent 组件?
How to correctly inherit from a parent component in Typescript?
我正在使用带有 Typescript 的 Vue v2,我正在尝试扩展 parent class:
我的 parent class 叫做 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>
我的childclassBaseSelectGender
看起来像这样:
<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
变量有两个不同的实例):
- 第一个因继承而创建的实例
- 由于在child
中使用<base-select>
而创建的第二个实例
这会在 valid
变量更改时导致一些问题,因为变量的错误实例反映在 DOM。
所以我现在的问题是:如何扩展基础 class 并使用它或至少扩展 child 组件模板部分中的 html 代码?
解决方法
所以我找到了一个解决方法,我使用 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 }"
将所有属性和道具从外部组件传递到内部组件。
我正在使用带有 Typescript 的 Vue v2,我正在尝试扩展 parent class:
我的 parent class 叫做 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>
我的childclassBaseSelectGender
看起来像这样:
<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
变量有两个不同的实例):
- 第一个因继承而创建的实例
- 由于在child 中使用
<base-select>
而创建的第二个实例
这会在 valid
变量更改时导致一些问题,因为变量的错误实例反映在 DOM。
所以我现在的问题是:如何扩展基础 class 并使用它或至少扩展 child 组件模板部分中的 html 代码?
解决方法
所以我找到了一个解决方法,我使用 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 }"
将所有属性和道具从外部组件传递到内部组件。