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
因为 defineProps
和 defineEmits
将被提升到模块范围之外
所以下面的代码将不起作用:
<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>
为什么我收到警告错误消息:
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 thesetup()
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
因为 defineProps
和 defineEmits
将被提升到模块范围之外
所以下面的代码将不起作用:
<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>