8000 hoist refs at compile time so that they are properly reactive (fix #1… · zhangking/vue@296ed69 · GitHub
[go: up one dir, main page]

Skip to content

Commit 296ed69

Browse files
committed
hoist refs at compile time so that they are properly reactive (fix vuejs#1671)
1 parent 7da156e commit 296ed69

File tree

4 files changed

+22
-20
lines changed

4 files changed

+22
-20
lines changed

src/compiler/compile.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,15 +493,20 @@ function checkElementDirectives (el, options) {
493493
function checkComponent (el, options) {
494494
var component = _.checkComponent(el, options)
495495
if (component) {
496+
var ref = _.findRef(el)
496497
var descriptor = {
497498
name: 'component',
499+
ref: ref,
498500
expression: component.id,
499501
def: internalDirectives.component,
500502
modifiers: {
501503
literal: !component.dynamic
502504
}
503505
}
504506
var componentLinkFn = function (vm, el, host, scope, frag) {
507+
if (ref) {
508+
_.defineReactive((scope || vm).$refs, ref, null)
509+
}
505510
vm._bindDir(descriptor, el, host, scope, frag)
506511
}
507512
componentLinkFn.terminal = true
@@ -568,7 +573,14 @@ function makeTerminalNodeLinkFn (el, dirName, value, options, def) {
568573
// either an element directive, or if/for
569574
def: def || publicDirectives[dirName]
570575
}
576+
// check ref for v-for
577+
if (dirName === 'for') {
578+
descriptor.ref = _.findRef(el)
579+
}
571580
var fn = function terminalNodeLinkFn (vm, el, host, scope, frag) {
581+
if (descriptor.ref) {
582+
_.defineReactive((scope || vm).$refs, descriptor.ref, null)
583+
}
572584
vm._bindDir(descriptor, el, host, scope, frag)
573585
}
574586
fn.terminal = true

src/directives/internal/component.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,6 @@ module.exports = {
2323

2424
bind: function () {
2525
if (!this.el.__vue__) {
26-
// check ref
27-
this.ref = _.findRef(this.el)
28-
var refs = (this._scope || this.vm).$refs
29-
if (this.ref && !refs.hasOwnProperty(this.ref)) {
30-
_.defineReactive(refs, this.ref, null)
31-
}
3226
// keep-alive cache
3327
this.keepAlive = this.params.keepAlive
3428
if (this.keepAlive) {
@@ -182,7 +176,7 @@ module.exports = {
182176
// if no inline-template, then the compiled
183177
// linker can be cached for better performance.
184178
_linkerCachable: !this.inlineTemplate,
185-
_ref: this.ref,
179+
_ref: this.descriptor.ref,
186180
_asComponent: true,
187181
_isRouterView: this._isRouterView,
188182
// if this is a transcluded component, context

src/directives/public/for.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,6 @@ module.exports = {
5555
_.replace(this.el, this.end)
5656
_.before(this.start, this.end)
5757

58-
// check ref
59-
this.ref = _.findRef(this.el)
60-
6158
// cache
6259
this.cache = Object.create(null)
6360

@@ -231,7 +228,7 @@ module.exports = {
231228
*/
232229

233230
updateRef: function () {
234-
var ref = this.ref
231+
var ref = this.descriptor.ref
235232
if (!ref) return
236233
var hash = (this._scope || this.vm).$refs
237234
var refs
@@ -243,11 +240,7 @@ module.exports = {
243240
refs[frag.scope.$key] = findVmFromFrag(frag)
244241
})
245242
}
246-
if (!hash.hasOwnProperty(ref)) {
247-
_.defineReactive(hash, ref, refs)
248-
} else {
249-
hash[ref] = refs
250-
}
243+
hash[ref] = refs
251244
},
252245

253246
/**
@@ -513,8 +506,8 @@ module.exports = {
513506
},
514507

515508
unbind: function () {
516-
if (this.ref) {
517-
(this._scope || this.vm).$refs[this.ref] = null
509+
if (this.descriptor.ref) {
510+
(this._scope || this.vm).$refs[this.descriptor.ref] = null
518511
}
519512
if (this.frags) {
520513
var i = this.frags.length

test/unit/specs/directives/public/ref_spec.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ if (_.inBrowser) {
5757
var vm = new Vue({
5858
el: el,
5959
data: { view: 'one' },
60-
template: '{{$refs.test.value}}<component :is="view" v-ref:test></component>',
60+
template:
61+
'{{$refs.test.value}}' +
62+
'<component :is="view" v-ref:test></component>' +
63+
'<div v-if="$refs.test.value > 1">ok</div>',
6164
components: {
6265
one: {
6366
id: 'one',
@@ -80,7 +83,7 @@ if (_.inBrowser) {
8083
vm.view = 'two'
8184
_.nextTick(function () {
8285
expect(vm.$refs.test.$options.id).toBe('two')
83-
expect(el.textContent).toBe('2')
86+
expect(el.textContent).toBe('2ok')
8487
vm.view = ''
8588
_.nextTick(function () {
8689
expect(vm.$refs.test).toBeNull()

0 commit comments

Comments
 (0)
0