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

Vue3+Vite+TypeScript组合式API下如何正确添加全局属性至组件模板

Vue3 + Vite + TypeScript 全局$t属性模板不生效问题解决

问题场景

在使用Vue3、Vite、TypeScript及组合式API的项目中,通过自定义插件向全局注册$t属性后,组件模板中无法正常使用该属性。以下是项目相关代码与配置:

src/main.ts

import { createApp } from 'vue'
import languagePlugin from '@/plugins/languagePlugin'
import App from './App.vue'

const app = createApp(App)
app.use(languagePlugin)
app.mount('#app')

./src/plugins/languagePlugin.ts

import { App } from 'vue'

export default {
    install(app: App) {
        app.config.globalProperties.$t = (key: string): string => key
    }
}

package.json

{
  ...
  "type": "module",
  ...
  "dependencies": {
    ...
    "vue": "^3.2.47"
  },
  "devDependencies": {
    "@types/node": "^18.15.3",
    "@vitejs/plugin-vue": "^4.1.0",
    "@vue/eslint-config-typescript": "^11.0.2",
    "eslint": "^8.36.0",
    "eslint-plugin-vue": "^9.9.0",
    "typescript": "^4.9.5",
    "vite": "^4.2.0",
    "vue-tsc": "^1.2.0"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "strict": false,
    "jsx": "preserve",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "types": [
      "vite/client"
    ],
    "lib": [
      "ESNext",
      "DOM"
    ],
    "skipLibCheck": true,
    "noEmit": true,
    "paths": {
      "@/*": [
        "./src/*"
      ]
    }
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.vue"
  ],
  "references": [
    {
      "path": "./tsconfig.node.json"
    }
  ],
  "exclude": [
    "node_modules",
    "dist"
  ]
}

tsconfig.node.json

{
  "compilerOptions": {
    "composite": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "allowSyntheticDefaultImports": true
  },
  "include": [
    "vite.config.ts"
  ]
}

./src/vite-env.d.ts

/// <reference types="vite/client" />

interface ImportMetaEnv {
    readonly VITE_APP_NAME: string
    readonly VITE_API_URL: string
}

interface ImportMeta {
    readonly env: ImportMetaEnv
}

./shims-vue.d.ts

declare module '*.vue' {
    import { defineComponent } from 'vue'
    const Component: ReturnType<typeof defineComponent>
    export default Component
}

./shims-vue-runtime-core.d.ts

export {}

declare module '@vue/runtime-core' {
    interface ComponentCustomProperties {
        $t(key: string): string
    }
}

解决步骤

1. 调整类型声明文件位置

当前shims-vue-runtime-core.d.ts放在项目根目录,但tsconfig.json的include仅包含src/**/*,导致TypeScript无法解析该类型声明。将该文件移动到src/目录下(即src/shims-vue-runtime-core.d.ts),确保被tsconfig.json的规则覆盖。

2. 验证类型合并逻辑

文件开头的export {}是必要的,它确保该文件被当作模块处理,从而让ComponentCustomProperties的扩展能够正确合并到Vue的全局类型中。

3. 组合式API中访问全局属性(可选)

如果在<script setup>中需要通过代码访问$t,可以通过getCurrentInstance获取:

import { getCurrentInstance } from 'vue'

const { appContext } = getCurrentInstance()!
const $t = appContext.config.globalProperties.$t

模板中则可以直接使用{{ $t('key') }},无需额外处理,只要类型配置正确。

4. 重启开发服务器

Vite和TypeScript的缓存可能导致类型更新不及时,重启开发服务器以确保新的类型声明生效。

5. 确认插件注册顺序

确保app.use(languagePlugin)在app.mount('#app')之前执行,你的代码已经符合该要求,无需调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 07:54:58