diff --git a/src/compiler/compile.js b/src/compiler/compile.js
index c53967dd52d..90087939119 100644
--- a/src/compiler/compile.js
+++ b/src/compiler/compile.js
@@ -665,8 +665,8 @@ function makeTerminalNodeLinkFn (el, dirName, value, options, def, rawName, arg,
modifiers: modifiers,
def: def
}
- // check ref for v-for and router-view
- if (dirName === 'for' || dirName === 'router-view') {
+ // check ref for v-for, v-if and router-view
+ if (dirName === 'for' || dirName === 'if' || dirName === 'router-view') {
descriptor.ref = findRef(el)
}
var fn = function terminalNodeLinkFn (vm, el, host, scope, frag) {
diff --git a/src/directives/public/for.js b/src/directives/public/for.js
index 9713208a1a1..f8af46cbbab 100644
--- a/src/directives/public/for.js
+++ b/src/directives/public/for.js
@@ -16,7 +16,8 @@ import {
def,
cancellable,
isArray,
- isPlainObject
+ isPlainObject,
+ findVmFromFrag
} from '../../util/index'
let uid = 0
@@ -602,24 +603,6 @@ function findPrevFrag (frag, anchor, id) {
return frag
}
-/**
- * Find a vm from a fragment.
- *
- * @param {Fragment} frag
- * @return {Vue|undefined}
- */
-
-function findVmFromFrag (frag) {
- let node = frag.node
- // handle multi-node frag
- if (frag.end) {
- while (!node.__vue__ && node !== frag.end && node.nextSibling) {
- node = node.nextSibling
- }
- }
- return node.__vue__
-}
-
/**
* Create a range array from given number.
*
diff --git a/src/directives/public/if.js b/src/directives/public/if.js
index 324e548ff9b..8485dc6b83e 100644
--- a/src/directives/public/if.js
+++ b/src/directives/public/if.js
@@ -5,7 +5,8 @@ import {
remove,
replace,
createAnchor,
- warn
+ warn,
+ findVmFromFrag
} from '../../util/index'
export default {
@@ -40,8 +41,10 @@ export default {
if (value) {
if (!this.frag) {
this.insert()
+ this.updateRef(value)
}
} else {
+ this.updateRef(value)
this.remove()
}
},
@@ -76,6 +79,29 @@ export default {
}
},
+ updateRef (value) {
+ var ref = this.descriptor.ref
+ if (!ref) return
+ var hash = (this.vm || this._scope).$refs
+ var refs = hash[ref]
+ var key = this._frag.scope.$key
+ if (!refs) return
+ if (value) {
+ if (Array.isArray(refs)) {
+ refs.push(findVmFromFrag(this._frag))
+ } else {
+ refs[key] = findVmFromFrag(this._frag)
+ }
+ } else {
+ if (Array.isArray(refs)) {
+ refs.$remove(findVmFromFrag(this._frag))
+ } else {
+ refs[key] = null
+ delete refs[key]
+ }
+ }
+ },
+
unbind () {
if (this.frag) {
this.frag.destroy()
diff --git a/src/util/dom.js b/src/util/dom.js
index 26382953e0a..38f43f72ada 100644
--- a/src/util/dom.js
+++ b/src/util/dom.js
@@ -449,3 +449,21 @@ export function getOuterHTML (el) {
return container.innerHTML
}
}
+
+/**
+ * Find a vm from a fragment.
+ *
+ * @param {Fragment} frag
+ * @return {Vue|undefined}
+ */
+
+export function findVmFromFrag (frag) {
+ let node = frag.node
+ // handle multi-node frag
+ if (frag.end) {
+ while (!node.__vue__ && node !== frag.end && node.nextSibling) {
+ node = node.nextSibling
+ }
+ }
+ return node.__vue__
+}
diff --git a/test/unit/specs/directives/public/if_spec.js b/test/unit/specs/directives/public/if_spec.js
index f9d28fc9f72..91f0aec4c0d 100644
--- a/test/unit/specs/directives/public/if_spec.js
+++ b/test/unit/specs/directives/public/if_spec.js
@@ -432,4 +432,77 @@ describe('v-if', function () {
done()
})
})
+
+ // GitHub issue #3204
+ it('update array refs', function (done) {
+ var vm = new Vue({
+ el: el,
+ template: '