写vue3时发现了一个很神奇的bug,setup + defineProps + interface 同时使用会导致冲突
报错代码:
<script setup lang="ts">
interface searchElement {
name: string
value: string
label?: string
}
const props = defineProps<{
items: searchElement[]
}>()
</script>
上述代码的报错是
Default export of the module has or is using private name 'searchElement'.
解决方案
将interface放在另一个script代码块,不要加setup※
<script lang="ts">
interface searchElement {
name: string
value: string
label?: string
}
</script>
<script setup lang="ts">
const props = defineProps<{
items: searchElement[]
}>()
</script>
完美解决
问题分析
这个bug耗费了我大量时间,网上又没有相关的文章,经过无数尝试后发现居然是
setup + defineProps + interface 同时使用导致的冲突......
如果这样写,则不会报错:(定义了但没有使用 interface )
<script setup lang="ts">
interface searchElement {
name: string
value: string
label?: string
}
const props = defineProps<{
items: string[]
}>()
</script>
这样写,也不会报错:(使用了但没有在 difineProps 中使用 interface )
<script setup lang="ts">
import { ref, reactive } from 'vue'
interface searchElement {
name: string
value: string
label?: string
}
let a = reactive<searchElement>({
name: '', value: ''
})
</script>
使用外部import的 interface 也不会报错
只有在 setup 中定义了 interface 并且刚好在 defineProps 中使用了这个 interface 才会报错
众所周知,setup语法糖
<script setup lang="ts">
</script>
实际上是
export default {
setup() {
// ....
}
}
的简写
并且在 setup 中暴漏了三个编译器宏函数:defineProps、defineEmits、defineExpose
问题显然是出在 setup 语法糖中,编译器宏函数与 interface 的定义在内部产生了某些奇妙的化学反应, 又由于 defineEmits 和 defineExpose 不需要使用 interface, 所以问题只集中在 defineProps 一个函数上
这个触发概率可谓是十分的低了.......