Vue 3:“defineProps”引用本地声明的变量

And*_*ter 11 javascript eslint vue.js vuejs3 vue-sfc

为什么我收到警告错误消息:

defineProps引用本地声明的变量。eslint(vue/valid-define-props)

当我在SFC 模式的 props 中使用自定义验证器时<script setup>

<script setup>
import { validateMarkers } from "./hooks"
import { defineProps } from 'vue'

const props = defineProps({
  markers: {
    type: [Array, Object],
    validator: validateMarkers
  }
})
</script>
Run Code Online (Sandbox Code Playgroud)

我的自定义验证器:

export const validateMarkers = (markers) =>
    isNotEmpty(markers)
        ? isObject(markers)
            ? markerValidator(markers)
            : isNotEmptyArray(markers)
            ? markers.every((marker) => markerValidator(marker))
            : error('Undefined type of prop marker')
        : null
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个警告?

rol*_*oli 18

@tony19 的答案正确回答了 OP 问题,在 eslint 和 Vue 的更高版本中,您不会收到导入绑定的警告。

但如果您仍然收到警告或错误,请按以下方法修复!

首先,我们必须了解一个组件可以有 2 个作用域:

设置范围:

<script setup>
// Setup scope
</script>
Run Code Online (Sandbox Code Playgroud)

模块范围:

<script>
// Module scope
</script>
Run Code Online (Sandbox Code Playgroud)

defineProps不应引用在设置范围内声明的局部变量

因为definePropsdefineEmits将从设置中提升到模块范围中

所以下面的代码将不起作用:

<script setup>
  const sizes = ['sm', 'md']

  const props = defineProps({
    size: {
      type: String,
      validator: val => sizes.includes(val) // <= Can't reference `sizes`
    }
  })
</script>
Run Code Online (Sandbox Code Playgroud)

如何修复上面的代码?

引用模块范围内的变量!

解决方案 1. 导入的绑定位于本地范围内:
<script setup>
import { sizes } from './sizes' // <= import it

const props = defineProps({
  size: {
    type: String,
    validator: val => sizes.includes(val) // <= use it
  }
})
</script>
Run Code Online (Sandbox Code Playgroud)
解决方案 2. 在模块作用域中声明的变量(不是脚本设置):
<script setup>
const props = defineProps({
  size: {
    type: String,
    validator: val => sizes.includes(val) // <= sizes from module scope
  }
})
</script>

<script>
const sizes = ['sm', 'md'] // <= sizes can be accessed in setup scope

export default {}
</script>
Run Code Online (Sandbox Code Playgroud)


ton*_*y19 3

此警告旨在防止这种特殊用法(来自eslint(vue/valid-define-props)文档):

\n
<script setup>\n  /* \xe2\x9c\x97 BAD */\n  const def = { msg: String }\n  defineProps(def)\n</script>\n
Run Code Online (Sandbox Code Playgroud)\n

如果您实际上尝试<script setup>在构建中编译该块,编译器会发出此错误消息,该消息稍微澄清了推理:

\n
\n

defineProps()in<script setup>无法引用本地声明的变量,因为它将被提升到函数之外setup()。如果您的组件选项需要在模块范围内初始化,请使用单独的法线<script>来导出选项。

\n
\n

然而,从模块导入验证器实际上应该没问题,因为这里不用担心提升局部变量。事实上,它编译时没有错误(请参阅JSSFC 游乐场中的选项卡)。

\n

所以我认为这是一个误报,可以通过评论忽略:

\n
<script setup>\nimport { validateMarkers } from "./hooks"\nimport { defineProps } from \'vue\'\n\nconst props = defineProps({\n  markers: {\n    type: [Array, Object],            \n    validator: validateMarkers, // eslint-disable-line vue/valid-define-props\n  }\n})\n</script>\n
Run Code Online (Sandbox Code Playgroud)\n