mirror of https://github.com/vuejs/vue.git
warn non-Array value for <select multiple> (close #3191)
This commit is contained in:
parent
41a3b79ecd
commit
5b668a9222
|
|
@ -32,7 +32,7 @@ export default {
|
|||
}
|
||||
}
|
||||
if (vnode.tag === 'select') {
|
||||
setSelected(el, binding.value)
|
||||
setSelected(el, binding, vnode.context)
|
||||
} else {
|
||||
if (!isAndroid) {
|
||||
el.addEventListener('compositionstart', onCompositionStart)
|
||||
|
|
@ -45,16 +45,15 @@ export default {
|
|||
}
|
||||
},
|
||||
componentUpdated (el, binding, vnode) {
|
||||
const val = binding.value
|
||||
if (vnode.tag === 'select') {
|
||||
setSelected(el, val)
|
||||
setSelected(el, binding, vnode.context)
|
||||
// in case the options rendered by v-for have changed,
|
||||
// it's possible that the value is out-of-sync with the rendered options.
|
||||
// detect such cases and filter out values that no longer has a matchig
|
||||
// option in the DOM.
|
||||
const needReset = el.multiple
|
||||
? val.some(v => hasNoMatchingOption(v, el.options))
|
||||
: hasNoMatchingOption(val, el.options)
|
||||
? binding.value.some(v => hasNoMatchingOption(v, el.options))
|
||||
: hasNoMatchingOption(binding.value, el.options)
|
||||
if (needReset) {
|
||||
trigger(el, 'change')
|
||||
}
|
||||
|
|
@ -62,10 +61,20 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
function setSelected (el, value) {
|
||||
function setSelected (el, binding, vm) {
|
||||
const value = binding.value
|
||||
const isMultiple = el.multiple
|
||||
if (!isMultiple) {
|
||||
el.selectedIndex = -1
|
||||
} else if (!Array.isArray(value)) {
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
`<select multiple v-model="${binding.expression}"> ` +
|
||||
`expects an Array value for its binding, but got ${
|
||||
Object.prototype.toString.call(value).slice(8, -1)
|
||||
}`,
|
||||
vm
|
||||
)
|
||||
return
|
||||
}
|
||||
for (let i = 0, l = el.options.length; i < l; i++) {
|
||||
const option = el.options[i]
|
||||
|
|
|
|||
|
|
@ -203,4 +203,16 @@ describe('Directive v-model select', () => {
|
|||
expect('inline selected attributes on <option> will be ignored when using v-model')
|
||||
.toHaveBeenWarned()
|
||||
})
|
||||
|
||||
it('should warn multiple with non-Array value', () => {
|
||||
const vm = new Vue({
|
||||
data: {
|
||||
test: 'meh'
|
||||
},
|
||||
template:
|
||||
'<select v-model="test" multiple></select>'
|
||||
}).$mount()
|
||||
expect('<select multiple v-model="test"> expects an Array value for its binding, but got String')
|
||||
.toHaveBeenWarned()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue