Skip to content

Commit e04553a

Browse files
committed
lifecycle hooks
1 parent 28a2c68 commit e04553a

File tree

9 files changed

+127
-56
lines changed

9 files changed

+127
-56
lines changed

examples/todomvc/js/app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var app = new Vue({
1515

1616
el: '#todoapp',
1717

18-
init: function () {
18+
created: function () {
1919
this.updateFilter()
2020
this.remaining = this.todos.filter(function (todo) {
2121
return !todo.completed

src/compiler.js

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function Compiler (vm, options) {
2929
// so we should not run any transitions
3030
compiler.init = true
3131

32-
// extend options
32+
// process and extend options
3333
options = compiler.options = options || makeHash()
3434
utils.processOptions(options)
3535
utils.extend(compiler, options.compilerOptions)
@@ -83,12 +83,13 @@ function Compiler (vm, options) {
8383
// setup observer
8484
compiler.setupObserver()
8585

86-
// call user init. this will capture some initial values.
87-
if (options.init) {
88-
options.init.apply(vm, options.args || [])
86+
// pre compile / created hook
87+
var created = options.beforeCompile || options.created
88+
if (created) {
89+
created.call(vm, options)
8990
}
9091

91-
// create bindings for keys set on the vm by the user
92+
// create bindings for things already in scope
9293
var key, keyPrefix
9394
for (key in vm) {
9495
keyPrefix = key.charAt(0)
@@ -122,6 +123,12 @@ function Compiler (vm, options) {
122123

123124
// done!
124125
compiler.init = false
126+
127+
// post compile / ready hook
128+
var ready = options.afterCompile || options.ready
129+
if (ready) {
130+
ready.call(vm, options)
131+
}
125132
}
126133

127134
var CompilerProto = Compiler.prototype
@@ -557,14 +564,18 @@ CompilerProto.destroy = function () {
557564

558565
var compiler = this,
559566
i, key, dir, instances, binding,
560-
el = compiler.el,
561-
directives = compiler.dirs,
562-
exps = compiler.exps,
563-
bindings = compiler.bindings,
564-
teardown = compiler.options.teardown
567+
vm = compiler.vm,
568+
el = compiler.el,
569+
directives = compiler.dirs,
570+
exps = compiler.exps,
571+
bindings = compiler.bindings,
572+
beforeDestroy = compiler.options.beforeDestroy,
573+
afterDestroy = compiler.options.afterDestroy
565574

566575
// call user teardown first
567-
if (teardown) teardown()
576+
if (beforeDestroy) {
577+
beforeDestroy.call(vm)
578+
}
568579

569580
// unwatch
570581
compiler.observer.off()
@@ -619,6 +630,11 @@ CompilerProto.destroy = function () {
619630
el.parentNode.removeChild(el)
620631
}, this)
621632
}
633+
634+
// post teardown hook
635+
if (afterDestroy) {
636+
afterDestroy.call(vm)
637+
}
622638
}
623639

624640
// Helpers --------------------------------------------------------------------

src/viewmodel.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ def(VMProto, '$emit', function () {
8080
parent = compiler.parentCompiler
8181
emitter.emit.apply(emitter, arguments)
8282
if (parent) {
83-
parent.emitter.emit.apply(parent.emitter, arguments)
8483
parent.vm.$emit.apply(parent.vm, arguments)
8584
}
8685
})

test/functional/fixtures/custom-element.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
},
3030
// private custom element with constructor
3131
wow: Vue.extend({
32-
init: function () {
32+
ready: function () {
3333
this.$el.textContent = 'this is wow'
3434
}
3535
})

test/functional/fixtures/nested-props.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ <h3>Computed property that concats the two: <span v-text="d"></span></h3>
2424
var data = { c: 555 }
2525
var Demo = Vue.extend({
2626
lazy: true,
27-
init: function () {
27+
ready: function () {
2828
this.msg = 'Yoyoyo'
2929
this.a = data
3030
},

test/functional/fixtures/nested-viewmodels.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
Vue.config({ debug: true })
5454

5555
var Man = Vue.extend({
56-
init: function () {
56+
created: function () {
5757
this.name = this.$el.dataset.name
5858
var family = this.$el.dataset.family
5959
if (family) {

test/functional/fixtures/repeated-vms.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
Vue.config({ debug: true })
1414

1515
Vue.component('item', {
16-
init: function () {
16+
ready: function () {
1717
this.item.title += ' init'
1818
},
1919
proto: {

test/unit/specs/api.js

Lines changed: 81 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -338,19 +338,6 @@ describe('UNIT: API', function () {
338338

339339
describe('Options', function () {
340340

341-
describe('init', function () {
342-
343-
it('should be called on the instance when instantiating', function () {
344-
var called = false,
345-
Test = Vue.extend({ init: function () {
346-
called = true
347-
}})
348-
new Test({ el: document.createElement('div') })
349-
assert.ok(called)
350-
})
351-
352-
})
353-
354341
describe('proto', function () {
355342

356343
it('should be mixed to the exteded VM\'s prototype', function () {
@@ -451,7 +438,7 @@ describe('UNIT: API', function () {
451438

452439
})
453440

454-
describe('element options', function () {
441+
describe('DOM element options', function () {
455442

456443
it('should not accept el as an extension option', function () {
457444
var el = document.createElement('div'),
@@ -729,22 +716,6 @@ describe('UNIT: API', function () {
729716

730717
})
731718

732-
describe('teardown', function () {
733-
734-
it('should be called when a vm is destroyed', function () {
735-
var called = false
736-
var Test = Vue.extend({
737-
teardown: function () {
738-
called = true
739-
}
740-
})
741-
var test = new Test()
742-
test.$destroy()
743-
assert.ok(called)
744-
})
745-
746-
})
747-
748719
describe('transitions', function () {
749720

750721
it('should get called during transitions', function () {
@@ -790,6 +761,86 @@ describe('UNIT: API', function () {
790761

791762
})
792763

764+
describe('hooks', function () {
765+
766+
describe('beforeCompile / created', function () {
767+
768+
it('should be called before compile', function () {
769+
770+
var called = false,
771+
Test = Vue.extend({ beforeCompile: function (options) {
772+
assert.ok(options.ok)
773+
called = true
774+
}}),
775+
Test2 = Vue.extend({ created: function (options) {
776+
assert.ok(options.ok)
777+
called = true
778+
}})
779+
new Test({ ok: true })
780+
assert.ok(called)
781+
called = false
782+
new Test2({ ok: true })
783+
assert.ok(called)
784+
})
785+
786+
})
787+
788+
describe('afterCompile / ready', function () {
789+
790+
it('should be called after compile with options', function () {
791+
var called = false,
792+
hook = function (options) {
793+
assert.ok(options.ok)
794+
assert.notOk(this.$compiler.init)
795+
called = true
796+
},
797+
Test = Vue.extend({ afterCompile: hook }),
798+
Test2 = Vue.extend({ ready: hook })
799+
new Test({ ok: true })
800+
assert.ok(called)
801+
called = false
802+
new Test2({ ok: true })
803+
assert.ok(called)
804+
})
805+
806+
})
807+
808+
describe('beforeDestroy', function () {
809+
810+
it('should be called before a vm is destroyed', function () {
811+
var called = false
812+
var Test = Vue.extend({
813+
beforeDestroy: function () {
814+
called = true
815+
}
816+
})
817+
var test = new Test()
818+
test.$destroy()
819+
assert.ok(called)
820+
})
821+
822+
})
823+
824+
describe('afterDestroy', function () {
825+
826+
it('should be called after a vm is destroyed', function () {
827+
var called = false,
828+
Test = Vue.extend({
829+
afterDestroy: function () {
830+
assert.notOk(this.$el.parentNode)
831+
called = true
832+
}
833+
})
834+
var test = new Test()
835+
document.body.appendChild(test.$el)
836+
test.$destroy()
837+
assert.ok(called)
838+
})
839+
840+
})
841+
842+
})
843+
793844
})
794845

795846
})

test/unit/specs/viewmodel.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ describe('UNIT: ViewModel', function () {
151151
var triggered = 0,
152152
msg = 'broadcast test'
153153
var Child = Vue.extend({
154-
init: function () {
154+
ready: function () {
155155
this.$on('hello', function (m) {
156156
assert.strictEqual(m, msg)
157157
triggered++
@@ -178,7 +178,7 @@ describe('UNIT: ViewModel', function () {
178178
midTriggered = false,
179179
msg = 'emit test'
180180
var Bottom = Vue.extend({
181-
init: function () {
181+
ready: function () {
182182
var self = this
183183
setTimeout(function () {
184184
self.$emit('hello', msg)
@@ -191,7 +191,7 @@ describe('UNIT: ViewModel', function () {
191191
var Middle = Vue.extend({
192192
template: '<div v-component="bottom"></div>',
193193
components: { bottom: Bottom },
194-
init: function () {
194+
ready: function () {
195195
this.$on('hello', function (m) {
196196
assert.strictEqual(m, msg)
197197
midTriggered = true
@@ -201,7 +201,7 @@ describe('UNIT: ViewModel', function () {
201201
var Top = Vue.extend({
202202
template: '<div v-component="middle"></div>',
203203
components: { middle: Middle },
204-
init: function () {
204+
ready: function () {
205205
this.$on('hello', function (m) {
206206
assert.strictEqual(m, msg)
207207
topTriggered = true
@@ -219,7 +219,8 @@ describe('UNIT: ViewModel', function () {
219219
// that's what we are actually testing here.
220220
var destroy = require('vue/src/compiler').prototype.destroy
221221

222-
var tearDownCalled = false,
222+
var beforeDestroyCalled = false,
223+
afterDestroyCalled = false,
223224
observerOffCalled = false,
224225
emitterOffCalled = false,
225226
dirUnbindCalled = false,
@@ -265,8 +266,11 @@ describe('UNIT: ViewModel', function () {
265266

266267
var compilerMock = {
267268
options: {
268-
teardown: function () {
269-
tearDownCalled = true
269+
beforeDestroy: function () {
270+
beforeDestroyCalled = true
271+
},
272+
afterDestroy: function () {
273+
afterDestroyCalled = true
270274
}
271275
},
272276
observer: {
@@ -312,8 +316,9 @@ describe('UNIT: ViewModel', function () {
312316

313317
destroy.call(compilerMock)
314318

315-
it('should call the teardown option', function () {
316-
assert.ok(tearDownCalled)
319+
it('should call the pre and post destroy hooks', function () {
320+
assert.ok(beforeDestroyCalled)
321+
assert.ok(afterDestroyCalled)
317322
})
318323

319324
it('should turn observer and emitter off', function () {

0 commit comments

Comments
 (0)