>  기사  >  웹 프론트엔드  >  vue3에서 ref 인스턴스를 ts InstanceType과 결합하는 문제를 해결하는 방법

vue3에서 ref 인스턴스를 ts InstanceType과 결합하는 문제를 해결하는 방법

WBOY
WBOY앞으로
2023-05-20 22:59:321692검색

    vue3은 ts의 InstanceType과 결합된 ref 인스턴스를 얻습니다.

    때때로 템플릿 참조를 사용하는 경우 ts 프롬프트가 작동하지 않습니다. 별로 영향을 미치지는 않지만 해결될 수 있습니다~

    <!-- MyModal.vue -->
    <script setup lang="ts">
    import { ref } from &#39;vue&#39;
    
    const sayHello = () => (console.log(&#39;我会说hello&#39;))
    
    defineExpose({
      sayHello
    })
    </script>

    그런 다음 상위 수준에서 사용합니다. MyModalRef.value를 입력하면 sayHello 함수 프롬프트가 없다는 것을 알 수 있으므로 이번에는 인스턴스 유형을 가져오려면 InstanceType 도구 유형을 사용해야 합니다

    <!-- App.vue -->
    <script setup lang="ts">
    import MyModal from &#39;./MyModal.vue&#39;
    const MyModalRef = ref()
    
    const handleOperation = () => {
      MyModalRef.value.sayHello
    }
    </script>

    vue3에서 ref 인스턴스를 ts InstanceType과 결합하는 문제를 해결하는 방법

    InstanceType 도구 유형을 사용하여 인스턴스 유형을 가져옵니다.

    <!-- MyModal.vue -->
    <script setup lang="ts">
    import { ref } from &#39;vue&#39;
    
    const sayHello = () => (console.log(&#39;我会说hello&#39;))
    
    defineExpose({
      open
    })
    </script>

    Parent use

    <!-- App.vue -->
    <script setup lang="ts">
    import MyModal from &#39;./MyModal.vue&#39;
    
    const MyModalRef = ref<InstanceType<typeof MyModal> | null>(null)
    
    const handleOperation = () => {
      MyModalRef.value?.sayHello()
    }
    </script>

    메시지가 표시될 때 InstanceType을 사용하라는 메시지가 아직 없는 것 같습니다. , 그리고 나서 오류 내용을 입력하면 컴파일 전에는 오류가 보고되지 않습니다... 그런데 Vue 공식이 이렇게 말하더군요. 그러면 들어보세요(사실 저는 평소에 잘 사용하지 않지만 배웠습니다)

    @vue 공식 API 구성 요소 템플릿 참조 유형에 주석 달기

    vue3 구성 요소에 대한 TS 유형에 주석을 추가하는 방법

    Vue3과 TS는 확실히 올해 가장 인기 있는 것들입니다. 프런트 엔드 기술 목록에 오신 것을 환영합니다. 많은 회사에서 Vue3 + TS + Vite 조합을 사용하여 새로운 프로젝트를 개발하고 있습니다. 다음은 다시 작성한 문장입니다. Vue3 컴포넌트에서 TS 유형과 결합된 Composition-Api를 사용하는 방법을 공유합니다.

    props에 대한 유형에 주석 달기

    <script setup lang="ts">
    const props = defineProps({
      foo: { type: String, required: true },
      bar: Number
    })
     
    props.foo // string
    props.bar // number / undefined
    </script>

    이를 런타임 선언이라고 합니다. DefineProps()에 전달된 값은 런타임 소품 옵션으로 사용됩니다.

    두 번째 방법은 일반 매개변수를 통해 props 유형을 정의하는 것입니다. 이는 보다 직접적인 방법입니다.

    <script setup lang="ts">
    const props = defineProps<{
      foo: string
      bar?: number
    }>()
    </script>
     
    /* or
    <sctipt setup lang="ts">
    interface Props {
      foo: string
      bar?: number
    }
    const props = defineProps<Props>()
    </script>
    */

    컴파일러는 유형 매개변수를 추론하고 해당 런타임 옵션을 생성하려고 시도합니다. 이 방법을 유형 기반 문이라고 합니다. 이 접근 방식의 단점은 props의 기본값을 정의하는 기능이 손실된다는 것입니다. withDefaults 컴파일러를 사용하면 이 문제를 해결할 수 있습니다

    interface Props {
      msg?: string
      labels?: string[]
    }
     
    const props = withDefaults(defineProps<Props>(), {
      msg: &#39;hello&#39;,
      label: () => [&#39;one&#39;, &#39;two&#39;]
    })

    위 코드는 동등한 런타임 소품의 기본 옵션으로 컴파일됩니다.

    Non-

    import { defineComponent } from &#39;vue&#39;
     
    export default defineComponent({
      props: {
        message: String
      },
      setup(props){
        props.message // 类型:string
      }
    })

    emit 유형에 주석 달기

    <script setup lang="ts">
    // 运行时
    const emit = defineEmits([&#39;change&#39;, &#39;update&#39;])
     
    //基于类型
    const emit = defineEmits<{
      (e: &#39;change&#39;, id: number): void
      (e: &#39;update&#39;, value: string): void
    }>()
    </script>

    우리는 다음을 볼 수 있습니다. 유형 기반 선언을 통해 트리거되는 이벤트 유형을 보다 세밀하게 제어할 수 있습니다.

    Non-

    import { defineComponent } from &#39;vue&#39;
     
    export default definComponent({
      emits: [&#39;change&#39;],
      setup(props, { emit }) {
        emit(&#39;change&#39;) //类型检查 / 自动补全
      }
    })

    는 참조입니다. () 주석 유형

    기본 파생 유형

    ref은 초기화 중 값을 기반으로 해당 유형을 자동으로 추론합니다.

    import { ref } from &#39;vue&#39;
     
    // 推导出的类型:Ref<number>
     
    const year = ref(2022)
     
    // TS Error: Type &#39;string&#39; is not assignable to type &#39;number&#39;.
    year.value = &#39;2022&#39;

    인터페이스를 통해 유형을 지정하세요

    때때로 값에 대해 더 복잡한 유형을 지정하고 싶을 수도 있습니다. ref. Ref 인터페이스를 사용할 수 있습니다:

    import { ref } from &#39;vue&#39;
    import type { Ref } from &#39;vue&#39;
     
    const year: Ref<string | number> = ref(2022)
    year.value = 2022 //成功

    generics를 통해 유형을 지정하세요

    또는 ref()를 호출할 때 일반 매개변수를 전달하여 기본 파생 동작을 재정의하세요.

    // 得到的类型:Ref<string | number>
    const year = ref<string | number>(&#39;2022&#39;)
    year.value = 2022 //成功

    일반 매개변수를 지정했지만 그렇지 않은 경우 초기 값을 제공하면 최종 결과는 정의되지 않은 것을 포함하는 통합 유형이 됩니다:

    // 推导得到的类型:Ref<number | undefined>
    const n = ref<number>()

    반응형()에 대한 주석이 달린 유형

    기본 추론 유형

    reactive()도 해당 매개변수에서 암시적으로 유형을 파생합니다:

    import { reactive } from &#39;vue&#39;
     
    //推导得到的类型:{ title: string }
    const book = reactive({ title: &#39;Vue 3 指引&#39;})

    인터페이스 유형 지정

    반응형 변수의 유형을 명시적으로 지정하려면 다음 인터페이스를 사용할 수 있습니다.

    import { reactive } from &#39;vue&#39;
     
    interface Book {
      title: string
      year?: number
    }
     
    const book: Book = reactive({ title: &#39;Vue 3 指引&#39; })

    계산()의 유형을 표시합니다.

    기본 파생 유형

    computed()가 반환에서 자동으로 추론됩니다. 계산 함수의 값 유형:

    import { ref, computed } from &#39;vue&#39;
    const count = ref(0)
     
    // 推导得到的类型:ComputedRef<number>
    const double = computed(() => count.value * 2)
     
    // TS Error: Property &#39;split&#39; does not exist on type &#39;number&#39;
    const result = double.value.split(&#39;&#39;)

    generics를 통해 유형을 지정

    const double = component<number>(() => {
      // 若返回值不是 number 类型则会报错
    })

    이벤트 핸들러 함수의 유형에 주석을 답니다

    네이티브 DOM 이벤트를 처리할 때 이벤트 핸들러 함수의 매개변수는 다음과 같은 유형으로 올바르게 표시되어야 합니다. :

    <script srtup lang="ts">
    function handleChange(event) {
      // `event` 隐式地标注为 `any`类型
      console.log(event.target.value)
    }
    </script>
     
    <template>
      <input type="text" @change="handleChange" />
    </template>

    유형 주석이 없는 경우 이 이벤트 매개변수는 자동으로 모든 유형으로 인식됩니다. tsconfig.json에 "strict": true 또는 "noImplicitAny": true가 구성된 경우에도 TS 오류가 발생합니다. 따라서 이벤트 핸들러 함수 매개변수의 유형을 명시적으로 주석으로 추가하는 것이 좋습니다. 또한 이벤트에서 속성을 명시적으로 캐스팅해야 할 수도 있습니다.

    function handleChange(event: Event) {
      console.log((event.target as HTMLInputElement).value)
    }

    provide/inject에 대한 유형에 주석을 답니다.

    provide 및 inject는 일반적으로 다른 구성 요소에서 실행됩니다. 주입된 값의 유형을 올바르게 표시하기 위해 Vue는 Symbol에서 상속된 일반 유형이며 공급자와 소비자 간에 주입된 값의 유형을 동기화하는 데 사용할 수 있는 주입키 인터페이스를 제공합니다.

    import { provide, inject } from &#39;vue&#39;
    import type { Injectiokey } from &#39;vue&#39;
     
    const key = Symbol() as Injectionkey<string>
    provide(key,&#39;foo&#39;) // 若提供的是非字符串值会导致错误
     
    const foo = inject(key) // foo 的类型: string | undefined

    주입된 값에 권장됩니다. 키 유형은 여러 구성 요소에서 가져올 수 있도록 별도의 파일에 배치됩니다.

    문자열을 사용하여 키를 삽입하는 경우 삽입된 값의 유형을 알 수 없으며 일반 매개변수를 통해 명시적으로 선언해야 합니다.

    const foo = inject<string>(&#39;key&#39;) // 类型:string | undefined

    由于提供者在运行时可能没有提供这个值,因此请注意注入的值可能仍然是未定义的。移除 undefined 类型的方法是提供一个默认值

    const foo = inject<string>(&#39;foo&#39;, &#39;bar&#39;) // 类型:string

    如果你确定该值始终被提供,则还可以强制转换该值:

    const foo = inject(&#39;foo&#39;) as string

    为 dom 模板引用标注类型

    模板 ref 需要通过一个显式指定的泛型参数和一个初始值 null 来创建:

    <script setup lang="ts">
    import { ref, onMounted } from &#39;vue&#39;
    const el = ref<HTMLInputElement | null>(null)
     
    onMounted(() => {
      el.value?.focus()
    })
    </script>
     
    <template>
      <input ref="el" />
    </template>

    为了严格的类型安全,请使用可选链或类型守卫来访问 el.value。这是因为直到组件被挂载前,这个 ref 的值都是初始的 null,并且 v-if 将引用的元素卸载时也会被设置为 null。

    为组件模板引用标注类型

    有时候,我们需要为一个子组件添加一个模板引用(template reference),以便可以调用它公开的方法。举个例子,我们有一个 MyModal 子组件,其中包含一个用于打开模态框的方法:

    <script setup lang="ts">
    import { ref } from &#39;vue&#39;
     
    const isContentShown = ref(false)
    const open = () => (isContentShow.value = true)
     
    defineExpose({
      open
    })
    </script>

    为了获取 MyModal 的类型,我们首先需要通过 typeof 得到其类型,再使用 TypeScript 内置的 InstanceType 工具类型来获取其实例类型:

    <script>
    import MyModal from &#39;./MyModal.vue&#39;
     
    const modal = ref<InstanceType<typeof MyModal > | null>(null)
    const openModal = () => {
      modal.value?.open()
    }
    </script>

    위 내용은 vue3에서 ref 인스턴스를 ts InstanceType과 결합하는 문제를 해결하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제