Skip to content
This repository has been archived by the owner on Jun 9, 2019. It is now read-only.

Commit

Permalink
feat: vuex support
Browse files Browse the repository at this point in the history
  • Loading branch information
JackuB committed Feb 23, 2017
1 parent d1708ad commit 22b8d27
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 1 deletion.
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ A minimalistic framework for demonstrating your Vue components, inspired by [rea
* [Loading Scenarios Dynamically](#loading-scenarios-dynamically)
* [Register Components](#register-components)
* [Use Component as `play()` argument](#use-component-as-play-argument)
* [Using with Vuex](#using-with-vuex)
- [Component Shorthand](#component-shorthand)
- [Additional Component Properties](#additional-component-properties)
* [example](#example)
Expand Down Expand Up @@ -221,6 +222,54 @@ play(MyButton)
.add('with text', '<my-other-button>text</my-other-button>')
```

### Using with [Vuex](https://github.com/vuejs/vuex)

If your component is using [Vuex](https://github.com/vuejs/vuex) data store, you can pass store as an argument for a full component, just like you would in a normal Vue instance.

First, load Vuex in your `./play/index.js` file:

```js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
```

And then pass a Vuex Store instance like so:

```js
import Vuex from 'vuex'

play('Monster', module)
.add('mutating tentacle monster', {
store: new Vuex.store({
state: {
type: 'TENTACLE_MONSTER',
tentacles: 12
},
getters: {
attack: state => tentacles * TENTACLE_DAMAGE
},
mutations: {
mutateTentacle(state, mutagenStrength) {
state.tentacles = state.tentacles * mutagenStrength
}
},
actions: {
mutateTentacle({ commit }, data) {
asyncServerOperation(data, (err, mutagenStrength) => {
commit('mutateTentacle', mutagenStrength)
})
}
}
}),
render(h) {}
// ...
})
```

You can use multiple Vuex Store instances. State always resets to the initial value when you switch between scenarios.

## Component Shorthand

If you only need `template` or `render` property for your component, you can use `component shorthand`, which means you can directly set the value of scenario to a template string or render function:
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"dependencies": {
"array-find-index": "^1.0.2",
"highlight.js": "^9.8.0",
"lodash": "^4.17.4",
"query-string": "^4.2.3",
"uid": "0.0.2",
"vue-router": "^2.0.3",
Expand Down
27 changes: 27 additions & 0 deletions play/Storage-counter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<template>
<div>
<p>{{ count }}</p>
<p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</p>
</div>
</template>

<script>
export default {
computed: {
count () {
return this.$store.state.count
}
},
methods: {
increment () {
this.$store.commit('increment')
},
decrement () {
this.$store.commit('decrement')
}
}
}
</script>
13 changes: 13 additions & 0 deletions play/Storage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<p>This component is <strong v-if="!enabled">not</strong> using Vuex</p>
</template>

<script>
export default {
computed: {
enabled() {
return (this.$store.state.enabled === true && this.$store.getters.isAlive === true) ? true : false
}
}
}
</script>
5 changes: 5 additions & 0 deletions play/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import Vue from 'vue'
import Vuex from 'vuex'

import MyButton from './MyButton.vue'
import Box from './Box.vue'

Vue.use(Vuex)

const load = requireContext => {
return requireContext.keys().map(requireContext)
}
Expand Down
33 changes: 33 additions & 0 deletions play/storage.play.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Vuex from 'vuex'
import {play} from '../src/play'
import Storage from './Storage.vue'
import StorageCounter from './Storage-counter.vue'

play('Storage', module)
.add('static', {
store: new Vuex.Store({
state: {
enabled: true
},
getters: {
isAlive: s => s.enabled
}
}),
render(h) {
return h(Storage)
}
})
.add('counter', {
store: new Vuex.Store({
state: {
count: 0
},
mutations: {
increment: state => state.count++,
decrement: state => state.count--
}
}),
render(h) {
return h(StorageCounter)
}
})
15 changes: 14 additions & 1 deletion src/preview.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Vue from 'vue'
import qs from 'query-string'
import get from 'lodash/get'
import findScenario from './utils/find-scenario'
import filterVuex from './utils/filter-vuex'
import {parseKey} from './utils/key-events'
import {getSpots} from './play'

Expand Down Expand Up @@ -33,6 +35,12 @@ export default function () {
const scenario = findScenario(spots, data.payload)
if (scenario) {
this.current = scenario.component

// Handle Vuex state if found
// If we have a cached initial state, use that
if (get(this.current, 'store.constructor.name') === 'Store' && this.current._initialState) {
this.current.store.replaceState(JSON.parse(this.current._initialState))
}
}
}
})
Expand All @@ -44,10 +52,15 @@ export default function () {
}
parent.postMessage({
type: 'SET_SPOTS',
payload: JSON.stringify(spots)
payload: JSON.stringify(spots, filterVuex)
}, location.origin)
},
render(h) {
// Save original store state on the first render
if (get(this.current, 'store.constructor.name') === 'Store' && !this.current._initialState) {
this.current._initialState = JSON.stringify(this.current.store.state)
}

return h('div', {attrs: {id: 'app'}}, [h(this.current)])
}
})
Expand Down
10 changes: 10 additions & 0 deletions src/utils/filter-vuex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Replacer function for JSON.stringify to filter Vuex instance from the tree
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
import get from 'lodash/get'

export default (key, value) => {
if (key === 'store' && get(value, 'constructor.name') === 'Store') {
return undefined
}
return value
}

0 comments on commit 22b8d27

Please sign in to comment.