Skip to content

Commit 08bd81f

Browse files
committed
fix #4530 with smaller change scope
1 parent f4f3a01 commit 08bd81f

File tree

6 files changed

+28
-6
lines changed

6 files changed

+28
-6
lines changed

flow/compiler.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ declare type CompilerOptions = {
66
directives?: { [key: string]: Function }; // platform specific directives
77
isUnaryTag?: (tag: string) => ?boolean; // check if a tag is unary for the platform
88
isReservedTag?: (tag: string) => ?boolean; // check if a tag is a native for the platform
9-
mustUseProp?: (tag: string, attr: string) => ?boolean; // check if an attribute should be bound as a property
9+
mustUseProp?: (tag: string, type: ?string, name: string) => boolean; // check if an attribute should be bound as a property
1010
isPreTag?: (attr: string) => ?boolean; // check if a tag needs to preserve whitespace
1111
getTagNamespace?: (tag: string) => ?string; // check the namespace for a tag
1212
transforms?: Array<Function>; // a list of transforms on parsed AST before codegen

src/compiler/parser/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ function processAttrs (el) {
443443
name = camelize(name)
444444
}
445445
}
446-
if (isProp || platformMustUseProp(el.tag, name)) {
446+
if (isProp || platformMustUseProp(el.tag, el.attrsMap.type, name)) {
447447
addProp(el, name, value)
448448
} else {
449449
addAttr(el, name, value)

src/core/config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export type Config = {
1515
parsePlatformTagName: (x: string) => string;
1616
isUnknownElement: (x?: string) => boolean;
1717
getTagNamespace: (x?: string) => string | void;
18-
mustUseProp: (tag?: string, x?: string) => boolean;
18+
mustUseProp: (tag: string, type: ?string, name: string) => boolean;
1919
// internal
2020
_assetTypes: Array<string>;
2121
_lifecycleHooks: Array<string>;

src/core/instance/render.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ export function renderMixin (Vue: Class<Component>) {
247247
if (key === 'class' || key === 'style') {
248248
data[key] = value[key]
249249
} else {
250-
const hash = asProp || config.mustUseProp(tag, key)
250+
const type = data.attrs && data.attrs.type
251+
const hash = asProp || config.mustUseProp(tag, type, key)
251252
? data.domProps || (data.domProps = {})
252253
: data.attrs || (data.attrs = {})
253254
hash[key] = value[key]

src/platforms/web/util/attrs.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { makeMap } from 'shared/util'
44

55
// attributes that should be using props for binding
66
const acceptValue = makeMap('input,textarea,option,select')
7-
export const mustUseProp = (tag: string, attr: string): boolean => {
7+
export const mustUseProp = (tag: string, type: ?string, attr: string): boolean => {
88
return (
9-
(attr === 'value' && acceptValue(tag)) ||
9+
(attr === 'value' && acceptValue(tag)) && type !== 'button' ||
1010
(attr === 'selected' && tag === 'option') ||
1111
(attr === 'checked' && tag === 'input') ||
1212
(attr === 'muted' && tag === 'video')

test/unit/modules/vdom/patch/edge-cases.spec.js

+21
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,25 @@ describe('vdom patch: edge cases', () => {
114114
})
115115
.then(done)
116116
})
117+
118+
// #4530
119+
it('should not reset value when patching bewteen dyanmic/static bindings', done => {
120+
const vm = new Vue({
121+
data: { ok: true },
122+
template: `
123+
<div>
124+
<input type="button" v-if="ok" value="a">
125+
<input type="button" :value="'b'">
126+
</div>
127+
`
128+
}).$mount()
129+
expect(vm.$el.children[0].value).toBe('a')
130+
vm.ok = false
131+
waitForUpdate(() => {
132+
expect(vm.$el.children[0].value).toBe('b')
133+
vm.ok = true
134+
}).then(() => {
135+
expect(vm.$el.children[0].value).toBe('a')
136+
}).then(done)
137+
})
117138
})

0 commit comments

Comments
 (0)