]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(rumtime-core): custom dom props should be cloned when cloning a hoisted DOM ...
authorHcySunYang <HcySunYang@outlook.com>
Thu, 25 Mar 2021 14:21:57 +0000 (22:21 +0800)
committerGitHub <noreply@github.com>
Thu, 25 Mar 2021 14:21:57 +0000 (10:21 -0400)
fix #3072

packages/runtime-dom/__tests__/nodeOps.spec.ts [new file with mode: 0644]
packages/runtime-dom/src/nodeOps.ts

diff --git a/packages/runtime-dom/__tests__/nodeOps.spec.ts b/packages/runtime-dom/__tests__/nodeOps.spec.ts
new file mode 100644 (file)
index 0000000..3f72379
--- /dev/null
@@ -0,0 +1,12 @@
+import { nodeOps } from '../src/nodeOps'
+
+describe('nodeOps', () => {
+  test('the _value property should be cloned', () => {
+    const el = nodeOps.createElement('input') as HTMLDivElement & {
+      _value: any
+    }
+    el._value = 1
+    const cloned = nodeOps.cloneNode!(el) as HTMLDivElement & { _value: any }
+    expect(cloned._value).toBe(1)
+  })
+})
index 72aa25a3930c74e70de61c0c8a7be28d5d756b94..06e59221113f368ebf1986c61dcae4ffecab96ac 100644 (file)
@@ -47,7 +47,20 @@ export const nodeOps: Omit<RendererOptions<Node, Element>, 'patchProp'> = {
   },
 
   cloneNode(el) {
-    return el.cloneNode(true)
+    const cloned = el.cloneNode(true)
+    // #3072
+    // - in `patchDOMProp`, we store the actual value in the `el._value` property.
+    // - normally, elements using `:value` bindings will not be hoisted, but if
+    //   the bound value is a constant, e.g. `:value="true"` - they do get
+    //   hoisted.
+    // - in production, hoisted nodes are cloned when subsequent inserts, but
+    //   cloneNode() does not copy the custom property we attached.
+    // - This may need to account for other custom DOM properties we attach to
+    //   elements in addition to `_value` in the future.
+    if (`_value` in el) {
+      ;(cloned as any)._value = (el as any)._value
+    }
+    return cloned
   },
 
   // __UNSAFE__