我有一个有输入参数的组件。我试图在properties对象上使用解构赋值,并将变量重新赋值为不同的名称:
<script setup lang="ts">
const { modelValue: isSelected, date1: inputDate1 } = defineProps({
modelValue: Boolean,
date1: String
})
console.log(isSelected)
const date1 = 'abc'
console.log(date1)
</script>
<template>
<div v-if="isSelected">Selected!</div>
</template>
字符串
在上面的代码中,变量modelValue
被重新分配给isSelected
,date1
被重新分配给inputDate1
。
代码产生两个问题。
编辑const date1 = 'abc'
行出错
重复键“date 1”。可能会导致脚本或模板标记中的名称冲突。eslintvue/no-dupe-keys
这是一个完全虚假的错误。如果你重写代码如下:
const date2 = 'abc'
console.log(date1)
型
那么你会在console.log(date1)
行遇到另一个错误:
找不到名称“日期1”。您的意思是“日期2”吗?ts(2552)
所以很明显没有其他变量与date1
同名。那么最初的问题是什么?为什么编译器会抱怨同名?
此外,为了累加,console.log(date1)
行在运行时输出正确的值。
运行时模板抛出异常/警告
[Vue warn]:在渲染期间访问了属性“isSelected”,但未在示例上定义。
我不明白这怎么可能...台词是:
console.log(isSelected)
型
输出正确的值(true
或false
)。
所以,我还是不明白问题出在哪里。如果我去掉了解构变量的重新赋值,那么代码就不会出错:
<script setup lang="ts">
const { modelValue } = defineProps({
modelValue: Boolean
})
console.log(modelValue)
</script>
<template>
<div v-if="modelValue">Selected!</div>
</template>
型console.log(modelValue)
输出与之前相同的精确值。console.log(typeof modelValue)
打印boolean
。console.log(typeof isSelected)
也可以打印boolean
。
那有什么问题
1条答案
按热度按时间oknwwptz1#
首先要做的是:
你不能只解构props。
defineProps()
返回的props对象是React性的,解构一个React性对象会破坏React性;解构后的变量将被赋予属性的当前值(因为对象是一个代理,只有属性访问被监控)。你必须使用toRefs()
将它转换为refs对象,然后你可以解构它。好吧,实际上,我撒了一点谎。“React性属性解构”(文档页面上说React性转换已被弃用,但这个特定功能已被分离)现在是一个东西,这意味着本质上编译器重写了
字符串
到
型
有些人喜欢这样。就我个人而言,我觉得这非常不直观和混乱。每个人都有自己的。
在上面的例子中,
foo
是一个字符串,但它是秘密React的(据我所知,这是“裸”React原语脚本块中唯一的情况)。简化第一个代码块:
型
所以,你有这个错误:
重复键“date 1”。可能会导致脚本或模板标记中的名称冲突。eslintvue/no-dupe-keys
Props在模板中自动解包。也就是说,你可以像访问
window
上的属性一样访问它们,而不需要显式指定window.
;它们在顶级作用域中。props有一个名为
date1
的prop,展开意味着它将在模板中处于顶层。然后定义一个名为date1
的变量,它也将在模板中处于顶层。这两个标识符可能会冲突,这就是ESLint警告的内容。然后,您的示例编辑:
型
新的错误:
找不到名称“日期1”。您的意思是“日期2”吗?ts(2552)
这是因为props只会在模板中自动解包,而不会在脚本中自动解包,所以
date1
没有在模板中定义。此外,为了累加,
console.log(date1)
行在运行时输出正确的值。它将输出组件创建时的prop值。但它不是响应式的;即使它是响应式的,
console.log()
也不会再次运行。(好吧,它是部分响应式的;请参阅本答案的第一部分。)下一个错误:
[Vue warn]:在渲染期间访问了属性“isSelected”,但未在示例上定义。
恐怕我不能复制这个。
可能是HMR问题/故障?
我不知道你的Vue版本或配置,所以我不能说更多的细节,比如我无法复制的错误。如果你想按下这一点,请将复制的完整代码和配置添加到你的答案中,最好是Vue Playground或StackBlitz项目或类似项目的链接。
我在测试的时候做了一个Vue Playground。你可以在里面玩,也可以查看编译好的代码。