expect(bar.selected).toEqual(true)
})
- it('should work with multiple select', async () => {
+ it('multiple select (model is Array)', async () => {
const component = defineComponent({
data() {
return { value: [] }
expect(two.selected).toEqual(true)
})
+ it('multiple select (model is Array, option value is object)', async () => {
+ const fooValue = { foo: 1 }
+ const barValue = { bar: 1 }
+
+ const component = defineComponent({
+ data() {
+ return { value: [] }
+ },
+ render() {
+ return [
+ withVModel(
+ h(
+ 'select',
+ {
+ value: null,
+ multiple: true,
+ 'onUpdate:modelValue': setValue.bind(this)
+ },
+ [
+ h('option', { value: fooValue }),
+ h('option', { value: barValue })
+ ]
+ ),
+ this.value
+ )
+ ]
+ }
+ })
+ render(h(component), root)
+
+ await nextTick()
+
+ const input = root.querySelector('select')
+ const [foo, bar] = root.querySelectorAll('option')
+ const data = root._vnode.component.data
+
+ foo.selected = true
+ triggerEvent('change', input)
+ await nextTick()
+ expect(data.value).toMatchObject([fooValue])
+
+ foo.selected = false
+ bar.selected = true
+ triggerEvent('change', input)
+ await nextTick()
+ expect(data.value).toMatchObject([barValue])
+
+ foo.selected = true
+ bar.selected = true
+ triggerEvent('change', input)
+ await nextTick()
+ expect(data.value).toMatchObject([fooValue, barValue])
+
+ foo.selected = false
+ bar.selected = false
+ data.value = [fooValue, barValue]
+ await nextTick()
+ expect(foo.selected).toEqual(true)
+ expect(bar.selected).toEqual(true)
+
+ foo.selected = false
+ bar.selected = false
+ data.value = [{ foo: 1 }, { bar: 1 }]
+ await nextTick()
+ // looseEqual
+ expect(foo.selected).toEqual(true)
+ expect(bar.selected).toEqual(true)
+ })
+
+ it('multiple select (model is Set)', async () => {
+ const component = defineComponent({
+ data() {
+ return { value: new Set() }
+ },
+ render() {
+ return [
+ withVModel(
+ h(
+ 'select',
+ {
+ value: null,
+ multiple: true,
+ 'onUpdate:modelValue': setValue.bind(this)
+ },
+ [h('option', { value: 'foo' }), h('option', { value: 'bar' })]
+ ),
+ this.value
+ )
+ ]
+ }
+ })
+ render(h(component), root)
+
+ const input = root.querySelector('select')
+ const foo = root.querySelector('option[value=foo]')
+ const bar = root.querySelector('option[value=bar]')
+ const data = root._vnode.component.data
+
+ foo.selected = true
+ triggerEvent('change', input)
+ await nextTick()
+ expect(data.value).toMatchObject(new Set(['foo']))
+
+ foo.selected = false
+ bar.selected = true
+ triggerEvent('change', input)
+ await nextTick()
+ expect(data.value).toMatchObject(new Set(['bar']))
+
+ foo.selected = true
+ bar.selected = true
+ triggerEvent('change', input)
+ await nextTick()
+ expect(data.value).toMatchObject(new Set(['foo', 'bar']))
+
+ foo.selected = false
+ bar.selected = false
+ data.value = new Set(['foo'])
+ await nextTick()
+ expect(input.value).toEqual('foo')
+ expect(foo.selected).toEqual(true)
+ expect(bar.selected).toEqual(false)
+
+ foo.selected = false
+ bar.selected = false
+ data.value = new Set(['foo', 'bar'])
+ await nextTick()
+ expect(foo.selected).toEqual(true)
+ expect(bar.selected).toEqual(true)
+ })
+
+ it('multiple select (model is Set, option value is object)', async () => {
+ const fooValue = { foo: 1 }
+ const barValue = { bar: 1 }
+
+ const component = defineComponent({
+ data() {
+ return { value: new Set() }
+ },
+ render() {
+ return [
+ withVModel(
+ h(
+ 'select',
+ {
+ value: null,
+ multiple: true,
+ 'onUpdate:modelValue': setValue.bind(this)
+ },
+ [
+ h('option', { value: fooValue }),
+ h('option', { value: barValue })
+ ]
+ ),
+ this.value
+ )
+ ]
+ }
+ })
+ render(h(component), root)
+
+ await nextTick()
+
+ const input = root.querySelector('select')
+ const [foo, bar] = root.querySelectorAll('option')
+ const data = root._vnode.component.data
+
+ foo.selected = true
+ triggerEvent('change', input)
+ await nextTick()
+ expect(data.value).toMatchObject(new Set([fooValue]))
+
+ foo.selected = false
+ bar.selected = true
+ triggerEvent('change', input)
+ await nextTick()
+ expect(data.value).toMatchObject(new Set([barValue]))
+
+ foo.selected = true
+ bar.selected = true
+ triggerEvent('change', input)
+ await nextTick()
+ expect(data.value).toMatchObject(new Set([fooValue, barValue]))
+
+ foo.selected = false
+ bar.selected = false
+ data.value = new Set([fooValue, barValue])
+ await nextTick()
+ expect(foo.selected).toEqual(true)
+ expect(bar.selected).toEqual(true)
+
+ foo.selected = false
+ bar.selected = false
+ data.value = new Set([{ foo: 1 }, { bar: 1 }])
+ await nextTick()
+ // whithout looseEqual, here is different from Array
+ expect(foo.selected).toEqual(false)
+ expect(bar.selected).toEqual(false)
+ })
+
it('should work with composition session', async () => {
const component = defineComponent({
data() {
looseIndexOf,
invokeArrayFns,
toNumber,
- isSet,
- looseHas
+ isSet
} from '@vue/shared'
type AssignerFn = (value: any) => void
assign(filtered)
}
} else if (isSet(modelValue)) {
- const found = modelValue.has(elementValue)
- if (checked && !found) {
- assign(modelValue.add(elementValue))
- } else if (!checked && found) {
+ if (checked) {
+ modelValue.add(elementValue)
+ } else {
modelValue.delete(elementValue)
- assign(modelValue)
}
} else {
assign(getCheckboxValue(el, checked))
if (isArray(value)) {
el.checked = looseIndexOf(value, vnode.props!.value) > -1
} else if (isSet(value)) {
- el.checked = looseHas(value, vnode.props!.value)
+ el.checked = value.has(vnode.props!.value)
} else if (value !== oldValue) {
el.checked = looseEqual(value, getCheckboxValue(el, true))
}
if (isArray(value)) {
option.selected = looseIndexOf(value, optionValue) > -1
} else {
- option.selected = looseHas(value, optionValue)
+ option.selected = value.has(optionValue)
}
} else {
if (looseEqual(getValue(option), value)) {
return { checked: true }
}
} else if (isSet(value)) {
- if (vnode.props && looseHas(value, vnode.props.value)) {
+ if (vnode.props && value.has(vnode.props.value)) {
return { checked: true }
}
} else if (value) {