Skip to content

pruge/vuex-service

Repository files navigation

vuex-service

Coverage Status

npm vue2

❗ Use vuex like angular service

const Root = this.$$store()
const Todo = this.$$store('Todo')
const {Member, Todo} = this.$$store('Todo, Member')
// import { Store } from 'vuex-service'
// const Todo = Store('Todo', store) // store is vuex store isntance
Todo.todos // state
Todo.all // getters
Todo.active
Todo.completed
Todo.update() // actions
Todo.m.update() // mutations

❗ EventBus

const Todo = this.$$store('Todo')
Todo.$on('hello.*', fn)
Todo.$on(this, 'hello.*', fn) // auto unregister, when vue component destoryed
Todo.$emit('hello.world', data)
Todo.$once('hello.world', fn)
Todo.$broadcast('hello.world', data)
Todo.$off('hello.world', fn)
Todo.$off('hello.world') // remove all

❗ Multiple arguments

// this.$store.dispatch('Todo/update', arg1)
Todo.update(arg1)
update({ commit }, name) {
  console.log(name)
}
// this.$store.dispatch('Todo/update', [ arg1, arg2, ... ])
Todo.update(arg1, arg2, ...)
update({ commit }, [ name, name2, ... ]) {
  console.log(name, name2, ...)
}

❗ Hook

The default setting is off.

Please read the following library for further instructions.
https://www.npmjs.com/package/hooks

Vue.use(vuexService, {hook: true})  // default hook = false

// action this.$store.dispatch('Todo/add', data)
const Todo = this.$$store('Todo')
Todo.hook('add', Todo.add)
Todo.pre('add', next => {
  console.log('hook pre action', Todo.todos)
  next()
})
Todo.post('add', next => {
  console.log('hook post action', Todo.todos)
  next()
})

Todo.add({title: 'hello', completed: false})

// will print
// hook pre action []
// hook post action [{...}]


// mutation this.$store.commit('Todo/add', data)
const Todo = this.$$store('Todo')
Todo.hook('m.add', Todo.m.add)
Todo.pre('m.add', next => {
  console.log('hook pre mutation', Todo.todos)
  next()
})
Todo.post('m.add', next => {
  console.log('hook post mutation', Todo.todos)
  next()
})

Todo.m.add('todos', {title: 'hello', completed: false})

// will print
// hook pre mutation []
// hook post mutation [{...}]

Getting Started

NPM

$ npm install vuex-service

Yarn

$ yarn add vuex-service

When used with a module system, you must explicitly install the vuex-service via Vue.use():

// ~/plugins/vuex-service.js
import Vue from 'vue'
import vuexService, { Store } from 'vuex-service'

Vue.use(vuexService, {hook: true})  // default hook = false

// nuxt
export default ({ app }, inject) => {
  inject('$store', Store)
}

how to use

store actions

// ~/store/Todo.js
import { defaultMutations } from 'vuex-service'

export const state = () => ({
  todos: [],
  hello: {
    world: '123'
  }
})

export const getters = {
  all (state) {
    return state.todos
  },
  active (state) {
    return state.todos.filter(todo => !todo.completed)
  },
  completed (state) {
    return state.todos.filter(todo => todo.completed)
  }
}

export const mutations = {
  ...defaultMutations // set, add, update, remove
}

export const actions = {
  add ({ commit }, todo) {
    const Todo = this.$$store('Todo')
    // commit('Todo/add', [ 'todos', todo ])
    Todo.m.add('todos', todo)
  },
  update ({ commit }, [ todo, patch ]) {
    const Todo = this.$$store('Todo')
    // commit('Todo/update', [ todo, patch ])
    Todo.m.update(todo, patch)
  }
}

vue component

export default {
  computed: {
    todos () {
      const Todo = this.$$store('Todo')
      const filter = this.$route.params.slug || 'all'
      // this.$store.getters['Todo/' + filter]
      return Todo[filter]
    }
  },
  methods: {
    doneCheck (todo, e) {
      const Todo = this.$$store('Todo')
      const data = [ todo, {completed: e.target.checked} ]
      // this.dispatch('Todo/update', data)
      Todo.update(data)
      // or
      // this.dispatch('Todo/update', [ todo, {completed: e.target.checked} ])
      Todo.update(todo, {completed: e.target.checked})
      // or
      Todo.m.update(todo, { completed: e.target.checked })
    },
  }
}

vuex store instance

// ~/store/Locale.js
import { defaultMutations } from 'vuex-service'

export const state = () => ({
  locales: ['en', 'kr'],
  locale: 'en'
})
export const mutations = {
  ...defaultMutations // set, add, update, remove
}

// ~/middleware/i18n.js
import { Store } from 'vuex-service'
export default function ({ isHMR, app, store, route, params, error, redirect }) {
  const Locale = Store('Locale', store)
  console.log(Locale.locales, Locale.locale)
  ...
}

default mutations - set, add, remove, update

// ~/store/Todo.js
import { defaultMutations } from 'vuex-service'

export const state = () => ({
  todos: [],
  hello: {
    world: '123',
    heart: []
  }
})
export const mutations = {
  ...defaultMutations // set, add, update, remove
}
  1. set (prop, value)
const Todo = this.$$store('Todo')
// Todo.m.set(prop, value)
Todo.m.set('todos', [{title: 'todo', completed: false}])
Todo.m.set('hello.world', 'abc') // abc
Todo.m.set('hello.heart', ['two', 'three']) // [two, three]
  1. add (prop, value)
const Todo = this.$$store('Todo')
// Todo.m.add(prop, value)
Todo.m.add('todos', {title: 'todo', completed: false})
Todo.m.add('hello.heart', 'one') // [one]
Todo.m.add('hello.heart', ...['two', 'three']) // [one, two, three]
  1. remove (prop, value)
const Todo = this.$$store('Todo')
// Todo.m.remove(prop, value)
Todo.m.add('todos', {title: 'todo', completed: false})
const todo = Todo.todos[0]
Todo.m.remove('todos', todo) // []
  1. update (src, patch)
const Todo = this.$$store('Todo')
// Todo.m.update(src, patch)
// if src is string, call m.set(prop, value)
Todo.m.update('todos', {title: 'todo', completed: false})
Todo.m.update('hello.heart', 'one') // [one]
Todo.m.update('hello.heart', ['two', 'three'])  // [two, three]
// or
Todo.m.add('todos', {title: 'hi', completed: false})
const todo = Todo.todos[0]
Todo.m.update(todo, {title: 'hello world'}) // 'hi' --> 'hello world'

When you call custom action/mutations

// If two parameters and more
// deprecated
// Todo.update(arg1, arg2) === this.$store.dispatch('Todo/update', {src: arg1, prop: arg1, value: arg2})
// Todo.m.update(arg1, arg2) === this.$store.commit('Todo/update', {src: arg1, prop: arg1, value: arg2})

// changed
// this.$store.dispatch('Todo/update', arg1)
Todo.update(arg1)
update({ commit }, name) {
  console.log(name)
}
// this.$store.dispatch('Todo/update', [ arg1, arg2, ... ])
Todo.update(arg1, arg2, ...)
update({ commit }, [ name, name2, ... ]) {
  console.log(name, name2, ...)
}
// ~/store/Todo.js
import { defaultMutations } from 'vuex-service'

export const state = () => ({
  todos: [],
  hello: {
    world: '123',
    heart: []
  }
})
export const mutations = {
  ...defaultMutations // set, add, update, remove
}
export const actions = {
  update ({ commit }, [ todo, patch ]) {
    const Todo = this.$$store('Todo')
    // commit('Todo/update', [ todo, patch ])
    Todo.m.update(todo, patch)
  }
}
// ~/components/list.vue
export default {
  methods {
    doneCheck (todo, e) {
      const Todo = this.$$store('Todo')
      const data = [ todo, {completed: e.target.checked} ]
      Todo.update(data) // this.dispatch('Todo/update', data)
      // or
      Todo.update(todo, {completed: e.target.checked}) // this.dispatch('Todo/update', [ todo, {completed: e.target.checked} ])
    }
  }
}

module

// ~/store   : nuxt
store
  ├── Todo
      └── comments.js
  ├─ Todo.js
  └─ index.js

const Root = this.$$store()
const Todo = this.$$store('Todo')
const comments = this.$$store('Todo/comments')
const { Root, Todo } = this.$$store(' , Todo')
const { Todo, comments } = this.$$store('Todo, Todo/comments')

eventbus

const { Todo, Member } = this.$$store('Todo, Member')

Todo.$on('hello', message => console.log('Todo: ' + message))
Member.$on('hello', message => console.log('Member: ' + message))

Todo.$emit('hello', 'hi')
// Todo: hi

Member.$emit('hello', 'hi')
// Member: hi

Todo.$broadcast('hello', 'hi')
// Todo: hi
// Member: hi

Todo.$on('hello.*', message => console.log('Todo * : ' + message))
Todo.$emit('hello.world', 'hi')
// Todo * : hi

eventbus auto unregister

Alternatively, you can pass a vue scope as the first parameter to on() or once() and the listener will be automatically unregistered if the vue scope is destroyed.

// Passing this will register a this.$on('hook:beforeDestroy) event for you.
// ~/components/todoList.vue
Todo.$on(this, 'hello', fn)
Todo.$once(this, 'hello', fn)

📜 Changelog

v0.3.10

  • cache vuexService

v0.3.0

  • add hooks

v0.2.0

  • change arguments of two or more function arguments

v0.1.5

  • support event bus

v0.1.0

  • support vuex like service

❗ Issues

Please make sure to read the Issue Reporting Checklist before opening an issue. Issues not conforming to the guidelines may be closed immediately.

💪 Contribution

Please make sure to read the Contributing Guide before making a pull request.

©️ License

MIT

About

vuex extend like angular service

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published