Intellisense для Vuex Store в VS Code

Я создаю приложение, используя , и в . У меня установлено расширение . Я создал файл определения, чтобы дать мне intellisense для большей части моего проекта, но я не смог понять, как добавить мое хранилище в intellisense. Я прочитал Документация по определению, но мне не удалось вместе решить, как я могу это сделать. Моя цель - получить возможность использовать intellisense для чего угодно в this.$store.. В настоящее время предоставляет intellisense для state, getters и т. д., Но не предоставляет intellisense для следующего уровня (например, this.$store.state.TestVariable). Как я могу получить intellisense для моего магазина ?

Магазин управления контрактами

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        Contract: new Library.Model.Entity.Contract()
    }
});

Компонент контракта

<template>
    <contract-line></contract-line>
</template>

<script lang = "ts">
    import Vue from 'vue';
    import Vuex from 'vuex';
    import store from '../store/ContractManagementStore';
    import ContractLine from "./ContractLine.vue";

    export default Vue.extend({
        name: 'contract-management',
        store,
        components: {
            'contract-line': ContractLine
        }
    });
</script>

<style>

</style>

Компонент строки контракта

<template>
    <button v-if = "CanDelete"></button>
</template>

<script lang = "ts">
    import Vue from 'vue';
    import Vuex from 'vuex';

    Vue.use(Vuex);

    export default Vue.extend({
        computed:{
            CanDelete(): Boolean {
                // Looking for intellisense after this.$store.state.
                return this.$store.state.Contract.ContractStatus.Value === Library.Enums.ContractStatus.Draft
            }
        }
    });
</script>

<style>

</style>
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
6
0
3 055
2

Ответы 2

Вы можете добиться этого, явно указав свое состояние.

В Contract Management Store.ts

export interface ContractManagementState {
    Contract: ContractType;
}

В вашем компоненте:

...
(this.$store as Store<ContractManagementState>).<intellisense here>

К сожалению, вы должны делать это каждый раз, когда получаете доступ к состоянию таким образом. Это связано с тем, как Vuex использует расширение модуля, чтобы объявить о существовании свойства $store в машинописном тексте.

В vuex/types/vue.d.ts:

declare module "vue/types/vue" {
  interface Vue {
    $store: Store<any>;
  }
}

Вы не можете заменить any вашими конкретными типами состояний (в конце концов, это называется модулем увеличение). Возможное решение - использовать геттеры для доступа к вашему магазину. Существует несколько библиотек машинописных текстов для добавления информации о типах к геттерам, мутаторам и действиям, например vuex-typescript и vuex-typex.

Я не думаю, что согласен с вами в том, что использование геттеров является лучшей практикой. Читая документация, я вижу, что доступ к хранилищу осуществляется напрямую для чтения данных. Я считаю, что лучшая практика больше ориентирована на изменение данных с помощью мутаций / действий, которые я правильно использую в своем коде. У вас есть какая-либо документация Vuex, на которую вы могли бы указать мне, о том, чтобы всегда использовать геттеры для доступа к состоянию?

Tim Hutchison 01.06.2018 16:29

Я могу получить intellisense для состояния из этого ... Как мне изменить его, чтобы также получить intellisense для геттеров / мутаторов / действий?

Tim Hutchison 01.06.2018 16:46

Вы абсолютно правы, в документации Vuex нет рекомендаций, явно рекомендующих геттеры вместо прямого доступа к состоянию. Я отредактировал свой ответ, поэтому мое мнение не похоже на официальную рекомендацию. Тем не менее, я все еще думаю, что пункты, касающиеся отладки и развязки, актуальны. Кроме того, касаясь вашего второго комментария, геттеры просто лучше работают с машинописным текстом. Я рекомендую взглянуть на библиотеку, которую я опубликовал в ответе, которая позволяет вам также вводить мутаторы и действия (за счет некоторого накладного кода)

Georg Grab 01.06.2018 18:00

Я также сталкиваюсь с этой проблемой в эти два дня и не могу вынести отсутствия понимания набора текста this.$store.state.

Решение @ georg-grab дает мне это вдохновение.

  1. I'm not familiar with TypeScript... So this solution may be silly, but it works.
  2. My solution can only deal with this.$store.state, all others such as this.$store.dispatch still has no IntelliSense
// store/index.ts
// I will not explain vuex modules here. Please see the doc of Vuex by yourself.
import Vue from 'vue'
import Vuex, {Store} from 'vuex'

import auth, {State as AuthState} from './modules/auth'  // State is an interface defined in module.

export interface State {
  auth: AuthState
}

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    auth
  }
}) as Store<State>  // Force TypeScript compiler to recognize this as Store<State> instead of Store<any>.

Затем добавьте глобальный получатель экземпляра через плагин Vue:

// main.ts
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store, { State } from './store'

declare module 'vue/types/vue' {  // Tell TypeScript the type of this.$state is our defined 'State'
  interface Vue {
    $state: State
  }
}
const TypedState = {  // define a Vue plugin. See https://vuejs.org/v2/guide/plugins.html
  install(Vue: any) {  // For simplify, didn't pass 'State' via options
    Object.defineProperty(Vue.prototype, '$state', {  // Add a global getter 'this.$state' in vm
      get (): State { return store.state as State }  // Force TypeScript compiler to recognize this as our defined 'State'
    })
  }
}
Vue.use(TypedState)

Теперь вы можете получить доступ к значениям в this.$store.state через this.$state с помощью IntelliSense.

I also want to "overwrite" the interface of vm.$store (from Store<any> to Store<State>), but TypeScript seems to has no way to do such thing:

declare module 'vue/types/vue' {
  interface Vue {
    $store: Store<State>   // Error
  }
}

Другие вопросы по теме