diff --git a/src/shared/util.js b/src/shared/util.js index 0054df62c8a..eda49380989 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -208,13 +208,15 @@ export function genStaticKeys (modules: Array): string { * if they are plain objects, do they have the same shape? */ export function looseEqual (a: mixed, b: mixed): boolean { - /* eslint-disable eqeqeq */ - return a == b || ( - isObject(a) && isObject(b) - ? JSON.stringify(a) === JSON.stringify(b) - : false - ) - /* eslint-enable eqeqeq */ + const isObjectA = isObject(a) + const isObjectB = isObject(b) + if (isObjectA && isObjectB) { + return JSON.stringify(a) === JSON.stringify(b) + } else if (!isObjectA && !isObjectB) { + return String(a) === String(b) + } else { + return false + } } export function looseIndexOf (arr: Array, val: mixed): number { diff --git a/test/unit/features/directives/model-checkbox.spec.js b/test/unit/features/directives/model-checkbox.spec.js index b4f300c70c2..9040628dd00 100644 --- a/test/unit/features/directives/model-checkbox.spec.js +++ b/test/unit/features/directives/model-checkbox.spec.js @@ -159,6 +159,40 @@ describe('Directive v-model checkbox', () => { expect(vm.check).toEqual(false) }) + it('should respect different primitive type value', (done) => { + const vm = new Vue({ + data: { + test: [0] + }, + template: + '
' + + '' + + '' + + '' + + '
' + }).$mount() + var checkboxInput = vm.$el.children + expect(checkboxInput[0].checked).toBe(false) + expect(checkboxInput[1].checked).toBe(true) + expect(checkboxInput[2].checked).toBe(false) + vm.test = [1] + waitForUpdate(() => { + expect(checkboxInput[0].checked).toBe(false) + expect(checkboxInput[1].checked).toBe(false) + expect(checkboxInput[2].checked).toBe(true) + vm.test = [''] + }).then(() => { + expect(checkboxInput[0].checked).toBe(true) + expect(checkboxInput[1].checked).toBe(false) + expect(checkboxInput[2].checked).toBe(false) + vm.test = ['', 0, 1] + }).then(() => { + expect(checkboxInput[0].checked).toBe(true) + expect(checkboxInput[1].checked).toBe(true) + expect(checkboxInput[2].checked).toBe(true) + }).then(done) + }) + it('warn inline checked', () => { const vm = new Vue({ template: ``, diff --git a/test/unit/features/directives/model-radio.spec.js b/test/unit/features/directives/model-radio.spec.js index 26e6ffed119..26ddb2db19c 100644 --- a/test/unit/features/directives/model-radio.spec.js +++ b/test/unit/features/directives/model-radio.spec.js @@ -146,6 +146,35 @@ describe('Directive v-model radio', () => { expect(vm.test).toBe(2) }) + it('should respect different primitive type value', (done) => { + const vm = new Vue({ + data: { + test: 1 + }, + template: + '
' + + '' + + '' + + '' + + '
' + }).$mount() + var radioboxInput = vm.$el.children + expect(radioboxInput[0].checked).toBe(false) + expect(radioboxInput[1].checked).toBe(false) + expect(radioboxInput[2].checked).toBe(true) + vm.test = 0 + waitForUpdate(() => { + expect(radioboxInput[0].checked).toBe(false) + expect(radioboxInput[1].checked).toBe(true) + expect(radioboxInput[2].checked).toBe(false) + vm.test = '' + }).then(() => { + expect(radioboxInput[0].checked).toBe(true) + expect(radioboxInput[1].checked).toBe(false) + expect(radioboxInput[2].checked).toBe(false) + }).then(done) + }) + it('warn inline checked', () => { const vm = new Vue({ template: ``, diff --git a/test/unit/features/directives/model-select.spec.js b/test/unit/features/directives/model-select.spec.js index 5aaae884c7f..23a6361b15c 100644 --- a/test/unit/features/directives/model-select.spec.js +++ b/test/unit/features/directives/model-select.spec.js @@ -310,7 +310,7 @@ describe('Directive v-model select', () => { '' }).$mount() document.body.appendChild(vm.$el) @@ -319,6 +319,35 @@ describe('Directive v-model select', () => { expect(vm.test).toBe(1) }) + it('should respect different pritive type value', (done) => { + const vm = new Vue({ + data: { + test: 0 + }, + template: + '' + }).$mount() + var opts = vm.$el.options + expect(opts[0].selected).toBe(false) + expect(opts[1].selected).toBe(true) + expect(opts[2].selected).toBe(false) + vm.test = 1 + waitForUpdate(() => { + expect(opts[0].selected).toBe(false) + expect(opts[1].selected).toBe(false) + expect(opts[2].selected).toBe(true) + vm.test = '' + }).then(() => { + expect(opts[0].selected).toBe(true) + expect(opts[1].selected).toBe(false) + expect(opts[2].selected).toBe(false) + }).then(done) + }) + it('should warn inline selected', () => { const vm = new Vue({ data: {