Skip to content

Commit 096a281

Browse files
committed
fix(mp-weixin): 修复 v-for 下带 key 时,组件同时使用v-model、input事件时编译结果不正确 (question/204429)
1 parent adc799e commit 096a281

File tree

4 files changed

+61
-14
lines changed

4 files changed

+61
-14
lines changed

packages/uni-cli-shared/src/vue/utils.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,10 @@ export function createDirectiveNode(
102102
}
103103
}
104104

105-
export function createOnDirectiveNode(name: string, value: string) {
105+
export function createOnDirectiveNode(
106+
name: string,
107+
value: string | ExpressionNode
108+
) {
106109
return createDirectiveNode('on', name, value)
107110
}
108111

packages/uni-mp-compiler/__tests__/vModel.spec.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { assert } from './testUtils'
1+
import { BindingTypes } from '@vue/compiler-core'
2+
import { assert, miniProgram } from './testUtils'
23

34
describe('compiler: transform v-model', () => {
45
test(`component v-model`, () => {
@@ -107,4 +108,27 @@ describe('compiler: transform v-model', () => {
107108
}`
108109
)
109110
})
111+
test(`input v-model + v-for`, () => {
112+
assert(
113+
`<view v-for="(item,index) in props" :key="index"><input v-model="formData[item]" @input="change" /></view>`,
114+
`<view wx:for="{{a}}" wx:for-item="item" wx:key="c"><input bindinput="{{item.a}}" value="{{item.b}}"/></view>`,
115+
`(_ctx, _cache) => {
116+
return { a: _f(props, (item, index, i0) => { return { a: _o([$event => formData[item] = $event.detail.value, change], index), b: formData[item], c: index }; }) }
117+
}`,
118+
{
119+
inline: true,
120+
bindingMetadata: {
121+
formData: BindingTypes.SETUP_CONST,
122+
change: BindingTypes.SETUP_CONST,
123+
props: BindingTypes.LITERAL_CONST,
124+
},
125+
miniProgram: {
126+
...miniProgram,
127+
event: {
128+
key: true,
129+
},
130+
},
131+
}
132+
)
133+
})
110134
})

packages/uni-mp-compiler/src/transforms/vModel.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ function findDatasetEventOpts(node: ElementNode) {
233233
}
234234

235235
function parseVOn(exp: ExpressionNode, context: TransformContext) {
236+
// @ts-expect-error
237+
const rawVOnExpr = exp.__withoutKeysVOnExpr
238+
if (rawVOnExpr) {
239+
exp = rawVOnExpr
240+
}
236241
return genExpr(exp).slice(context.helperString(V_ON).length + 1, -1)
237242
}
238243

@@ -313,19 +318,24 @@ function transformVModel(
313318
: onUpdateExpr
314319
) as ExpressionNode
315320

321+
let vOnExpr: ExpressionNode | string = wrapperVOn(
322+
modifiers
323+
? wrapperVModelModifiers(vOnValue, modifiers, context, isComponent)
324+
: vOnValue,
325+
node,
326+
context
327+
)
328+
// @ts-expect-error
329+
const rawVOnExpr = vOnExpr.__withoutKeysVOnExpr
330+
vOnExpr = formatEventCode(genExpr(vOnExpr))
331+
if (rawVOnExpr) {
332+
vOnExpr = createSimpleExpression(vOnExpr, false)
333+
// @ts-expect-error
334+
vOnExpr.__withoutKeysVOnExpr = formatEventCode(genExpr(rawVOnExpr))
335+
}
316336
const vOnUpdate = createOnDirectiveNode(
317337
event || camelize(onUpdateArg.content.replace('onUpdate:', 'update-')),
318-
formatEventCode(
319-
genExpr(
320-
wrapperVOn(
321-
modifiers
322-
? wrapperVModelModifiers(vOnValue, modifiers, context, isComponent)
323-
: vOnValue,
324-
node,
325-
context
326-
)
327-
)
328-
)
338+
vOnExpr
329339
)
330340
return [vBindModelValue, vOnUpdate]
331341
}

packages/uni-mp-compiler/src/transforms/vOn.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,20 @@ export function wrapperVOn(
229229
}
230230
}
231231
}
232-
return createCompoundExpression([
232+
const newExpr = createCompoundExpression([
233233
`${context.helperString(V_ON)}(`,
234234
value,
235235
...keys,
236236
`)`,
237237
])
238+
// 严格限制生效范围,仅当有keys时,才保存原始事件表达式
239+
if (keys.length) {
240+
// @ts-expect-error 内部 parseVOn 时使用
241+
newExpr.__withoutKeysVOnExpr = createCompoundExpression([
242+
`${context.helperString(V_ON)}(`,
243+
value,
244+
`)`,
245+
])
246+
}
247+
return newExpr
238248
}

0 commit comments

Comments
 (0)