|
| 1 | +import { getWatcher, getDep } from './util' |
| 2 | + |
1 | 3 | export default function (Vue) { |
2 | 4 | // override init and inject vuex init procedure |
3 | 5 | const _init = Vue.prototype._init |
@@ -38,28 +40,58 @@ export default function (Vue) { |
38 | 40 | if (getters) { |
39 | 41 | options.computed = options.computed || {} |
40 | 42 | for (let key in getters) { |
41 | | - options.computed[key] = makeBoundGetter(getters[key]) |
| 43 | + defineVuexGetter(this, key, getters[key]) |
42 | 44 | } |
43 | 45 | } |
44 | 46 | // actions |
45 | 47 | if (actions) { |
46 | 48 | options.methods = options.methods || {} |
47 | 49 | for (let key in actions) { |
48 | | - options.methods[key] = makeBoundAction(actions[key]) |
| 50 | + options.methods[key] = makeBoundAction(actions[key], this.$store) |
49 | 51 | } |
50 | 52 | } |
51 | 53 | } |
52 | 54 | } |
53 | 55 |
|
54 | | - function makeBoundGetter (getter) { |
55 | | - return function vuexBoundGetter () { |
56 | | - return getter.call(this, this.$store.state) |
| 56 | + function defineVuexGetter (vm, key, getter) { |
| 57 | + Object.defineProperty(vm, key, { |
| 58 | + enumerable: true, |
| 59 | + configurable: true, |
| 60 | + get: makeComputedGetter(vm.$store, getter) |
| 61 | + }) |
| 62 | + } |
| 63 | + |
| 64 | + function makeComputedGetter (store, getter) { |
| 65 | + const id = store._getterCacheId |
| 66 | + // cached |
| 67 | + if (getter[id]) { |
| 68 | + return getter[id] |
| 69 | + } |
| 70 | + const vm = store._vm |
| 71 | + const Watcher = getWatcher(vm) |
| 72 | + const Dep = getDep(vm) |
| 73 | + const watcher = new Watcher( |
| 74 | + vm, |
| 75 | + state => getter(state), |
| 76 | + null, |
| 77 | + { lazy: true } |
| 78 | + ) |
| 79 | + const computedGetter = () => { |
| 80 | + if (watcher.dirty) { |
| 81 | + watcher.evaluate() |
| 82 | + } |
| 83 | + if (Dep.target) { |
| 84 | + watcher.depend() |
| 85 | + } |
| 86 | + return watcher.value |
57 | 87 | } |
| 88 | + getter[id] = computedGetter |
| 89 | + return computedGetter |
58 | 90 | } |
59 | 91 |
|
60 | | - function makeBoundAction (action) { |
| 92 | + function makeBoundAction (action, store) { |
61 | 93 | return function vuexBoundAction (...args) { |
62 | | - return action.call(this, this.$store, ...args) |
| 94 | + return action.call(this, store, ...args) |
63 | 95 | } |
64 | 96 | } |
65 | 97 |
|
|
0 commit comments