Vue.js 3 和打字稿:属性 '$store' 在类型 'ComponentPublicInstance 上不存在
Vue.js 3 and typescript : Property '$store' does not exist on type 'ComponentPublicInstance
找不到解决这个看似显而易见的问题的方法。
刚刚从 Vue 2 升级到 Vue 3 和 Vuex with Typescript。
this.$store 似乎无法访问,尽管遵循了 Vue 3 说明。
ERROR in src/components/FlashMessages.vue:28:25
TS2339: Property '$store' does not exist on type 'ComponentPublicInstance<{}, {}, {}, { getAllFlashMessages(): Word; }, {}, EmitsOptions, {}, {}, false, ComponentOptionsBase<{}, {}, {}, { getAllFlashMessages(): Word; }, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, {}>>'.
26 | computed: {
27 | getAllFlashMessages (): FlashType {
> 28 | return this.$store.getters.getFlashMessages;
| ^^^^^^
29 | },
30 | },
31 |
main.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')
store.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
这是我第一次正确使用 eslint,所以我不确定我是否设置正确。我最终在 /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 support 部分
我在 VS Code 中遇到了类似的错误。
从 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-support
我不得不禁用然后再次启用 Vetur。
我做了与上面的解决方案相同的事情,但另外,我为应用程序创建了一个 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');
尝试添加
app.provide("$store", store);
在您的 main.ts
文件中,然后安装。这个方法对我有效,最终代码看起来像
...
let app = createApp(App);
app.provide("$store", store);
app.use(store);
app.mount("#app");
Vuex 不提供开箱即用的类型。$store 属性。与 TypeScript 一起使用时,您必须声明自己的模块扩充。
Reference
对于那些通过 vue-class-component and/or vue-property-decorator there may be no need in adding more type declarations. The issue could be solved with tsconfig.json
使用 VS Code 和 Vue with TypeScript 的人。即与其include
属性.
如果您看到此错误的文件不在 include
属性.
中的 glob 列表中,您将看到缺少 this.$store
定义错误
请注意,在下面的代码中,如果您从 include
数组中省略 tests/....
glob,则错误将出现在与此 glob 匹配的文件中。如果您将 glob 添加回去,错误将消失。
"include": ["src/**/*.ts", "src/**/*.vue", "tests/e2e/.fixtures/**/*.ts"]
我在尝试使用 typescript 和选项配置 vuex 时遇到了很多问题 API。无论您使用什么 API,我都强烈建议您使用 Pinia,因为它是一个 typescript ready 解决方案并且与 Vuex 非常相似
找不到解决这个看似显而易见的问题的方法。
刚刚从 Vue 2 升级到 Vue 3 和 Vuex with Typescript。
this.$store 似乎无法访问,尽管遵循了 Vue 3 说明。
ERROR in src/components/FlashMessages.vue:28:25 TS2339: Property '$store' does not exist on type 'ComponentPublicInstance<{}, {}, {}, { getAllFlashMessages(): Word; }, {}, EmitsOptions, {}, {}, false, ComponentOptionsBase<{}, {}, {}, { getAllFlashMessages(): Word; }, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, {}>>'.
26 | computed: {
27 | getAllFlashMessages (): FlashType {
> 28 | return this.$store.getters.getFlashMessages;
| ^^^^^^
29 | },
30 | },
31 |
main.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')
store.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
这是我第一次正确使用 eslint,所以我不确定我是否设置正确。我最终在 /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 support 部分
我在 VS Code 中遇到了类似的错误。 从 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-support
我不得不禁用然后再次启用 Vetur。
我做了与上面的解决方案相同的事情,但另外,我为应用程序创建了一个 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');
尝试添加
app.provide("$store", store);
在您的 main.ts
文件中,然后安装。这个方法对我有效,最终代码看起来像
...
let app = createApp(App);
app.provide("$store", store);
app.use(store);
app.mount("#app");
Vuex 不提供开箱即用的类型。$store 属性。与 TypeScript 一起使用时,您必须声明自己的模块扩充。 Reference
对于那些通过 vue-class-component and/or vue-property-decorator there may be no need in adding more type declarations. The issue could be solved with tsconfig.json
使用 VS Code 和 Vue with TypeScript 的人。即与其include
属性.
如果您看到此错误的文件不在 include
属性.
this.$store
定义错误
请注意,在下面的代码中,如果您从 include
数组中省略 tests/....
glob,则错误将出现在与此 glob 匹配的文件中。如果您将 glob 添加回去,错误将消失。
"include": ["src/**/*.ts", "src/**/*.vue", "tests/e2e/.fixtures/**/*.ts"]
我在尝试使用 typescript 和选项配置 vuex 时遇到了很多问题 API。无论您使用什么 API,我都强烈建议您使用 Pinia,因为它是一个 typescript ready 解决方案并且与 Vuex 非常相似