mirror of https://github.com/vuejs/vue.git
parent
bbe09dfe75
commit
c17e3876bf
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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__
|
||||
}
|
||||
|
|
|
@ -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: '<foo v-if="!activeItem || $index === activeItem" v-ref:foo :index="$index" v-for="item in items"></foo>',
|
||||
data: {
|
||||
items: [0, 1, 2],
|
||||
activeItem: null
|
||||
},
|
||||
components: {
|
||||
foo: {
|
||||
props: ['index'],
|
||||
template: '<div>I am foo ({{ index }})<div>'
|
||||
}
|
||||
}
|
||||
})
|
||||
vm.$refs.foo.forEach(function (ref, index) {
|
||||
expect(ref.$el.textContent).toBe('I am foo (' + index + ')')
|
||||
expect(ref.index).toBe(index)
|
||||
})
|
||||
vm.activeItem = 1 // select active item
|
||||
nextTick(function () {
|
||||
expect(vm.$refs.foo.length).toBe(1)
|
||||
expect(vm.$refs.foo[0].index).toBe(1)
|
||||
vm.activeItem = null // enable all elements
|
||||
nextTick(function () {
|
||||
expect(vm.$refs.foo.length).toBe(3)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('update object refs', function (done) {
|
||||
var vm = new Vue({
|
||||
el: el,
|
||||
template: '<foo v-if="!activeKey || $key === activeKey" v-ref:foo :key="$key" v-for="item in items"></foo>',
|
||||
data: {
|
||||
items: {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3
|
||||
},
|
||||
activeKey: null
|
||||
},
|
||||
components: {
|
||||
foo: {
|
||||
props: ['key'],
|
||||
template: '<div>I am foo ({{ key }})<div>'
|
||||
}
|
||||
}
|
||||
})
|
||||
Object.keys(vm.$refs.foo).forEach(function (key) {
|
||||
var ref = vm.$refs.foo[key]
|
||||
expect(ref.$el.textContent).toBe('I am foo (' + key + ')')
|
||||
expect(ref.key).toBe(key)
|
||||
})
|
||||
vm.activeKey = 'b' // select active item
|
||||
nextTick(function () {
|
||||
expect(Object.keys(vm.$refs.foo).length).toBe(1)
|
||||
expect(vm.$refs.foo['b'].key).toBe('b')
|
||||
vm.activeKey = null // enable all elements
|
||||
nextTick(function () {
|
||||
expect(Object.keys(vm.$refs.foo).length).toBe(3)
|
||||
Object.keys(vm.$refs.foo).forEach(function (key) {
|
||||
var ref = vm.$refs.foo[key]
|
||||
expect(ref.$el.textContent).toBe('I am foo (' + key + ')')
|
||||
expect(ref.key).toBe(key)
|
||||
})
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue