Skip to content

Commit 540da66

Browse files
committed
add watch option
1 parent 664e59d commit 540da66

File tree

5 files changed

+94
-27
lines changed

5 files changed

+94
-27
lines changed

changes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ By default, all child components **DO NOT** inherit the parent scope. Only anony
102102
// -> goodbye!
103103
```
104104

105+
- #### new option: `watch`.
106+
107+
Similar to the new `events` option, the `watch` option accepts an object of expression/callback pairs. The instance will automatically call `$watch` for each entry in the object. You can also use a method name string instead of a callback.
108+
105109
- #### new option: `inherit`.
106110

107111
Default: `false`.

src/instance/events.js

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,63 @@ var _ = require('../util')
22
var inDoc = _.inDoc
33

44
/**
5-
* Setup the instance's option events.
5+
* Setup the instance's option events & watchers.
66
* If the value is a string, we pull it from the
77
* instance's methods by name.
88
*/
99

1010
exports._initEvents = function () {
1111
var options = this.$options
12-
var events = options.events
13-
var methods = options.methods
14-
if (events) {
15-
var handlers, e, i, j
16-
for (e in events) {
17-
handlers = events[e]
18-
if (_.isArray(handlers)) {
19-
for (i = 0, j = handlers.length; i < j; i++) {
20-
register(this, e, handlers[i], methods)
21-
}
22-
} else {
23-
register(this, e, handlers, methods)
12+
registerCallbacks(this, '$on', options.events)
13+
registerCallbacks(this, '$watch', options.watch)
14+
}
15+
16+
/**
17+
* Register callbacks for option events and watchers.
18+
*
19+
* @param {Vue} vm
20+
* @param {String} action
21+
* @param {Object} hash
22+
*/
23+
24+
function registerCallbacks (vm, action, hash) {
25+
if (!hash) return
26+
var handlers, key, i, j
27+
for (key in hash) {
28+
handlers = hash[key]
29+
if (_.isArray(handlers)) {
30+
for (i = 0, j = handlers.length; i < j; i++) {
31+
register(vm, action, key, handlers[i])
2432
}
33+
} else {
34+
register(vm, action, key, handlers)
2535
}
2636
}
2737
}
2838

2939
/**
30-
* Helper to register an event.
40+
* Helper to register an event/watch callback.
3141
*
3242
* @param {Vue} vm
33-
* @param {String} event
43+
* @param {String} action
44+
* @param {String} key
3445
* @param {*} handler
35-
* @param {Object|undefined} methods
3646
*/
3747

38-
function register (vm, event, handler, methods) {
48+
function register (vm, action, key, handler) {
3949
var type = typeof handler
4050
if (type === 'function') {
41-
vm.$on(event, handler)
51+
vm[action](key, handler)
4252
} else if (type === 'string') {
53+
var methods = vm.$options.methods
4354
var method = methods && methods[handler]
4455
if (method) {
45-
vm.$on(event, method)
56+
vm[action](key, method)
4657
} else {
4758
_.warn(
4859
'Unknown method: "' + handler + '" when ' +
49-
'registering callback for event: "' + event + '".'
60+
'registering callback for ' + action +
61+
': "' + key + '".'
5062
)
5163
}
5264
}

src/instance/init.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@ exports._init = function (options) {
6060
// set data after merge.
6161
this._data = options.data || {}
6262

63-
// setup event system and option events.
64-
this._initEvents()
65-
6663
// initialize data observation and scope inheritance.
6764
this._initScope()
6865

66+
// setup event system and option events.
67+
this._initEvents()
68+
6969
// call created hook
7070
this._callHook('created')
7171

src/util/merge-option.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,13 @@ strats.components = function (parentVal, childVal, vm, key) {
126126
}
127127

128128
/**
129-
* Events
129+
* Events & Watchers.
130130
*
131-
* Events should not overwrite one another, so we merge
132-
* them as arrays.
131+
* Events & watchers hashes should not overwrite one
132+
* another, so we merge them as arrays.
133133
*/
134134

135+
strats.watch =
135136
strats.events = function (parentVal, childVal) {
136137
if (!childVal) return parentVal
137138
if (!parentVal) return childVal

test/unit/specs/instance/events_spec.js

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe('Instance Events', function () {
1010
spyOn(_, 'warn')
1111
})
1212

13-
describe('events', function () {
13+
describe('option events', function () {
1414

1515
it('normal events', function () {
1616
var vm = new Vue({
@@ -52,6 +52,56 @@ describe('Instance Events', function () {
5252

5353
})
5454

55+
describe('option watchers', function () {
56+
57+
it('normal', function (done) {
58+
var spyA = jasmine.createSpy()
59+
var spyB = jasmine.createSpy()
60+
var vm = new Vue({
61+
watch: {
62+
'a.b.c': spyA,
63+
'b + c': spyB
64+
},
65+
data: {
66+
a: {
67+
b: { c: 1 }
68+
},
69+
b: 1,
70+
c: 2
71+
}
72+
})
73+
vm.a.b.c = 2
74+
vm.b = 3
75+
vm.c = 4
76+
_.nextTick(function () {
77+
expect(spyA).toHaveBeenCalledWith(2, 1)
78+
expect(spyB).toHaveBeenCalledWith(7, 3)
79+
done()
80+
})
81+
})
82+
83+
it('method name strings', function (done) {
84+
var spy = jasmine.createSpy()
85+
var vm = new Vue({
86+
watch: {
87+
'a': 'test'
88+
},
89+
data: {
90+
a: 1
91+
},
92+
methods: {
93+
test: spy
94+
}
95+
})
96+
vm.a = 2
97+
_.nextTick(function () {
98+
expect(spy).toHaveBeenCalledWith(2, 1)
99+
done()
100+
})
101+
})
102+
103+
})
104+
55105
describe('hooks', function () {
56106

57107
it('created', function () {

0 commit comments

Comments
 (0)