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
相关产品推荐
相关产品推荐

