Skip to content
/ vue Public

Vue integration for Nano Stores, a tiny state manager with many atomic tree-shakable stores

License

Notifications You must be signed in to change notification settings

nanostores/vue

Repository files navigation

Nano Stores Vue

Vue integration for Nano Stores, a tiny state manager with many atomic tree-shakable stores.

  • Small. Less than 1 KB with all helpers. Zero dependencies.
  • Fast. With small atomic and derived stores, you do not need to call the selector function for all components on every store change.
  • Tree Shakable. The chunk contains only stores used by components in the chunk.
  • Helpers. Designed to keep code clean and save a few keystrokes.
  • Devtools. Plugin with full support of Vue Devtools.
  • Was designed to move logic from components to stores.
  • It has good TypeScript support.

Install

npm install @nanostores/vue

Usage

Store state

Subscribe to store changes and use reactive store state.

<template>
  <header>{{ post.title }} for {{ user.name }}</header>
</template>

<script>
  import { useStore } from '@nanostores/vue'
  import { profile } from '../stores/profile.js'
  import { Post } from '../stores/post.js'

  export default {
    setup (props) {
      const user = useStore(profile)
      const post = useStore(Post(props.postId))
      return { user, post }
    }
  }
</script>

Multiple store states

Generate multiple store states and save a few keystrokes.

<template>
  <header>{{ project.name }} / {{ user.name }}</header>
</template>

<script>
  import { mapStores } from '@nanostores/vue'
  import { project } from '../stores/project.js'
  import { user } from '../stores/user.js'

  export default {
    setup () {
      return {
        ...mapStores({ project, user })
      }
    }
  }
</script>

Form handling

Since the store state is deep read-only, you cannot directly mutate it. But for v-model you can create model via useVModel(store, keys, opts). It will explicitly mutate the store via store.set() / store.setKey().

<template>
  <input v-model="username"/>
</template>

<script>
  import { useVModel } from '@nanostores/vue'
  import { profile } from '../stores/profile.js'

  export default {
    setup () {
      const username = useVModel(profile, 'username')
      return { username }
    }
  }
</script>

The keys argument can be an array of keys to create multiple models. Each model will be prefixed with Model. You can change it via opts.prefix.

<template>
  <input v-model="firstNameModel"/>
  <input v-model="lastNameModel"/>
</template>

<script>
  import { useVModel } from '@nanostores/vue'
  import { profile } from '../stores/profile.js'

  export default {
    setup () {
      return {
        ...useVModel(profile, ['firstName', 'lastName'])
      }
    }
  }
</script>

Devtools

Nanostores Vue Devtools screenshot

Install

npm install --save-dev @vue/devtools-api

Usage

Store detector

Install Vue Devtools plugin as usual. It will detect nanostores in selected component and add their states to the component inspector.

import { createApp } from 'vue'
import { devtools } from '@nanostores/vue/devtools'

import { User } from '../stores/user.js'

const app = createApp()
app.use(devtools)

Notice: if you are using SSR, there is no Vue Devtools on server. Check it’s a browser environment:

if (window) app.use(devtools)

Attach stores to add them to the nanostores inspector and see their builds, lifecycles and changes on the timeline.

import { createApp } from 'vue'
import { devtools, attachStores } from '@nanostores/vue/devtools'

import { User } from '../stores/user.js'

const app = createApp()
app.use(devtools)

attachStores(app, { User })

You can connect several stores in different places of your application and set custom names to simplify the work with devtools.

attachStores(app, {
  'Current User': User,
  Post
})

For MapTemplate you can create a custom nameGetter to set suitable names for each store built from template.

attachStores(app, { User }, {
  nameGetter: (store, templateName) => {
    return `User:${store.get().id}`
  }
})

Settings

The states of all detected stores in component inspector are updated in real time. You can disable this in the the plugin settings via the Real-time update detected property.

By default, we removes unmounted stores from nanostores inspector to keep it clean. You can change this via the Keep unmounted property.