Skip to content

Commit 2451dd8

Browse files
authored
fix(runtime-core): the select tag's multiple prop should be set before the children mounting (#3202)
fix #3199
1 parent 084e932 commit 2451dd8

File tree

3 files changed

+33
-7
lines changed

3 files changed

+33
-7
lines changed

packages/runtime-core/src/renderer.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111
Static,
1212
VNodeNormalizedRef,
1313
VNodeHook,
14-
VNodeNormalizedRefAtom
14+
VNodeNormalizedRefAtom,
15+
VNodeProps
1516
} from './vnode'
1617
import {
1718
ComponentInternalInstance,
@@ -114,7 +115,8 @@ export interface RendererOptions<
114115
createElement(
115116
type: string,
116117
isSVG?: boolean,
117-
isCustomizedBuiltIn?: string
118+
isCustomizedBuiltIn?: string,
119+
vnodeProps?: (VNodeProps & { [key: string]: any }) | null
118120
): HostElement
119121
createText(text: string): HostNode
120122
createComment(text: string): HostNode
@@ -738,7 +740,8 @@ function baseCreateRenderer(
738740
el = vnode.el = hostCreateElement(
739741
vnode.type as string,
740742
isSVG,
741-
props && props.is
743+
props && props.is,
744+
props
742745
)
743746

744747
// mount children first, since some props may rely on child content
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { nodeOps } from '../src/nodeOps'
22

3-
describe('nodeOps', () => {
3+
describe('runtime-dom: node-ops', () => {
44
test('the _value property should be cloned', () => {
55
const el = nodeOps.createElement('input') as HTMLDivElement & {
66
_value: any
@@ -9,4 +9,20 @@ describe('nodeOps', () => {
99
const cloned = nodeOps.cloneNode!(el) as HTMLDivElement & { _value: any }
1010
expect(cloned._value).toBe(1)
1111
})
12+
13+
test("the <select>'s multiple attr should be set in createElement", () => {
14+
const el = nodeOps.createElement('select', false, undefined, {
15+
multiple: ''
16+
}) as HTMLSelectElement
17+
const option1 = nodeOps.createElement('option') as HTMLOptionElement
18+
const option2 = nodeOps.createElement('option') as HTMLOptionElement
19+
option1.selected = true
20+
option2.selected = true
21+
nodeOps.insert(option1, el)
22+
nodeOps.insert(option2, el)
23+
24+
expect(el.multiple).toBe(true)
25+
expect(option1.selected).toBe(true)
26+
expect(option2.selected).toBe(true)
27+
})
1228
})

packages/runtime-dom/src/nodeOps.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,17 @@ export const nodeOps: Omit<RendererOptions<Node, Element>, 'patchProp'> = {
1919
}
2020
},
2121

22-
createElement: (tag, isSVG, is): Element =>
23-
isSVG
22+
createElement: (tag, isSVG, is, props): Element => {
23+
const el = isSVG
2424
? doc.createElementNS(svgNS, tag)
25-
: doc.createElement(tag, is ? { is } : undefined),
25+
: doc.createElement(tag, is ? { is } : undefined)
26+
27+
if (tag === 'select' && props && props.multiple != null) {
28+
;(el as HTMLSelectElement).setAttribute('multiple', props.multiple)
29+
}
30+
31+
return el
32+
},
2633

2734
createText: text => doc.createTextNode(text),
2835

0 commit comments

Comments
 (0)