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

Vue 3: `defineProps` are referencing locally declared variables

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

defineProps are referencing locally declared variables. eslint(vue/valid-define-props)

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

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

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

我的自定义验证器:

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

如何修复此警告?

此警告旨在防止此特定用法(来自 eslint(vue/valid-define-props) docs):

<script setup>
  /* ✗ BAD */
  const def = { msg: String }
  defineProps(def)
</script>

如果您实际上 tried to compile that <script setup> block 在构建中,编译器会发出此错误消息,稍微澄清一下推理:

defineProps() in <script setup> cannot reference locally declared variables because it will be hoisted outside of the setup() function. If your component options require initialization in the module scope, use a separate normal <script> to export the options instead.

但是,从模块中导入验证器实际上应该没问题,因为这里不需要提升局部变量。事实上,它 compiles without error(请参阅 SFC 游乐场中的 JS 选项卡)。

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

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

const props = defineProps({
  markers: {
    type: [Array, Object],            
    validator: validateMarkers, // eslint-disable-line vue/valid-define-props
  }
})
</script>

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

但是如果您仍然收到警告或错误,请按照以下方法解决!

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

设置范围:

<script setup>
// Setup scope
</script>

模块范围:

<script>
// Module scope
</script>

defineProps should not reference local variables declared in setup scope

因为 definePropsdefineEmits 将被提升到模块范围之外

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

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

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

如何修复上面的代码?

模块范围内的引用变量!

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

const props = defineProps({
  size: {
    type: String,
    validator: val => sizes.includes(val) // <= use it
  }
})
</script>
解决方案 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>