nextTick,
ref,
Ref,
- watch
+ watch,
+ openBlock,
+ createVNode,
+ createElementVNode,
+ createBlock,
+ createElementBlock,
+ Fragment
} from '@vue/runtime-test'
import {
defineEmits,
await nextTick()
expect(serializeInner(root)).toBe('2')
})
+
+ // #9838
+ test('pass modelValue to slot (optimized mode) ', async () => {
+ let foo: any
+ const update = () => {
+ foo.value = 'bar'
+ }
+
+ const Comp = {
+ render(this: any) {
+ return this.$slots.default()
+ }
+ }
+
+ const childRender = vi.fn()
+ const slotRender = vi.fn()
+ const Child = defineComponent({
+ props: ['modelValue'],
+ emits: ['update:modelValue'],
+ setup(props) {
+ foo = useModel(props, 'modelValue')
+ return () => {
+ childRender()
+ return (
+ openBlock(),
+ createElementBlock(Fragment, null, [
+ createVNode(Comp, null, {
+ default: () => {
+ slotRender()
+ return createElementVNode('div', null, foo.value)
+ },
+ _: 1 /* STABLE */
+ })
+ ])
+ )
+ }
+ }
+ })
+
+ const msg = ref('')
+ const setValue = vi.fn(v => (msg.value = v))
+ const root = nodeOps.createElement('div')
+ createApp({
+ render() {
+ return (
+ openBlock(),
+ createBlock(
+ Child,
+ {
+ modelValue: msg.value,
+ 'onUpdate:modelValue': setValue
+ },
+ null,
+ 8 /* PROPS */,
+ ['modelValue']
+ )
+ )
+ }
+ }).mount(root)
+
+ expect(foo.value).toBe('')
+ expect(msg.value).toBe('')
+ expect(setValue).not.toBeCalled()
+ expect(childRender).toBeCalledTimes(1)
+ expect(slotRender).toBeCalledTimes(1)
+ expect(serializeInner(root)).toBe('<div></div>')
+
+ // update from child
+ update()
+
+ await nextTick()
+ expect(msg.value).toBe('bar')
+ expect(foo.value).toBe('bar')
+ expect(setValue).toBeCalledTimes(1)
+ expect(childRender).toBeCalledTimes(2)
+ expect(slotRender).toBeCalledTimes(2)
+ expect(serializeInner(root)).toBe('<div>bar</div>')
+ })
})
test('createPropsRestProxy', () => {
return ref() as any
}
- let localValue: any
- watchSyncEffect(() => {
- localValue = props[name]
- })
-
- return customRef((track, trigger) => ({
- get() {
- track()
- return localValue
- },
- set(value) {
- const rawProps = i.vnode!.props
- if (!(rawProps && name in rawProps) && hasChanged(value, localValue)) {
- localValue = value
+ return customRef((track, trigger) => {
+ let localValue: any
+ watchSyncEffect(() => {
+ const propValue = props[name]
+ if (hasChanged(localValue, propValue)) {
+ localValue = propValue
trigger()
}
- i.emit(`update:${name}`, value)
+ })
+ return {
+ get() {
+ track()
+ return localValue
+ },
+ set(value) {
+ const rawProps = i.vnode!.props
+ if (!(rawProps && name in rawProps) && hasChanged(value, localValue)) {
+ localValue = value
+ trigger()
+ }
+ i.emit(`update:${name}`, value)
+ }
}
- }))
+ })
}
function getContext(): SetupContext {