| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029 |
- import {
- h,
- render,
- nextTick,
- defineComponent,
- vModelDynamic,
- withDirectives,
- VNode,
- ref
- } from '@vue/runtime-dom'
- const triggerEvent = (type: string, el: Element) => {
- const event = new Event(type)
- el.dispatchEvent(event)
- }
- const withVModel = (node: VNode, arg: any, mods?: any) =>
- withDirectives(node, [[vModelDynamic, arg, '', mods]])
- const setValue = function(this: any, value: any) {
- this.value = value
- }
- let root: any
- beforeEach(() => {
- root = document.createElement('div') as any
- })
- describe('vModel', () => {
- it('should work with text input', async () => {
- const manualListener = jest.fn()
- const component = defineComponent({
- data() {
- return { value: null }
- },
- render() {
- return [
- withVModel(
- h('input', {
- 'onUpdate:modelValue': setValue.bind(this),
- onInput: () => {
- manualListener(data.value)
- }
- }),
- this.value
- )
- ]
- }
- })
- render(h(component), root)
- const input = root.querySelector('input')!
- const data = root._vnode.component.data
- expect(input.value).toEqual('')
- input.value = 'foo'
- triggerEvent('input', input)
- await nextTick()
- expect(data.value).toEqual('foo')
- // #1931
- expect(manualListener).toHaveBeenCalledWith('foo')
- data.value = 'bar'
- await nextTick()
- expect(input.value).toEqual('bar')
- data.value = undefined
- await nextTick()
- expect(input.value).toEqual('')
- })
- it('should work with multiple listeners', async () => {
- const spy = jest.fn()
- const component = defineComponent({
- data() {
- return { value: null }
- },
- render() {
- return [
- withVModel(
- h('input', {
- 'onUpdate:modelValue': [setValue.bind(this), spy]
- }),
- this.value
- )
- ]
- }
- })
- render(h(component), root)
- const input = root.querySelector('input')!
- const data = root._vnode.component.data
- input.value = 'foo'
- triggerEvent('input', input)
- await nextTick()
- expect(data.value).toEqual('foo')
- expect(spy).toHaveBeenCalledWith('foo')
- })
- it('should work with updated listeners', async () => {
- const spy1 = jest.fn()
- const spy2 = jest.fn()
- const toggle = ref(true)
- const component = defineComponent({
- render() {
- return [
- withVModel(
- h('input', {
- 'onUpdate:modelValue': toggle.value ? spy1 : spy2
- }),
- 'foo'
- )
- ]
- }
- })
- render(h(component), root)
- const input = root.querySelector('input')!
- input.value = 'foo'
- triggerEvent('input', input)
- await nextTick()
- expect(spy1).toHaveBeenCalledWith('foo')
- // update listener
- toggle.value = false
- await nextTick()
- input.value = 'bar'
- triggerEvent('input', input)
- await nextTick()
- expect(spy1).not.toHaveBeenCalledWith('bar')
- expect(spy2).toHaveBeenCalledWith('bar')
- })
- it('should work with textarea', async () => {
- const component = defineComponent({
- data() {
- return { value: null }
- },
- render() {
- return [
- withVModel(
- h('textarea', {
- 'onUpdate:modelValue': setValue.bind(this)
- }),
- this.value
- )
- ]
- }
- })
- render(h(component), root)
- const input = root.querySelector('textarea')
- const data = root._vnode.component.data
- input.value = 'foo'
- triggerEvent('input', input)
- await nextTick()
- expect(data.value).toEqual('foo')
- data.value = 'bar'
- await nextTick()
- expect(input.value).toEqual('bar')
- })
- it('should support modifiers', async () => {
- const component = defineComponent({
- data() {
- return { number: null, trim: null, lazy: null }
- },
- render() {
- return [
- withVModel(
- h('input', {
- class: 'number',
- 'onUpdate:modelValue': (val: any) => {
- this.number = val
- }
- }),
- this.number,
- {
- number: true
- }
- ),
- withVModel(
- h('input', {
- class: 'trim',
- 'onUpdate:modelValue': (val: any) => {
- this.trim = val
- }
- }),
- this.trim,
- {
- trim: true
- }
- ),
- withVModel(
- h('input', {
- class: 'lazy',
- 'onUpdate:modelValue': (val: any) => {
- this.lazy = val
- }
- }),
- this.lazy,
- {
- lazy: true
- }
- )
- ]
- }
- })
- render(h(component), root)
- const number = root.querySelector('.number')
- const trim = root.querySelector('.trim')
- const lazy = root.querySelector('.lazy')
- const data = root._vnode.component.data
- number.value = '+01.2'
- triggerEvent('input', number)
- await nextTick()
- expect(data.number).toEqual(1.2)
- trim.value = ' hello, world '
- triggerEvent('input', trim)
- await nextTick()
- expect(data.trim).toEqual('hello, world')
- lazy.value = 'foo'
- triggerEvent('change', lazy)
- await nextTick()
- expect(data.lazy).toEqual('foo')
- })
- it('should work with checkbox', async () => {
- const component = defineComponent({
- data() {
- return { value: null }
- },
- render() {
- return [
- withVModel(
- h('input', {
- type: 'checkbox',
- 'onUpdate:modelValue': setValue.bind(this)
- }),
- this.value
- )
- ]
- }
- })
- render(h(component), root)
- const input = root.querySelector('input')
- const data = root._vnode.component.data
- input.checked = true
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toEqual(true)
- data.value = false
- await nextTick()
- expect(input.checked).toEqual(false)
- data.value = true
- await nextTick()
- expect(input.checked).toEqual(true)
- input.checked = false
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toEqual(false)
- })
- it('should work with checkbox and true-value/false-value', async () => {
- const component = defineComponent({
- data() {
- return { value: null }
- },
- render() {
- return [
- withVModel(
- h('input', {
- type: 'checkbox',
- 'true-value': 'yes',
- 'false-value': 'no',
- 'onUpdate:modelValue': setValue.bind(this)
- }),
- this.value
- )
- ]
- }
- })
- render(h(component), root)
- const input = root.querySelector('input')
- const data = root._vnode.component.data
- input.checked = true
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toEqual('yes')
- data.value = 'no'
- await nextTick()
- expect(input.checked).toEqual(false)
- data.value = 'yes'
- await nextTick()
- expect(input.checked).toEqual(true)
- input.checked = false
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toEqual('no')
- })
- it('should work with checkbox and true-value/false-value with object values', async () => {
- const component = defineComponent({
- data() {
- return { value: null }
- },
- render() {
- return [
- withVModel(
- h('input', {
- type: 'checkbox',
- 'true-value': { yes: 'yes' },
- 'false-value': { no: 'no' },
- 'onUpdate:modelValue': setValue.bind(this)
- }),
- this.value
- )
- ]
- }
- })
- render(h(component), root)
- const input = root.querySelector('input')
- const data = root._vnode.component.data
- input.checked = true
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toEqual({ yes: 'yes' })
- data.value = { no: 'no' }
- await nextTick()
- expect(input.checked).toEqual(false)
- data.value = { yes: 'yes' }
- await nextTick()
- expect(input.checked).toEqual(true)
- input.checked = false
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toEqual({ no: 'no' })
- })
- it(`should support array as a checkbox model`, async () => {
- const component = defineComponent({
- data() {
- return { value: [] }
- },
- render() {
- return [
- withVModel(
- h('input', {
- type: 'checkbox',
- class: 'foo',
- value: 'foo',
- 'onUpdate:modelValue': setValue.bind(this)
- }),
- this.value
- ),
- withVModel(
- h('input', {
- type: 'checkbox',
- class: 'bar',
- value: 'bar',
- 'onUpdate:modelValue': setValue.bind(this)
- }),
- this.value
- )
- ]
- }
- })
- render(h(component), root)
- const foo = root.querySelector('.foo')
- const bar = root.querySelector('.bar')
- const data = root._vnode.component.data
- foo.checked = true
- triggerEvent('change', foo)
- await nextTick()
- expect(data.value).toMatchObject(['foo'])
- bar.checked = true
- triggerEvent('change', bar)
- await nextTick()
- expect(data.value).toMatchObject(['foo', 'bar'])
- bar.checked = false
- triggerEvent('change', bar)
- await nextTick()
- expect(data.value).toMatchObject(['foo'])
- foo.checked = false
- triggerEvent('change', foo)
- await nextTick()
- expect(data.value).toMatchObject([])
- data.value = ['foo']
- await nextTick()
- expect(bar.checked).toEqual(false)
- expect(foo.checked).toEqual(true)
- data.value = ['bar']
- await nextTick()
- expect(foo.checked).toEqual(false)
- expect(bar.checked).toEqual(true)
- data.value = []
- await nextTick()
- expect(foo.checked).toEqual(false)
- expect(bar.checked).toEqual(false)
- })
- it(`should support Set as a checkbox model`, async () => {
- const component = defineComponent({
- data() {
- return { value: new Set() }
- },
- render() {
- return [
- withVModel(
- h('input', {
- type: 'checkbox',
- class: 'foo',
- value: 'foo',
- 'onUpdate:modelValue': setValue.bind(this)
- }),
- this.value
- ),
- withVModel(
- h('input', {
- type: 'checkbox',
- class: 'bar',
- value: 'bar',
- 'onUpdate:modelValue': setValue.bind(this)
- }),
- this.value
- )
- ]
- }
- })
- render(h(component), root)
- const foo = root.querySelector('.foo')
- const bar = root.querySelector('.bar')
- const data = root._vnode.component.data
- foo.checked = true
- triggerEvent('change', foo)
- await nextTick()
- expect(data.value).toMatchObject(new Set(['foo']))
- bar.checked = true
- triggerEvent('change', bar)
- await nextTick()
- expect(data.value).toMatchObject(new Set(['foo', 'bar']))
- bar.checked = false
- triggerEvent('change', bar)
- await nextTick()
- expect(data.value).toMatchObject(new Set(['foo']))
- foo.checked = false
- triggerEvent('change', foo)
- await nextTick()
- expect(data.value).toMatchObject(new Set())
- data.value = new Set(['foo'])
- await nextTick()
- expect(bar.checked).toEqual(false)
- expect(foo.checked).toEqual(true)
- data.value = new Set(['bar'])
- await nextTick()
- expect(foo.checked).toEqual(false)
- expect(bar.checked).toEqual(true)
- data.value = new Set()
- await nextTick()
- expect(foo.checked).toEqual(false)
- expect(bar.checked).toEqual(false)
- })
- it('should work with radio', async () => {
- const component = defineComponent({
- data() {
- return { value: null }
- },
- render() {
- return [
- withVModel(
- h('input', {
- type: 'radio',
- class: 'foo',
- value: 'foo',
- 'onUpdate:modelValue': setValue.bind(this)
- }),
- this.value
- ),
- withVModel(
- h('input', {
- type: 'radio',
- class: 'bar',
- value: 'bar',
- 'onUpdate:modelValue': setValue.bind(this)
- }),
- this.value
- )
- ]
- }
- })
- render(h(component), root)
- const foo = root.querySelector('.foo')
- const bar = root.querySelector('.bar')
- const data = root._vnode.component.data
- foo.checked = true
- triggerEvent('change', foo)
- await nextTick()
- expect(data.value).toEqual('foo')
- bar.checked = true
- triggerEvent('change', bar)
- await nextTick()
- expect(data.value).toEqual('bar')
- data.value = null
- await nextTick()
- expect(foo.checked).toEqual(false)
- expect(bar.checked).toEqual(false)
- data.value = 'foo'
- await nextTick()
- expect(foo.checked).toEqual(true)
- expect(bar.checked).toEqual(false)
- data.value = 'bar'
- await nextTick()
- expect(foo.checked).toEqual(false)
- expect(bar.checked).toEqual(true)
- })
- it('should work with single select', async () => {
- const component = defineComponent({
- data() {
- return { value: null }
- },
- render() {
- return [
- withVModel(
- h(
- 'select',
- {
- value: null,
- '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).toEqual('foo')
- foo.selected = false
- bar.selected = true
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toEqual('bar')
- foo.selected = false
- bar.selected = false
- data.value = 'foo'
- await nextTick()
- expect(input.value).toEqual('foo')
- expect(foo.selected).toEqual(true)
- expect(bar.selected).toEqual(false)
- foo.selected = true
- bar.selected = false
- data.value = 'bar'
- await nextTick()
- expect(input.value).toEqual('bar')
- expect(foo.selected).toEqual(false)
- expect(bar.selected).toEqual(true)
- })
- it('multiple select (model is Array)', async () => {
- const component = defineComponent({
- data() {
- return { value: [] }
- },
- 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(['foo'])
- foo.selected = false
- bar.selected = true
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toMatchObject(['bar'])
- foo.selected = true
- bar.selected = true
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toMatchObject(['foo', 'bar'])
- foo.selected = false
- bar.selected = false
- data.value = ['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 = ['foo', 'bar']
- await nextTick()
- expect(foo.selected).toEqual(true)
- expect(bar.selected).toEqual(true)
- })
- it('v-model.number should work with select tag', async () => {
- const component = defineComponent({
- data() {
- return { value: null }
- },
- render() {
- return [
- withVModel(
- h(
- 'select',
- {
- value: null,
- 'onUpdate:modelValue': setValue.bind(this)
- },
- [h('option', { value: '1' }), h('option', { value: '2' })]
- ),
- this.value,
- {
- number: true
- }
- )
- ]
- }
- })
- render(h(component), root)
- const input = root.querySelector('select')
- const one = root.querySelector('option[value="1"]')
- const data = root._vnode.component.data
- one.selected = true
- triggerEvent('change', input)
- await nextTick()
- expect(typeof data.value).toEqual('number')
- expect(data.value).toEqual(1)
- })
- it('v-model.number should work with multiple select', async () => {
- const component = defineComponent({
- data() {
- return { value: [] }
- },
- render() {
- return [
- withVModel(
- h(
- 'select',
- {
- value: null,
- multiple: true,
- 'onUpdate:modelValue': setValue.bind(this)
- },
- [h('option', { value: '1' }), h('option', { value: '2' })]
- ),
- this.value,
- {
- number: true
- }
- )
- ]
- }
- })
- render(h(component), root)
- const input = root.querySelector('select')
- const one = root.querySelector('option[value="1"]')
- const two = root.querySelector('option[value="2"]')
- const data = root._vnode.component.data
- one.selected = true
- two.selected = false
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toMatchObject([1])
- one.selected = false
- two.selected = true
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toMatchObject([2])
- one.selected = true
- two.selected = true
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toMatchObject([1, 2])
- one.selected = false
- two.selected = false
- data.value = [1]
- await nextTick()
- expect(one.selected).toEqual(true)
- expect(two.selected).toEqual(false)
- one.selected = false
- two.selected = false
- data.value = [1, 2]
- await nextTick()
- expect(one.selected).toEqual(true)
- 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).toBeInstanceOf(Set)
- expect(data.value).toMatchObject(new Set(['foo']))
- foo.selected = false
- bar.selected = true
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toBeInstanceOf(Set)
- expect(data.value).toMatchObject(new Set(['bar']))
- foo.selected = true
- bar.selected = true
- triggerEvent('change', input)
- await nextTick()
- expect(data.value).toBeInstanceOf(Set)
- 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() {
- return { value: '' }
- },
- render() {
- return [
- withVModel(
- h('input', {
- 'onUpdate:modelValue': setValue.bind(this)
- }),
- this.value
- )
- ]
- }
- })
- render(h(component), root)
- const input = root.querySelector('input')!
- const data = root._vnode.component.data
- expect(input.value).toEqual('')
- //developer.mozilla.org/en-US/docs/Web/API/Element/compositionstart_event
- //compositionstart event could be fired after a user starts entering a Chinese character using a Pinyin IME
- input.value = '使用拼音'
- triggerEvent('compositionstart', input)
- await nextTick()
- expect(data.value).toEqual('')
- // input event has no effect during composition session
- input.value = '使用拼音输入'
- triggerEvent('input', input)
- await nextTick()
- expect(data.value).toEqual('')
- // After compositionend event being fired, an input event will be automatically trigger
- triggerEvent('compositionend', input)
- await nextTick()
- expect(data.value).toEqual('使用拼音输入')
- })
- })
|