All Projects → Goldziher → vuex-hooks

Goldziher / vuex-hooks

Licence: MIT license
Typescript enabled vuex composition-api hooks

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to vuex-hooks

vuelve
A declarative syntax for the Composition API in Vue 3.
Stars: ✭ 38 (+216.67%)
Mutual labels:  composition-api
ts-express-vue3
Boilerplate for Express + Vue 3 with Typescript and Composition API
Stars: ✭ 15 (+25%)
Mutual labels:  composition-api
vue3-demo
💡 vue3新特性示例: 响应式API、组合式API、TodoMVC
Stars: ✭ 114 (+850%)
Mutual labels:  composition-api
vue-next-rx
RxJS integration for Vue next
Stars: ✭ 31 (+158.33%)
Mutual labels:  composition-api
nuxt-realworld
🛠 Built a Example App of RealWorld with Nuxt & Composition API ⚗️
Stars: ✭ 127 (+958.33%)
Mutual labels:  composition-api
goldfish
A development framework for Alipay Mini Program.
Stars: ✭ 69 (+475%)
Mutual labels:  composition-api
vuex-composition-api
www.npmjs.com/package/vuex-composition-api
Stars: ✭ 23 (+91.67%)
Mutual labels:  composition-api
Vue3 News
🔥 Find the latest breaking Vue3、Vue CLI 3+ & Vite News. (2021)
Stars: ✭ 2,416 (+20033.33%)
Mutual labels:  composition-api
vue3-form-validation
Vue Composition Function for Form Validation
Stars: ✭ 18 (+50%)
Mutual labels:  composition-api
vue-tiny-validate
💯 Tiny Vue Validate Composition
Stars: ✭ 80 (+566.67%)
Mutual labels:  composition-api
v-intl
Add i18n to your awesome Vue 3 app 🔉
Stars: ✭ 13 (+8.33%)
Mutual labels:  composition-api
vue-unstated
A tiny state management library for Vue Composition API.
Stars: ✭ 30 (+150%)
Mutual labels:  composition-api
vue-snippets
Visual Studio Code Syntax Highlighting For Vue3 And Vue2
Stars: ✭ 25 (+108.33%)
Mutual labels:  composition-api
vue-reuse
基于composition-api的hooks函数库
Stars: ✭ 28 (+133.33%)
Mutual labels:  composition-api
webneko-blog
✍️ Technical Blog written by @jiyuujin
Stars: ✭ 14 (+16.67%)
Mutual labels:  composition-api
vesselize
⛵ A JavaScript IoC container that works seamlessly with Vue.js and React.
Stars: ✭ 22 (+83.33%)
Mutual labels:  composition-api
v-bucket
📦 Fast, Simple, and Lightweight State Manager for Vue 3.0 built with composition API, inspired by Vuex.
Stars: ✭ 42 (+250%)
Mutual labels:  composition-api
2019-ncov-vue3-version
新型冠状病毒实时疫情 Vue-Compostion-Api版本 (Vue3 + TypeScript)
Stars: ✭ 55 (+358.33%)
Mutual labels:  composition-api
vue3-realworld-example-app
Explore the charm of Vue composition API! Vite?
Stars: ✭ 364 (+2933.33%)
Mutual labels:  composition-api
v-pip
🖼 Tiny vue wrapper for supporting native picture-in-picture mode.
Stars: ✭ 30 (+150%)
Mutual labels:  composition-api

vuex-hooks

npm version License: MIT Build Status Coverage Status Maintainability

This package offers TypeScript enabled vuex composition-api hooks, closing the gap between vuex and the @vue/composition-api.

Installation

Install the package using your package manager of choice:

npm i vuex-hooks or yarn add vuex-hooks

Then install the plugin in your entry point before instantiating vue:

import Vue from 'vue'
import CompositionApi from '@vue/composition-api'
import VuexHooks from 'vuex-hooks'

Vue.use(CompositionApi)
Vue.use(VuexHooks)
...

new Vue(...)

Usage

You can use the plugin in your composition functions or vue components.

<script>
import { defineComponent } from '@vue/composition-api'
import { useStore, useState, useActions, useMutations, useGetters } from 'vuex-hooks'

export default defineComponent({
    name: 'MyApp',
    setup() {
        const Store = useStore()
        const { supportedLocales } = useState('locales')
        const { SET_LOCALE } = useMutations('locales')
        const { getLocales } = useActions('locales')
        const { currentLocale } = useGetters('locales')

        ...
    }
})
<script>

Although the api appears similar to the vuex helpers - mapState, mapActions, mapGetters and mapMutations, you do not need to pass a second "mapping" argument of the desired keys. That is, when you use the native vuex helpers you would usually do something like this:

computed: {
    ...mapState('locales', ['currentLocale'])
}

This is not required here, just give the module name as the only argument and then destructure what is needed from the returned value.

If you want to remap names, do this:

const { SET_LOCALE: setLocale } = useMutations('locales')

The vuex helpers are being called under the hood by the hooks, and they are being given the entire module's keys. So when you choose a module called locales inside the useState helper for example, all locales' module state entries are returned. This sounds inefficent, but is in fact a bit more efficent than the regular implementation because the hooks use memoization.

Computed Refs and Methods

The useState and useGetters hooks return computed readonly refs, thus to access their value inside the setup function you should use .value:

setup() {
    ...
    if (currentLocale.value.lang === 'en') {
        ...
    }
    ...
}

useActions and useMutations return regular functions:

setup() {
    ...
    if (currentLocale.value.lang === 'en') {
        ...
    } else {
        getLocales()
    }
    ...
}

useStore returns the main store object that is attached to the vue instance.

TypeScript Support

When using TypeScript typing is optional but is of course highly recommended. To use typing, you should use either a ts/tsx file or a vue file with the correct script header, and then pass an interface as a generic argument to the respective hook.

Lets assume you defined some interfaces like so in a types.ts file:

export type Locale = { lang: string; id: number }

export interface LocalesState {
	supportedLocales: Locale[]
	currentLocaleId: number
}

export interface LocalesGetters {
	currentLocale: () => Locale
}

export interface LocalesActions {
	getLocales: () => Promise<Locale[]>
}

export interface LocalesMutations {
	SET_LOCALE: (payload: Locale) => void
}

export interface RootState {
	locales: LocalesState
}

You can then use these in the hooks to get type checking and inference:

<script lang="ts">
import {
    LocalesState,
    LocalesGetters,
    LocalesActions,
    LocalesMutations,
    RootState,
} from './types'
import { defineComponent } from '@vue/composition-api'
import { useStore, useState, useActions, useMutations, useGetters } from 'vuex-hooks'

export default defineComponent({
    name: 'MyApp',
    setup() {
        const Store = useStore<RootState>() // Store<RootState>
        const { supportedLocales } = useState<LocalesState>('locales') // Readonly<Ref<Locale>>
        const { currentLocale } = useGetters<LocalesGetters>('locales') // Readonly<Ref<Locale>>
        const { SET_LOCALE } = useMutations<LocalesMutations>('locales') // (payload: Locale) => void
        const { getLocales } = useActions<LocalesActions>('locales') // () => Promise<Locale[]>
        ...
    }
})
</script>

Doing this will result in the return values being correctly typed, so for example supportedLocales will be typed as Readonly<Ref<Locale>>.

You can also use the typings of a module directly. Lets assume there is a module that looks like so:

interface User {
    id: number
    name: string
    email: sring
    company: string
}
interface UserState {
    allUsers: User[]
    currentUserId: number | null
}
const state: UserState = {
	users: [],
	currentUserId: null,
}

export default {
	namespaced: true,
	state,
	actions: {
		async getUsers(ctx: ActionContext<UserState, any>): Promise<void> {
            try {
                const response = await api.get('myapi/users/')
                ctx.commit('SET_USERS', response.data)
            } catch(error) {
                ...
            }
        },
        async updateUser(ctx: ActionContext<UserState, any>, payload: Partial<User>): Promise<void | User> {
            try {
                const userId = ctx.state.currentUserId
                const response = await api.patch(`myapi/users/${userId}/`)
                return response.data
            } catch(error) {
                ...
            }
        }
    },
    getters: {
        getUserById(state: UserState) => (id: number): User | undefiend {
            return state.users.find(user => user.id === id)
        }
    },
    mutations: {
        SET_USERS(state: UserState, payload: User[]): void {
            state.users = payload
        },
    }
}

Obviously you already have typings in this case, and you can use these:

<script lang="ts">
import { defineComponent } from '@vue/composition-api'
import { useState, useActions, useMutations, useGetters } from 'vuex-hooks'
import UsersStore from './store'

export default defineComponent({
    name: 'MyApp',
    setup() {
        const { currentUserId } = useState<typeof UsersStore['state']>('users') // ReadOnly<Ref<number | null>>
        const { updateUser } = useGetters<typeof UsersStore['getters']>('users') // ReadOnly<Ref<(id: number) => User | undefiend>>
        const { SET_USERS } = useMutations<typeof UsersStore['mutations']>('users') // (payload: User[]) => void
        const { getUserById } = useActions<typeof UsersStore['actions']>('users') // (payload: Partial<User>) => Promise<void | User>
        ...
    }
})
</script>

The plugin remaps the typings and strips the vuex specific arguments from actions and mutations, so for example updateUser will not be inferred as (ctx: ActionContext<UserState, any>, payload: Partial<User>) => Promise<void | User> but rather as (payload: Partial<User>) => Promise<void | User>. It also returns correctly curried functions from getters.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].