expect(serializeInner(root)).toBe('bar')
})
+ test('kebab-case v-model (should not be local)', async () => {
+ let foo: any
+
+ const compRender = vi.fn()
+ const Comp = defineComponent({
+ props: ['fooBar'],
+ emits: ['update:fooBar'],
+ setup(props) {
+ foo = useModel(props, 'fooBar')
+ return () => {
+ compRender()
+ return foo.value
+ }
+ },
+ })
+
+ const updateFooBar = vi.fn()
+ const root = nodeOps.createElement('div')
+ // v-model:foo-bar compiles to foo-bar and onUpdate:fooBar
+ render(
+ h(Comp, { 'foo-bar': 'initial', 'onUpdate:fooBar': updateFooBar }),
+ root,
+ )
+ expect(compRender).toBeCalledTimes(1)
+ expect(serializeInner(root)).toBe('initial')
+
+ expect(foo.value).toBe('initial')
+ foo.value = 'bar'
+ // should not be using local mode, so nothing should actually change
+ expect(foo.value).toBe('initial')
+
+ await nextTick()
+ expect(compRender).toBeCalledTimes(1)
+ expect(updateFooBar).toBeCalledTimes(1)
+ expect(updateFooBar).toHaveBeenCalledWith('bar')
+ expect(foo.value).toBe('initial')
+ expect(serializeInner(root)).toBe('initial')
+ })
+
+ test('kebab-case update listener (should not be local)', async () => {
+ let foo: any
+
+ const compRender = vi.fn()
+ const Comp = defineComponent({
+ props: ['fooBar'],
+ emits: ['update:fooBar'],
+ setup(props) {
+ foo = useModel(props, 'fooBar')
+ return () => {
+ compRender()
+ return foo.value
+ }
+ },
+ })
+
+ const updateFooBar = vi.fn()
+ const root = nodeOps.createElement('div')
+ // The template compiler won't create hyphenated listeners, but it could have been passed manually
+ render(
+ h(Comp, { 'foo-bar': 'initial', 'onUpdate:foo-bar': updateFooBar }),
+ root,
+ )
+ expect(compRender).toBeCalledTimes(1)
+ expect(serializeInner(root)).toBe('initial')
+
+ expect(foo.value).toBe('initial')
+ foo.value = 'bar'
+ // should not be using local mode, so nothing should actually change
+ expect(foo.value).toBe('initial')
+
+ await nextTick()
+ expect(compRender).toBeCalledTimes(1)
+ expect(updateFooBar).toBeCalledTimes(1)
+ expect(updateFooBar).toHaveBeenCalledWith('bar')
+ expect(foo.value).toBe('initial')
+ expect(serializeInner(root)).toBe('initial')
+ })
+
test('default value', async () => {
let count: any
const inc = () => {
camelize,
extend,
hasChanged,
+ hyphenate,
isArray,
isFunction,
isPromise,
}
const camelizedName = camelize(name)
+ const hyphenatedName = hyphenate(name)
const res = customRef((track, trigger) => {
let localValue: any
!(
rawProps &&
// check if parent has passed v-model
- (name in rawProps || camelizedName in rawProps) &&
+ (name in rawProps ||
+ camelizedName in rawProps ||
+ hyphenatedName in rawProps) &&
(`onUpdate:${name}` in rawProps ||
- `onUpdate:${camelizedName}` in rawProps)
+ `onUpdate:${camelizedName}` in rawProps ||
+ `onUpdate:${hyphenatedName}` in rawProps)
) &&
hasChanged(value, localValue)
) {