10000 basic counter example working · padcom/vuejs.org@25e0f1e · GitHub
[go: up one dir, main page]

Skip to content

Commit 25e0f1e

Browse files
committed
basic counter example working
1 parent 1b2845c commit 25e0f1e

File tree

11 files changed

+159
-66
lines changed

11 files changed

+159
-66
lines changed

build/build.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,6 @@ rollup.rollup({
3737
}).code
3838
return write('dist/vuex.min.js', minified)
3939
})
40-
.then(function () {
41-
return rollup.rollup({
42-
entry: 'src/plugins/logger.js',
43-
plugins: [babel()]
44-
}).then(function (bundle) {
45-
return write('logger.js', bundle.generate({
46-
format: 'cjs'
47-
}).code)
48-
})
49-
})
5040
.catch(logError)
5141

5242
function write (dest, code) {

build/dev-entry.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('../src').default

examples/counter/Counter.vue

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99
</template>
1010

1111
<script>
12-
import * as actions from './actions'
12+
import { mapGetters, mapActions } from 'vuex'
1313
1414
export default {
15-
vuex: {
16-
getters: {
17-
count: state => state.count
18-
},
19-
actions: actions
20-
}
15+
computed: mapGetters(['co 341A unt']),
16+
methods: mapActions([
17+
'increment',
18+
'decrement',
19+
'incrementIfOdd',
20+
'incrementAsync'
21+
])
2122
}
2223
</script>

examples/counter/actions.js

Lines changed: 0 additions & 14 deletions
This file was deleted.

examples/counter/store.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Vue from 'vue'
2-
import Vuex from '../../src'
2+
import Vuex from 'vuex'
33

44
Vue.use(Vuex)
55

@@ -15,19 +15,38 @@ const state = {
1515
// mutations must be synchronous and can be recorded by plugins
1616
// for debugging purposes.
1717
const mutations = {
18-
INCREMENT (state) {
18+
increment (state) {
1919
state.count++
2020
},
21-
DECREMENT (state) {
21+
decrement (state) {
2222
state.count--
2323
}
2424
}
2525

26+
const actions = {
27+
increment: ({ dispatch }) => dispatch('increment'),
28+
decrement: ({ dispatch }) => dispatch('decrement'),
29+
incrementIfOdd ({ dispatch, state }) {
30+
if ((state.count + 1) % 2 === 0) {
31+
dispatch('increment')
32+
}
33+
},
34+
incrementAsync ({ dispatch, state }) {
35+
setTimeout(() => {
36+
dispatch('increment')
37+
}, 1000)
38+
}
39+
}
40+
2641
// A Vuex instance is created by combining the state, the actions,
2742
// and the mutations. Because the actions and mutations are just
2843
// functions that do not depend on the instance itself, they can
2944
// be easily tested or even hot-reloaded (see counter-hot example).
3045
export default new Vuex.Store({
3146
state,
47+
getters: {
48+
count: state => state.count
49+
},
50+
actions,
3251
mutations
3352
})

examples/webpack.build-all.config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
var path = require('path')
2+
13
var examples = [
24
'chat',
35
'counter',
@@ -17,6 +19,11 @@ module.exports = {
1719
path: __dirname,
1820
filename: '[name]/build.js'
1921
},
22+
resolve: {
23+
alias: {
24+
vuex: path.resolve(__dirname, '../build/dev-entry')
25+
}
26+
},
2027
module: {
2128
loaders: [
2229
{

examples/webpack.shared.config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
var path = require('path')
2+
13
module.exports = {
24
entry: './main.js',
35
output: {
46
path: process.cwd(),
57
filename: 'build.js'
68
},
9+
resolve: {
10+
alias: {
11+
vuex: path.resolve(__dirname, '../build/dev-entry')
12+
}
13+
},
714
module: {
815
loaders: [
916
{

src/helpers.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export function mapGetters (getters) {
2+
const res = {}
3+
normalizeMap(getters).forEach(({ key, val }) => {
4+
res[key] = function () {
5+
return this.$store.getters[val]
6+
}
7+
})
8+
return res
9+
}
10+
11+
export function mapActions (actions) {
12+
const res = {}
13+
normalizeMap(actions).forEach(({ key, val }) => {
14+
res[key] = function () {
15+
return this.$store.call(val)
16+
}
17+
})
18+
return res
19+
}
20+
21+
function normalizeMap (map) {
22+
return Array.isArray(map)
23+
? map.map(key => ({ key, val: key }))
24+
: Object.keys(map).map(key => ({ key, val: map[key] }))
25+
}

src/index.js

Lines changed: 88 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import devtoolPlugin from './plugins/devtool'
2-
import strictPlugin from './plugins/strict'
32
import applyMixin from './mixin'
3+
import { mapGetters, mapActions } from './helpers'
44

55
let Vue // bind on install
66

@@ -38,24 +38,18 @@ class Store {
3838
this.call = bind(this.call, this)
3939
this.dispatch = bind(this.dispatch, this)
4040

41-
// use a Vue instance to store the state tree
42-
// suppress warnings just in case the user has added
43-
// some funky global mixins
44-
const silent = Vue.config.silent
45-
Vue.config.silent = true
46-
this._vm = new Vue({ data: { state }})
47-
Vue.config.silent = silent
41+
// init state and getters
42+
extractModuleGetters(getters, modules)
43+
initStoreState(this, state, getters)
4844

4945
// apply root module
5046
this.module([], options)
5147

48+
// strict mode
49+
if (strict) enableStrictMode(this)
50+
5251
// apply plugins
53-
plugins = plugins.concat(
54-
strict
55-
? [devtoolPlugin, strictPlugin]
56-
: [devtoolPlugin]
57-
)
58-
plugins.forEach(plugin => plugin(this))
52+
plugins.concat(devtoolPlugin).forEach(plugin => plugin(this))
5953
}
6054

6155
get state () {
@@ -88,7 +82,7 @@ class Store {
8882

8983
// set state
9084
if (!isRoot && !hot) {
91-
const parentState = get(this.state, path.slice(-1))
85+
const parentState = getNestedState(this.state, path.slice(-1))
9286
const moduleName = path[path.length - 1]
9387
Vue.set(parentState, moduleName, state || {})
9488
}
@@ -117,7 +111,7 @@ class Store {
117111
entry.push(payload => {
118112
handler(getNestedState(this.state, path), payload)
119113
})
120-
},
114+
}
121115

122116
action (type, handler, path = []) {
123117
const entry = this._actions[type] || (this._actions[type] = [])
@@ -153,7 +147,7 @@ class Store {
153147
this._dispatching = true
154148
entry.forEach(handler => handler(payload))
155149
this._dispatching = false
156-
this._subscribers.forEach(sub => sub(mutation, state))
150+
this._subscribers.forEach(sub => sub(mutation, this.state))
157151
}
158152

159153
call (type, payload, cb) {
@@ -177,14 +171,14 @@ class Store {
177171
subs.push(fn)
178172
}
179173
return () => {
180-
let i = subs.indexOf(fn)
174+
const i = subs.indexOf(fn)
181175
if (i > -1) {
182176
subs.splice(i, 1)
183177
}
184178
}
185179
}
186180

187-
update (newOptions) {
181+
hotUpdate (newOptions) {
188182
this._actions = Object.create(null)
189183
this._mutations = Object.create(null)
190184
const options = this._options
@@ -200,11 +194,82 @@ class Store {
200194
}
201195
}
202196
this.module([], options, true)
197+
198+
// update getters
199+
const getters = extractModuleGetters(newOptions.getters || {}, newOptions.modules)
200+
if (Object.keys(getters).length) {
201+
const oldVm = this._vm
202+
initStoreState(this, this.state, getters)
203+
if (this.strict) {
204+
enableStrictMode(this)
205+
}
206+
// trigger changes in all subscribed watchers
207+
// to force getter re-evaluation.
208+
this._dispatching = true
209+
oldVm.state = null
210+
this._dispatching = false
211+
Vue.nextTick(() => oldVm.$destroy())
212+
}
203213
}
204214
}
205215

216+
function initStoreState (store, state, getters) {
217+
// bind getters
218+
store.getters = {}
219+
const computed = {}
220+
Object.keys(getters).forEach(key => {
221+
const fn = getters[key]
222+
// use computed to leverage its lazy-caching mechanism
223+
computed[key] = () => fn(store._vm.state)
224+
Object.defineProperty(store.getters, key, {
225+
get: () => store._vm[key]
226+
})
227+
})
228+
229+
// use a Vue instance to store the state tree
230+
// suppress warnings just in case the user has added
231+
// some funky global mixins
232+
const silent = Vue.config.silent
233+
Vue.config.silent = true
234+
store._vm = new Vue({
235+
data: { state },
236+
computed
237+
})
238+
Vue.config.silent = silent
239+
}
240+
241+
function extractModuleGetters (getters, modules, path = []) {
242+
if (!modules) return
243+
Object.keys(modules).forEach(key => {
244+
const module = modules[key]
245+
if (module.getters) {
246+
Object.keys(module.getters).forEach(getterKey => {
247+
const rawGetter = module.getters[getterKey]
248+
if (getters[getterKey]) {
249+
console.warn(`[vuex] duplicate getter key: ${getterKey}`)
250+
return
251+
}
252+
getters[getterKey] = state => rawGetter(getNestedState(state, path))
253+
})
254+
}
255+
extractModuleGetters(getters, module.modules, path.concat(key))
256+
})
257+
}
258+
259+
function enableStrictMode (store) {
260+
store._vm.watch('state', () => {
261+
if (!store._dispatching) {
262+
throw new Error(
263+
'[vuex] Do not mutate vuex store state outside mutation handlers.'
264+
)
265+
}
266+
}, { deep: true, sync: true })
267+
}
268+
206269
function bind (fn, ctx) {
207-
return () => fn.apply(ctx, arguments)
270+
return function () {
271+
return fn.apply(ctx, arguments)
272+
}
208273
}
209274

210275
function isObject (obj) {
@@ -237,5 +302,7 @@ if (typeof window !== 'undefined' && window.Vue) {
237302

238303
export default {
239304
Store,
240-
install
305+
install,
306+
mapGetters,
307+
mapActions
241308
}

src/plugins/devtool.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default function devtoolPlugin (store) {
1111
store.replaceState(targetState)
1212
})
1313

14-
store.subscribe(mutation, state) => {
14+
store.subscribe((mutation, state) => {
1515
hook.emit('vuex:mutation', mutation, state)
1616
})
1717
}

0 commit comments

Comments
 (0)
0