浏览代码

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

close #2245
underfin 5 年之前
父节点
当前提交
02f355eb69

+ 7 - 0
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(

+ 5 - 0
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)

+ 7 - 0
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}`)

+ 5 - 0
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)
     }