#typescript #vue.js #vuejs3
#typescript #vue.js #vuejs3
Вопрос:
Я использую новый API-интерфейс Vue 3 Composition и написал «хранилище» для реактивных данных.
const state = reactive<State>({
accessToken: undefined,
user: undefined,
});
export default {
state: readonly(state),
}
При создании приложения я предоставляю хранилище для всех компонентов:
const app = createApp(App)
.provide("store", store)
.use(IonicVue)
.use(router);
И, наконец, в компоненте / представлении я вводю хранилище, чтобы использовать его.
export default defineComponent({
name: "Home",
inject: ["store"],
components: {
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar,
IonButton,
},
computed: {
email() {
return this.store.state.user.email;
},
},
});
</script>
К сожалению, Typescript не нравится способ, который я использую this.store
в вычисляемом свойстве email()
И говорит
Свойство ‘store’ не существует для типа ‘ComponentPublicInstance<{}, {}, {}, { email(): любой; }, {}, EmitsOptions, {}, {}, false, ComponentOptionsBase<{}, {}, {}, { электронная почта (): любая; }, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, строка, {}>>’
Я имею в виду, что все работает нормально, когда я удаляю lang="ts"
<script/>
тег in, но без отображения ошибки. Есть какие-нибудь предложения о том, как это исправить или что это конкретно означает?
Заранее спасибо!
Ответ №1:
Я рекомендую использовать хранилище как глобальное свойство без указания inject
в каком-либо дочернем компоненте, потому что provide / inject может иметь некоторые оговорки о реактивности:
const app = createApp(App)
.use(IonicVue)
.use(router);
app.config.globalProperties.store= store;
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
store:any // replace it with the right type
}
}
затем используйте его напрямую :
export default defineComponent({
name: "Home",
components: {
...
},
computed: {
email() {
return this.store.state.user.email;
},
},
});
</script>
Ответ №2:
Для тех, кто сталкивается с той же проблемой с Vue 3 TS, я нашел решение без необходимости изменять app.config
или объявлять новый module
:
- Настройка App.ts
import { createApp, reactive } from 'vue'
import App from './App.vue'
const Store = reactive({
myProperty: 'my value'
})
createApp(App)
.provide('Store', Store)
.mount('#app')
- Компонент, получающий доступ к введенному реактивному объекту:
<template>
<div>{{ Store.myProperty }}</div>
</template>
<script lang="ts">
import { IStore } from '@/types'
import { defineComponent, inject } from 'vue'
export default defineComponent({
name: 'MyComponentName',
setup() {
return {
Store: inject('Store') as IStore,
}
},
created() {
console.log(this.Store) // will show the `Store` in the console
}
})
</script>
- Определение типа для хранилища (
@/types.ts
):
export interface IStore {
myProperty: string
}
Выполнив эти 3 шага, я смог читать / записывать Store.myProperty
без проблем, используя TypeScript
Комментарии:
1. а как пользоваться часами? в настройках