From 02f355eb69df32a03e942e01ac1de654d26916a1 Mon Sep 17 00:00:00 2001 From: underfin Date: Wed, 14 Oct 2020 04:28:24 +0800 Subject: [PATCH] fix(v-for): handle and warn when `v-for` receives non-integer range number (#2247) close #2245 --- packages/runtime-core/__tests__/helpers/renderList.spec.ts | 7 +++++++ packages/runtime-core/src/helpers/renderList.ts | 5 +++++ packages/server-renderer/__tests__/ssrRenderList.spec.ts | 7 +++++++ packages/server-renderer/src/helpers/ssrRenderList.ts | 5 +++++ 4 files changed, 24 insertions(+) diff --git a/packages/runtime-core/__tests__/helpers/renderList.spec.ts b/packages/runtime-core/__tests__/helpers/renderList.spec.ts index e28c6a00..48b2930c 100644 --- a/packages/runtime-core/__tests__/helpers/renderList.spec.ts +++ b/packages/runtime-core/__tests__/helpers/renderList.spec.ts @@ -21,6 +21,13 @@ describe('renderList', () => { ]) }) + it('should warn when given a non-integer N', () => { + renderList(3.1, () => {}) + expect( + `The v-for range expect an integer value but got 3.1.` + ).toHaveBeenWarned() + }) + it('should render properties in an object', () => { expect( renderList( diff --git a/packages/runtime-core/src/helpers/renderList.ts b/packages/runtime-core/src/helpers/renderList.ts index f8238a46..de4ab8af 100644 --- a/packages/runtime-core/src/helpers/renderList.ts +++ b/packages/runtime-core/src/helpers/renderList.ts @@ -1,5 +1,6 @@ import { VNodeChild } from '../vnode' import { isArray, isString, isObject } from '@vue/shared' +import { warn } from '../warning' /** * v-for string @@ -60,6 +61,10 @@ export function renderList( ret[i] = renderItem(source[i], i) } } else if (typeof source === 'number') { + if (__DEV__ && !Number.isInteger(source)) { + warn(`The v-for range expect an integer value but got ${source}.`) + return [] + } ret = new Array(source) for (let i = 0; i < source; i++) { ret[i] = renderItem(i + 1, i) diff --git a/packages/server-renderer/__tests__/ssrRenderList.spec.ts b/packages/server-renderer/__tests__/ssrRenderList.spec.ts index e0dab831..59b5d2dd 100644 --- a/packages/server-renderer/__tests__/ssrRenderList.spec.ts +++ b/packages/server-renderer/__tests__/ssrRenderList.spec.ts @@ -24,6 +24,13 @@ describe('ssr: renderList', () => { expect(stack).toEqual(['node 0: 1', 'node 1: 2', 'node 2: 3']) }) + it('should warn when given a non-integer N', () => { + ssrRenderList(3.1, () => {}) + expect( + `The v-for range expect an integer value but got 3.1.` + ).toHaveBeenWarned() + }) + it('should render properties in an object', () => { ssrRenderList({ a: 1, b: 2, c: 3 }, (item, key, index) => stack.push(`node ${index}/${key}: ${item}`) diff --git a/packages/server-renderer/src/helpers/ssrRenderList.ts b/packages/server-renderer/src/helpers/ssrRenderList.ts index 67c27294..bde28f25 100644 --- a/packages/server-renderer/src/helpers/ssrRenderList.ts +++ b/packages/server-renderer/src/helpers/ssrRenderList.ts @@ -1,4 +1,5 @@ import { isArray, isString, isObject } from '@vue/shared' +import { warn } from '@vue/runtime-core' export function ssrRenderList( source: unknown, @@ -9,6 +10,10 @@ export function ssrRenderList( renderItem(source[i], i) } } else if (typeof source === 'number') { + if (__DEV__ && !Number.isInteger(source)) { + warn(`The v-for range expect an integer value but got ${source}.`) + return + } for (let i = 0; i < source; i++) { renderItem(i + 1, i) }