程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了在 Vue 3 中从父级到子级调用函数 - TypeScript大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决在 Vue 3 中从父级到子级调用函数 - TypeScript?

开发过程中遇到在 Vue 3 中从父级到子级调用函数 - TypeScript的问题如何解决?下面主要结合日常开发的经验,给出你关于在 Vue 3 中从父级到子级调用函数 - TypeScript的解决方法建议,希望对你解决在 Vue 3 中从父级到子级调用函数 - TypeScript有所启发或帮助;

我已从 Quasar v1 迁移到 Quasar v2,并因此迁移到 Vue 3。我有以下在 Quasar v1 (Vue v2) 中运行的代码,但现在在 Quasar v2 (Vue v3) 中运行时我选择过滤器时,在控制台中收到以下错误消息

Uncaught (in promisE) TypeError: vIEw.value.fetchFilteredresources is not a function
    searchresourcesString MainLayout.vue:128
    fulfilled index.Js:16
    promise callBACk*step index.Js:18
    __awaiter index.Js:19
    __awaiter index.Js:15
    searchresourcesString MainLayout.vue:124
    callWithErrorHandling runtime-core.esm-bundler.Js:154
    callWithAsyncErrorHandling runtime-core.esm-bundler.Js:163
    invoker runtime-dom.esm-bundler.Js:333
    addEventListener runtime-dom.esm-bundler.Js:283
    patchEvent runtime-dom.esm-bundler.Js:301
    patchProp runtime-dom.esm-bundler.Js:369
    mountElement runtime-core.esm-bundler.Js:3905
    procesSELER_466_11845@ent runtime-core.esm-bundler.Js:3868
    patch runtime-core.esm-bundler.Js:3788
    mountChildren runtime-core.esm-bundler.Js:3975
    mountElement runtime-core.esm-bundler.Js:3896
    procesSELER_466_11845@ent runtime-core.esm-bundler.Js:3868
    patch runtime-core.esm-bundler.Js:3788
    mountChildren runtime-core.esm-bundler.Js:3975
    mountElement runtime-core.esm-bundler.Js:3896
    procesSELER_466_11845@ent runtime-core.esm-bundler.Js:3868
    patch runtime-core.esm-bundler.Js:3788
    mountChildren runtime-core.esm-bundler.Js:3975
    mountElement runtime-core.esm-bundler.Js:3896
    procesSELER_466_11845@ent runtime-core.esm-bundler.Js:3868
    patch runtime-core.esm-bundler.Js:3788
    mountChildren runtime-core.esm-bundler.Js:3975
    mountElement runtime-core.esm-bundler.Js:3896
    procesSELER_466_11845@ent runtime-core.esm-bundler.Js:3868
    patch runtime-core.esm-bundler.Js:3788
    componentEffect runtime-core.esm-bundler.Js:4298
    reactiveEffect reactivity.esm-bundler.Js:42
    effect reactivity.esm-bundler.Js:17
    setupRenderEffect runtime-core.esm-bundler.Js:4263
    mountComponent runtime-core.esm-bundler.Js:4222
    processComponent runtime-core.esm-bundler.Js:4182
    patch runtime-core.esm-bundler.Js:3791
    mountChildren runtime-core.esm-bundler.Js:3975 MainLayout.vue:128

应该发生的是调用函数以过滤 GraphQL 查询的结果。

./src/pages/Index.vue

<template ref="indexPage">
  <q-page class="row items-center justify-evenly">
    <div>
        ...
    </div>
  </q-page>
</template>

<script lang="ts">
/* eslint-disable vue/require-default-prop */
import { usequery } from '@vue/apollo-composable'
import { defineComponent,onMounted,ref } from 'vue'
import { GET_resourcES,GET_resourcES_LENGTH } from '../gql/resource/querIEs'
import { Loading } from 'quasar'

export default defineComponent({
  name: 'PageIndex',props: {
    formats: {
      type: Array
    },Tags: {
      type: Array
    },levels: {
      type: Array
    },keyword: {
      type: String
    },languages: {
      type: Array
    }
  },setup (props) {
    const apIISUp = ref<Boolean>(true)
    const { onError } = usequery(GET_resourcES,{ limit: 1 })
    onError(() => {
      apIISUp.value = false
    })
    // Read envs for page state
    const onDevice = ref<any>(process.env.oNDEVICE)
    // Loading Boolean in case the API is very fast,the UI still loads for a lil bit - better User ExperIEnce
    const limit = ref<number>(250)
    const disablebutton = ref<Boolean>(true)
    // Fetch resources query
    const {
      result: fetchedresources,loading: fetchresourcesLoading,refetch: fetchresources
    } = usequery(GET_resourcES,{ limit: 250 })
    const {
      result: fetchedresourcesLength,loading: fetchresourcesLengthLoading,refetch: fetchresourcesLength
    } = usequery(GET_resourcES_LENGTH,{})

    // On mount,enable loading and fetch resources
    onMounted(async () => {
      await fetchresources()
    })

    // Enable loading and filter resources according to all inputs
    const fetchFilteredresources = async (
      keyword:string = props.keyword!,formats: String[] = props.formats! as String[],languages: String[] = props.languages as String[],Tags: String[] = props.Tags as String[],levels: String[] = props.levels as String[]) => {
      Loading.show()
      await fetchresourcesLength(
        {
          keyword,languages,formats,Tags,levels
        }
      )
      await fetchresources({
        keyword,levels,limit: limit.value
      } as any)
      Loading.hIDe()
    }

    // ...

    return {
      apIISUp,disablebutton,fetchedresources,fetchFilteredresources,fetchresourcesLoading,fetchedresourcesLength,fetchresourcesLengthLoading,limit,loadMore,onDevice,redirect
    }
  }
})
</script>

./src/layouts/MainLayout.vue

<template>
  <q-layout vIEw="lHh Lpr lFf">

      // ...

    <q-drawer
      v-model="leftDrawerOpen"
      show-if-above
      v-if="isInIndex"
      bordered
      class="bg-white"
    >
      <q-List>
            <q-item-label
            header
            class="text-grey-8 text-h5 text-center q-mt-md"
            >
            {{ $t('search_options') }}
            </q-item-label>
            <q-separator class="q-mt-md" />

        <q-input
          outlined
          class="q-mt-lg q-mx-auto w-90"
          v-model="keyword"
          clearable
          @keyup="searchresourcesString"
          :label="$t('keywords')"
        />
        <q-SELEct
          class="w-90 q-mx-auto q-mt-md"
          outlined
          v-if="fetchedLanguages"
          v-model="SELEctedLanguages"
          :label="$t('languages')"
          :option-label="(lang) => lang.language"
          :option-value="(lang) => lang.ID"
          :options="fetchedLanguages.languages"
          @update:model-value="searchresources"
          multiple
          map-options
          emit-value
        >
          <template #option="{ itemProps,opt,SELEcted,toggLeoption }">
            <q-item
              v-bind="itemProps"
              v-on="itemProps"
            >
              <q-item-section>
                <q-item-label v-HTML="opt.language" />
              </q-item-section>
              <q-item-section sIDe>
                <q-toggle
                  :model-value="SELEcted"
                  @update:model-value="toggLeoption(opt)"
                />
              </q-item-section>
            </q-item>
          </template>
        </q-SELEct>

    // ...

    <q-page-container>
      <router-vIEw
        ref="vIEw"
        :keyword="keyword"
        :formats="SELEctedFormats"
        :Tags="SELEctedTags"
        :levels="SELEctedLevels"
        :languages="SELEctedLanguages"
      />
    </q-page-container>
  </q-layout>
</template>

<script lang="ts">

import { computed,defineComponent,ref,watch } from 'vue'
import { usequery } from '@vue/apollo-composable'
import { GET_LANGUAGES } from '../gql/language/querIEs'
import { GET_FORMATS } from '../gql/format/querIEs'
import { GET_Tags } from '../gql/tag/querIEs'
import { GET_LEVELS } from '../gql/level/querIEs'
import { GET_resourcES_LENGTH } from '../gql/resource/querIEs'
import { Quasar,useQuasar } from 'quasar'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'

export default defineComponent({
  name: 'MainLayout',setup () {
    const $q = useQuasar()
    const $router = useRouter()
    const keyword = ref<String>('')
    // Router vIEw reference in order to call method from parent to child
    const vIEw = ref<any>(null)
    // SELEcted languages for SELEct dropdown - IDs
    const SELEctedLanguages = ref<String[]>([])
    // SELEcted formats
    const SELEctedFormats = ref<[]>([])
    // SELEcted Tags
    const SELEctedTags = ref<String[]>([])
    // SELEcted level
    const SELEctedLevels = ref<String[]>([])

    // ...

    // Fetch languages query
    const { result: fetchedLanguages,loading: fetchLanguagesLoading,refetch: fetchLanguages } = usequery(GET_LANGUAGES)
    // Fetch formats query
    const { result: fetchedFormats,loading: fetchFormatsLoading,refetch: fetchFormats } = usequery(GET_FORMATS)
    // Fetch Tags query
    const { result: fetchedTags,loading: fetchTagsLoading,refetch: fetchTags } = usequery(GET_Tags)
    // Fetch level query
    const { result: fetchedLevels,loading: fetchLevelsLoading,refetch: fetchLevels } = usequery(GET_LEVELS)
    // Fetch resources query
    const {
      result: fetchedresourcesLength
    } = usequery(GET_resourcES_LENGTH,{})

    onMounted(async () => {
      await fetchLanguages()
      await fetchFormats()
      await fetchTags()
      await fetchLevels()
    })
    // If keyword input is cleared,then execute the query
    watch(() => keyword.value,(newvalue) => {
      if (newValue === null) {
        searchresources()
      }
    })

    // Method to call fetchFilteredresources from parent to child
    const searchresources = async () => {
      vIEw.value.fetchFilteredresources(keyword.value,SELEctedFormats.value,SELEctedLanguages.value,SELEctedTags.value,SELEctedLevels.value)
    }

    // Method to call fetchFilteredresources from parent to child
    const searchresourcesString = async () => {
      if (!searching.value) {
        searching.value = true
        await delay(1000)
        vIEw.value.fetchFilteredresources(keyword.value,SELEctedLevels.value)
        searching.value = false
      }
    }

    return {
      changeLanguage,fetchedLanguages,fetchFormatsLoading,fetchLanguagesLoading,fetchedTags,fetchTagsLoading,fetchedLevels,fetchLevelsLoading,fetchedFormats,isInIndex,keyword,leftDrawerOpen,reseTinputs,SELEctedLanguages,SELEctedFormats,SELEctedTags,SELEctedLevels,SELEctedLanguage,searchresources,searchresourcesString,vIEw
    }
  }
})
</script>

任何想法如何以最少的更改恢复功能(我希望只是让它工作而不是必须进行任何重构)?

解决方法

vue-router 4 的迁移指南没有明确说明,但是您不能再通过 <router-view> 标签本身来引用子组件。提到了一种处理子插槽的新范式,结果证明它也适用于您的用例;这是调整后的代码:

      <router-view
        v-slot="{ Component,route }"
        :keyword="keyword"
        :formats="SELEctedFormats"
        :tags="SELEctedTags"
        :levels="SELEctedLevels"
        :languages="SELEctedLanguages"
      >
        <component
          :is="Component"
          :key="route.meta.usePathKey ? route.path : undefined"
          ref="view"
        />
      </router-view>

大佬总结

以上是大佬教程为你收集整理的在 Vue 3 中从父级到子级调用函数 - TypeScript全部内容,希望文章能够帮你解决在 Vue 3 中从父级到子级调用函数 - TypeScript所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。