]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
test: add more test
authorAnthony Fu <anthonyfu117@hotmail.com>
Mon, 10 Apr 2023 09:24:20 +0000 (11:24 +0200)
committer三咲智子 Kevin Deng <sxzz@sxzz.moe>
Mon, 21 Aug 2023 08:13:11 +0000 (16:13 +0800)
packages/compiler-ssr/src/transforms/ssrVModel.ts
packages/runtime-dom/__tests__/directives/vModel.spec.ts
packages/runtime-dom/src/directives/vModel.ts

index 838edc232ab5fe41b5bec98818e80681c70a8efa..ed98042ea43101ece9c7c24e98cff11fcec09174 100644 (file)
@@ -130,7 +130,7 @@ export const ssrTransformModel: DirectiveTransform = (dir, node, context) => {
       checkDuplicatedValue()
       node.children = [createInterpolation(model, model.loc)]
     } else if (node.tag === 'dialog' || node.tag === 'details') {
-      res.props = [createObjectProperty(`open`, model)]
+      res.props = [createObjectProperty('open', model)]
     } else if (node.tag === 'select') {
       node.children.forEach(option => {
         if (option.type === NodeTypes.ELEMENT) {
index 73b8f18afc0806c36aba82de7e69562a6881b8a1..9cedb6d00c8bde40fc7af9f1581b5add0bb80856 100644 (file)
@@ -9,8 +9,8 @@ import {
   ref
 } from '@vue/runtime-dom'
 
-const triggerEvent = (type: string, el: Element) => {
-  const event = new Event(type)
+const triggerEvent = (type: string, el: Element, arg?: any) => {
+  const event = new Event(type, arg)
   el.dispatchEvent(event)
 }
 
@@ -1172,4 +1172,82 @@ describe('vModel', () => {
     await nextTick()
     expect(data.value).toEqual('使用拼音输入')
   })
+
+  it('should work with details', async () => {
+    const manualListener = vi.fn()
+    const component = defineComponent({
+      data() {
+        return { value: false }
+      },
+      render() {
+        return [
+          withVModel(
+            h('details', {
+              'onUpdate:modelValue': setValue.bind(this),
+              onToggle: () => {
+                manualListener(data.value)
+              }
+            }),
+            this.value
+          )
+        ]
+      }
+    })
+    render(h(component), root)
+
+    const details = root.querySelector('details')! as HTMLDetailsElement
+    const data = root._vnode.component.data
+    expect(details.open).toEqual(false)
+
+    details.open = true
+    triggerEvent('toggle', details, { target: details })
+    await nextTick()
+    expect(data.value).toEqual(true)
+    expect(manualListener).toHaveBeenCalledWith(true)
+
+    data.value = false
+    await nextTick()
+    expect(details.open).toEqual(false)
+
+    data.value = true
+    await nextTick()
+    expect(details.open).toEqual(true)
+  })
+
+  it('should work with dialog', async () => {
+    const manualListener = vi.fn()
+    const component = defineComponent({
+      data() {
+        return { value: false }
+      },
+      render() {
+        return [
+          withVModel(
+            h('dialog', {
+              'onUpdate:modelValue': setValue.bind(this),
+              onClose: () => {
+                manualListener(data.value)
+              }
+            }),
+            this.value
+          )
+        ]
+      }
+    })
+    render(h(component), root)
+
+    const dialog = root.querySelector('dialog')! as HTMLDialogElement
+    const data = root._vnode.component.data
+    expect(dialog.open).toEqual(false)
+
+    data.value = true
+    await nextTick()
+    expect(dialog.open).toEqual(true)
+
+    dialog.open = false
+    triggerEvent('close', dialog)
+    await nextTick()
+    expect(data.value).toEqual(false)
+    expect(manualListener).toHaveBeenCalledWith(false)
+  })
 })
index 056ccfb6f03dbc98dd8b37bec0e635cd5b6fb35a..b37ebd266d66b524504fe2d8c1d1246e74252709 100644 (file)
@@ -212,15 +212,15 @@ export const vModelSelect: ModelDirective<HTMLSelectElement> = {
 
 export const vModelDetails: ModelDirective<HTMLDetailsElement> = {
   created(el, _, vnode) {
+    el._assign = getModelAssigner(vnode)
     addEventListener(el, 'toggle', () => {
       el._assign(el.open)
     })
-    el._assign = getModelAssigner(vnode)
   },
   mounted(el, { value }) {
     el.open = value
   },
-  beforeUpdate(el, _binding, vnode) {
+  beforeUpdate(el, _, vnode) {
     el._assign = getModelAssigner(vnode)
   },
   updated(el, { value }) {
@@ -238,7 +238,7 @@ export const vModelDialog: ModelDirective<HTMLDialogElement> = {
   mounted(el, { value }) {
     el.open = value
   },
-  beforeUpdate(el, _binding, vnode) {
+  beforeUpdate(el, _, vnode) {
     el._assign = getModelAssigner(vnode)
   },
   updated(el, { value }) {
@@ -314,6 +314,10 @@ function resolveDynamicModel(tagName: string, type: string | undefined) {
       return vModelSelect
     case 'TEXTAREA':
       return vModelText
+    case 'DETAILS':
+      return vModelDetails
+    case 'DIALOG':
+      return vModelDialog
     default:
       switch (type) {
         case 'checkbox':