fix(v-for): handle and warn when v-for receives non-integer range number (#2247)

close #2245
This commit is contained in:
underfin 2020-10-14 04:28:24 +08:00 committed by GitHub
parent 8539c0bf32
commit 02f355eb69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 0 deletions

View File

@ -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', () => { it('should render properties in an object', () => {
expect( expect(
renderList( renderList(

View File

@ -1,5 +1,6 @@
import { VNodeChild } from '../vnode' import { VNodeChild } from '../vnode'
import { isArray, isString, isObject } from '@vue/shared' import { isArray, isString, isObject } from '@vue/shared'
import { warn } from '../warning'
/** /**
* v-for string * v-for string
@ -60,6 +61,10 @@ export function renderList(
ret[i] = renderItem(source[i], i) ret[i] = renderItem(source[i], i)
} }
} else if (typeof source === 'number') { } 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) ret = new Array(source)
for (let i = 0; i < source; i++) { for (let i = 0; i < source; i++) {
ret[i] = renderItem(i + 1, i) ret[i] = renderItem(i + 1, i)

View File

@ -24,6 +24,13 @@ describe('ssr: renderList', () => {
expect(stack).toEqual(['node 0: 1', 'node 1: 2', 'node 2: 3']) 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', () => { it('should render properties in an object', () => {
ssrRenderList({ a: 1, b: 2, c: 3 }, (item, key, index) => ssrRenderList({ a: 1, b: 2, c: 3 }, (item, key, index) =>
stack.push(`node ${index}/${key}: ${item}`) stack.push(`node ${index}/${key}: ${item}`)

View File

@ -1,4 +1,5 @@
import { isArray, isString, isObject } from '@vue/shared' import { isArray, isString, isObject } from '@vue/shared'
import { warn } from '@vue/runtime-core'
export function ssrRenderList( export function ssrRenderList(
source: unknown, source: unknown,
@ -9,6 +10,10 @@ export function ssrRenderList(
renderItem(source[i], i) renderItem(source[i], i)
} }
} else if (typeof source === 'number') { } 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++) { for (let i = 0; i < source; i++) {
renderItem(i + 1, i) renderItem(i + 1, i)
} }