Vue.js 3 和 typescript : 属性'$store'在类型'ComponentPublicInstance上不存在



找不到任何东西来解决这个看似显而易见的问题。

刚刚用Typescript从Vue 2升级到Vue 3和Vuex。

这个$尽管遵循了Vue 3的说明,但商店似乎无法访问。

src/components/FlashMessages中的错误。vue:28:25TS2339:类型"ComponentPublicInstance<"上不存在属性"$store";{},{},{},{getAllFlashMessages((:Word;},{}、EmitsOptions、{}、{},false,ComponentOptionsBase<{},{},{},{getAllFlashMessages((:Word;},{}、ComponentOptionsMixin,ComponentOptionsMix,EmitsOptions,string,{}>gt;'。

26 |     computed: {
27 |         getAllFlashMessages (): FlashType {
> 28 |             return this.$store.getters.getFlashMessages;
|                         ^^^^^^
29 |         },
30 |     },
31 | 

主.ts

import { createApp } from 'vue'
import App from './App.vue'
import './registerServiceWorker'
import router from './router'
import store from './store'
import './assets/styles/index.css'
const app = createApp(App)
app.use(store)
app.use(router)
app.mount('#app')

存储.ts

import { createStore } from 'vuex'
import FlashType from '@/init'
export default createStore({
state: {
flashMessages: [] as FlashType[],
},
getters: {
getFlashMessages (state) {
return state.flashMessages
}
},

FlashMessages.vue

<script lang="ts">
import { defineComponent } from "vue";
import FlashType from "@/init";
export default defineComponent({
name: "FlashMessages",
data () {
return {};
},
computed: {
getAllFlashMessages (): FlashType {
return this.$store.getters.getFlashMessages;
},
},

init.ts

export type FlashType = {
kind: 'success' | 'error';
message: string;
time: number;
}

任何智慧都值得赞赏:(

文件结构

├── .editorconfig
├── client
│   ├── babel.config.js
│   ├── CONTRACTS.md
│   ├── cypress.json
│   ├── jest.config.js
│   ├── package.json
│   ├── package-lock.json
│   ├── postcss.config.js
│   ├── public
│   │   ├── favicon.ico
│   │   ├── index.html
│   │   └── robots.txt
│   ├── README.md
│   ├── src
│   │   ├── App.vue
│   │   ├── assets
│   │   │   ├── logo.png
│   │   │   └── styles
│   │   │       └── index.css
│   │   ├── components
│   │   │   ├── admin
│   │   │   │   ├── AdminAdd.vue
│   │   │   │   ├── AdminList.vue
│   │   │   │   ├── AdminWord.vue
│   │   │   │   ├── EmotionAdd.vue
│   │   │   │   ├── EmotionsList.vue
│   │   │   │   └── Emotion.vue
│   │   │   └── FlashMessages.vue
│   │   ├── init.ts
│   │   ├── main.ts
│   │   ├── registerServiceWorker.ts
│   │   ├── router
│   │   │   └── index.ts
│   │   ├── shims-vue.d.ts
│   │   ├── store
│   │   │   └── index.ts
│   │   └── views
│   │       ├── About.vue
│   │       ├── Admin.vue
│   │       ├── Emotions.vue
│   │       └── Home.vue
│   ├── tsconfig.json
│   └── vue.config.js
├
└── server
├── api
├── api.bundle.js
├── index.ts
├── logger
│   └── logger.ts
├── models
├── nodemon.json
├── package.json
├── package-lock.json
├── router
│   ├── db.ts
│   └── emotions.ts
├── tsconfig.json
└── webpack.config.js

这是我第一次正确使用esint,所以我不确定我是否正确设置了它。。最后,我在/client和/server目录中得到了一个不同的tsconfig。

client/tsconfig.json

{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": "./",
"types": [
"webpack-env",
"jest"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}

shims-vue.d.ts文件旁边创建另一个名为shims-vuex.d.ts的文件,内容如下:

import { Store } from '@/store';// path to store file
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$store: Store;
}
}

有关更多信息,请查看Typescript支持部分以了解更多详细信息

我在VS代码中也出现了类似的错误。从Vuex 4开始,这是首选方法:

// vuex-shim.d.ts
import { ComponentCustomProperties } from 'vue'
import { Store } from 'vuex'
declare module '@vue/runtime-core' {
// Declare your own store states.
interface State {
count: number
}
interface ComponentCustomProperties {
$store: Store<State>
}
}

文档:https://next.vuex.vuejs.org/guide/migrating-to-4-0-from-3-x.html#typescript-支持

我不得不禁用然后再次启用Vetur

对于那些通过Vue类组件和/或Vue属性装饰器使用VS Code和Vue与TypeScript的人,可能不需要添加更多的类型声明。这个问题可以用tsconfig.json来解决。即具有include性质。

如果看到此错误的文件不在include属性的globs列表中,则会看到缺少this.$store定义错误。

请注意,在下面的代码中,如果从include数组中省略tests/...glob,则匹配该glob的文件中将出现错误。如果您将glob添加回,则错误将消失。

"include": ["src/**/*.ts", "src/**/*.vue", "tests/e2e/.fixtures/**/*.ts"]

尝试添加

app.provide("$store", store);

在安装之前,请将其保存在main.ts文件中。这种方法在我这边有效,最终代码看起来像

...
let app = createApp(App);
app.provide("$store", store);
app.use(store);
app.mount("#app");

我做了与上面的解决方案相同的事情,但除此之外,我为应用程序创建了一个globalProperty。

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
const app = createApp(App);
app.config.globalProperties.$store = store;
app.use(router).mount('#app');

我在尝试使用typescript和选项API配置vuex时遇到了很多问题。无论您使用的是哪种API,我强烈建议您使用Pinia,因为它是一种支持打字脚本的解决方案,与Vuex 非常相似

Vuex没有为此提供打字员$存储开箱即用的属性。与TypeScript一起使用时,必须声明自己的模块扩充。参考

相关内容

最新更新