diff --git a/packages/runtime-core/__tests__/helpers/renderList.spec.ts b/packages/runtime-core/__tests__/helpers/renderList.spec.ts index e28c6a004ce..48b2930c11f 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 f8238a46a16..de4ab8afa7f 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 e0dab83117b..59b5d2ddf27 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 67c27294358..bde28f25759 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) }