You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue+TypeScript获取插槽文本遇TS7053错误,求正确实现方案

如何正确访问Vue组件插槽内的文本内容?

问题背景

我编写了一个GoogleTranslate.vue组件,意图将插槽内容翻译为母语,组件代码及使用方式如下:

组件代码:

<template>
  <div>
    <slot></slot>
    <!-- This is a tooltip from bootstrap -->
    <i class="ms-2 bi bi-globe" data-bs-toggle="tooltip" :title="translateText()"></i>
  </div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
  name: "VueGoogleTranslate",
  components: {},
  props: {},
  mounted() {},
  setup() {},
  methods: {
    translateText() {
         // Get the text content of slot and translate it with the google-translate-api
        let textToTranslate : string = this.$slots.default[0].text;
        return textToTranslate;
    }
  },
  data() {
    return {};
  }
});
</script>
<style scoped>
</style>

组件使用方式:

<GoogleTranslate>
Ce test est en français et devrait être traduit en anglais.
</GoogleTranslate>

执行npm run build时出现TypeScript错误:

src/components/atoms/GoogleTranslate.vue:35:40 - error TS7053: Element implicitly has an 'any' type because expression of type '0' can't be used to index type 'Slot<any>'.
  Property '0' does not exist on type 'Slot<any>'.
35         let textToTranslate : string = this.$slots.default[0].text;
                                          ~~~~~~~~~~~~~~~~~~~~~~

错误原因

this.$slots.default在Vue的类型定义中是Slot<any>类型,它本质是一个返回VNode数组的函数,而非直接的数组,因此不能通过[0]直接索引访问。

解决方法

要正确提取插槽文本,需先调用this.$slots.default()获取VNode列表,再递归提取所有文本内容(处理嵌套VNode的情况),同时处理空插槽的边界条件:

修改后的translateText方法:

translateText(): string {
  // 定义递归提取文本的辅助函数
  const extractText = (vnodes: any[]): string => {
    return vnodes.reduce((text, vnode) => {
      // 如果是文本节点,直接取内容
      if (vnode.type === Text) {
        return text + vnode.children;
      }
      // 如果是有子节点的元素,递归提取
      if (vnode.children && Array.isArray(vnode.children)) {
        return text + extractText(vnode.children);
      }
      return text;
    }, '').trim();
  };

  // 获取插槽VNode数组,处理插槽为空的情况
  const slotVNodes = this.$slots.default?.() || [];
  return extractText(slotVNodes);
}

完整修改后的组件代码

<template>
  <div>
    <slot></slot>
    <!-- This is a tooltip from bootstrap -->
    <i class="ms-2 bi bi-globe" data-bs-toggle="tooltip" :title="translateText()"></i>
  </div>
</template>
<script lang="ts">
import { defineComponent, Text } from "vue";
export default defineComponent({
  name: "VueGoogleTranslate",
  components: {},
  props: {},
  mounted() {},
  setup() {},
  methods: {
    translateText(): string {
      const extractText = (vnodes: any[]): string => {
        return vnodes.reduce((text, vnode) => {
          if (vnode.type === Text) {
            return text + vnode.children;
          }
          if (vnode.children && Array.isArray(vnode.children)) {
            return text + extractText(vnode.children);
          }
          return text;
        }, '').trim();
      };

      const slotVNodes = this.$slots.default?.() || [];
      return extractText(slotVNodes);
    }
  },
  data() {
    return {};
  }
});
</script>
<style scoped>
</style>

说明

  • 引入Vue的Text类型判断文本节点,确保类型安全
  • 递归处理嵌套VNode,可正确提取插槽内包含HTML标签或子组件时的文本内容
  • 用?.()和|| []处理空插槽场景,避免空指针错误

内容的提问来源于stack exchange,提问作者flori10

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:10:17