vue.js - Genişletilmiş bileşenden Vue TypeScript türünde özellikler


Bizim bir temel Interactive bileşenimiz var, tasarım gereği diğer bileşenlerin bunu kullanması ve kendi dokunuşlarını eklemesi için temel olması amaçlanmıştır. Örneğin, Button bileşeni Interactive bileşenini bir temel olarak render eder ve işlevselliği genişletir, ayrıca stil ekler.

Bu nedenle, Interactive bileşeninin props tanımındaki tüm özellikler, üst Button üzerinde özellik olarak eklenmelidir.

Bunu daha önce şöyle uygulamıştık:

{
  props: {
    ...Interactive.props,
    aCustomProp: {/* ... */}
}

TypeScript'e dönüştürdüğümüz için, bu geçerli bir Vue değildir ve çalışıyor gibi görünse de kötü bir uygulama ve "geçici çözüm" gibiydi. Buradan alınan ders. Takımın kişisel tercihi olarak mixin kullanımından kaçınmak istiyoruz ve ideal olarak Interactive alt bileşenini kullanan her bileşende prop tanımını tekrarlamak istemiyoruz.

Bence extends: Interactive çözüm olabilir, ancak sonunda TypeScript tarafından props.disabled tahmin edilemeyecek bir duruma geliyoruz.

Esasen, bir bileşeni nasıl genişletebilirim ve TS'nin onun propslarını çıkarmasını nasıl sağlayabilirim?

Interactive.vue

export default defineComponent({
  props: {
    disabled: { type: Boolean, required: false, default: false },
    to: { type: String, required: false, default: null }
  }
});

Button.vue

import Interactive from './Interactive.vue';

export default defineComponent({
  props: {
    primary: { type: Boolean, required: false, default: false },
  },
  extends: Interactive,
  setup(props) {
    if (props.disabled) {
      // Do something
    }
  }
});

Yukarıdaki, Property 'disabled' does not exist on type 'Readonly<{ name: string; loading: boolean; } & {}>' hatasını veriyor

Cevap #1

Şu anda bunu keşfeden herkes için, sorun Vue3'te hâlâ devam ediyor. Bizim bunu aşma şeklimiz, ve bu hem Vue2 hem de Vue3 için işe yarıyor, bir tür sharedProps tanımı kullanmaktır.

Eğer Vue3 script setup kullanıyorsanız bu şöyle olur:

export interface SharedProps {
  prop1: string
}

// --

import type { SharedProps } from './path/to/props';

const props = defineProps<SharedProps & { prop2: number }>();

Eğer nesne sözdizimini kullanıyorsanız bu şekilde olur:

export const sharedProps = {
  prop1: { type: String, default: '', },
  // ...
}

// --

import { sharedProps } from './path/to/props';

export default defineComponent({
  props: {
    ...sharedProps,
    prop2: { type: number, default: 0 },
});

Maalesef, bildiğim kadarıyla, paylaşılmış özellikleri jenerik yerine bir parametre olarak defineProps()'a geçmediğiniz sürece, bunlar birbirinin yerine kullanılamaz.

Yine de, nesne tanımından türü çıkarmak için bir TS yardımcı programı oluşturmanın bir yolu olabilir.