Skip to content

Commit 56bfa1d

Browse files
defccyyx990803
authored andcommitted
update loose equal, check toString value for primitive type (vuejs#4528)
1 parent fd55399 commit 56bfa1d

File tree

4 files changed

+102
-8
lines changed

4 files changed

+102
-8
lines changed

src/shared/util.js

+9-7
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,15 @@ export function genStaticKeys (modules: Array<ModuleOptions>): string {
208208
* if they are plain objects, do they have the same shape?
209209
*/
210210
export function looseEqual (a: mixed, b: mixed): boolean {
211-
/* eslint-disable eqeqeq */
212-
return a == b || (
213-
isObject(a) && isObject(b)
214-
? JSON.stringify(a) === JSON.stringify(b)
215-
: false
216-
)
217-
/* eslint-enable eqeqeq */
211+
const isObjectA = isObject(a)
212+
const isObjectB = isObject(b)
213+
if (isObjectA && isObjectB) {
214+
return JSON.stringify(a) === JSON.stringify(b)
215+
} else if (!isObjectA && !isObjectB) {
216+
return String(a) === String(b)
217+
} else {
218+
return false
219+
}
218220
}
219221

220222
export function looseIndexOf (arr: Array<mixed>, val: mixed): number {

test/unit/features/directives/model-checkbox.spec.js

+34
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,40 @@ describe('Directive v-model checkbox', () => {
159159
expect(vm.check).toEqual(false)
160160
})
161161

162+
it('should respect different primitive type value', (done) => {
163+
const vm = new Vue({
164+
data: {
165+
test: [0]
166+
},
167+
template:
168+
'<div>' +
169+
'<input type="checkbox" value="" v-model="test">' +
170+
'<input type="checkbox" value="0" v-model="test">' +
171+
'<input type="checkbox" value="1" v-model="test">' +
172+
'</div>'
173+
}).$mount()
174+
var checkboxInput = vm.$el.children
175+
expect(checkboxInput[0].checked).toBe(false)
176+
expect(checkboxInput[1].checked).toBe(true)
177+
expect(checkboxInput[2].checked).toBe(false)
178+
vm.test = [1]
179+
waitForUpdate(() => {
180+
expect(checkboxInput[0].checked).toBe(false)
181+
expect(checkboxInput[1].checked).toBe(false)
182+
expect(checkboxInput[2].checked).toBe(true)
183+
vm.test = ['']
184+
}).then(() => {
185+
expect(checkboxInput[0].checked).toBe(true)
186+
expect(checkboxInput[1].checked).toBe(false)
187+
expect(checkboxInput[2].checked).toBe(false)
188+
vm.test = ['', 0, 1]
189+
}).then(() => {
190+
expect(checkboxInput[0].checked).toBe(true)
191+
expect(checkboxInput[1].checked).toBe(true)
192+
expect(checkboxInput[2].checked).toBe(true)
193+
}).then(done)
194+
})
195+
162196
it('warn inline checked', () => {
163197
const vm = new Vue({
164198
template: `<input type="checkbox" v-model="test" checked>`,

test/unit/features/directives/model-radio.spec.js

+29
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,35 @@ describe('Directive v-model radio', () => {
146146
expect(vm.test).toBe(2)
147147
})
148148

149+
it('should respect different primitive type value', (done) => {
150+
const vm = new Vue({
151+
data: {
152+
test: 1
153+
},
154+
template:
155+
'<div>' +
156+
'<input type="radio" value="" v-model="test" name="test">' +
157+
'<input type="radio" value="0" v-model="test" name="test">' +
158+
'<input type="radio" value="1" v-model="test" name="test">' +
159+
'</div>'
160+
}).$mount()
161+
var radioboxInput = vm.$el.children
162+
expect(radioboxInput[0].checked).toBe(false)
163+
expect(radioboxInput[1].checked).toBe(false)
164+
expect(radioboxInput[2].checked).toBe(true)
165+
vm.test = 0
166+
waitForUpdate(() => {
167+
expect(radioboxInput[0].checked).toBe(false)
168+
expect(radioboxInput[1].checked).toBe(true)
169+
expect(radioboxInput[2].checked).toBe(false)
170+
vm.test = ''
171+
}).then(() => {
172+
expect(radioboxInput[0].checked).toBe(true)
173+
expect(radioboxInput[1].checked).toBe(false)
174+
expect(radioboxInput[2].checked).toBe(false)
175+
}).then(done)
176+
})
177+
149178
it('warn inline checked', () => {
150179
const vm = new Vue({
151180
template: `<input v-model="test" type="radio" value="1" checked>`,

test/unit/features/directives/model-select.spec.js

+30-1
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ describe('Directive v-model select', () => {
310310
'<select v-model.number="test">' +
311311
'<option value="1">a</option>' +
312312
'<option :value="2">b</option>' +
313-
' <option :value="3">c</option>' +
313+
'<option :value="3">c</option>' +
314314
'</select>'
315315
}).$mount()
316316
document.body.appendChild(vm.$el)
@@ -319,6 +319,35 @@ describe('Directive v-model select', () => {
319319
expect(vm.test).toBe(1)
320320
})
321321

322+
it('should respect different pritive type value', (done) => {
323+
const vm = new Vue({
324+
data: {
325+
test: 0
326+
},
327+
template:
328+
'<select v-model.number="test">' +
329+
'<option value="">a</option>' +
330+
'<option value="0">b</option>' +
331+
'<option value="1">c</option>' +
332+
'</select>'
333+
}).$mount()
334+
var opts = vm.$el.options
335+
expect(opts[0].selected).toBe(false)
336+
expect(opts[1].selected).toBe(true)
337+
expect(opts[2].selected).toBe(false)
338+
vm.test = 1
339+
waitForUpdate(() => {
340+
expect(opts[0].selected).toBe(false)
341+
expect(opts[1].selected).toBe(false)
342+
expect(opts[2].selected).toBe(true)
343+
vm.test = ''
344+
}).then(() => {
345+
expect(opts[0].selected).toBe(true)
346+
expect(opts[1].selected).toBe(false)
347+
expect(opts[2].selected).toBe(false)
348+
}).then(done)
349+
})
350+
322351
it('should warn inline selected', () => {
323352
const vm = new Vue({
324353
data: {

0 commit comments

Comments
 (0)