`foo-bar` is not convert to `FooBar` but the code completion says so
Vue version
3.3.4
Link to minimal reproduction
Steps to reproduce
- Create a component
<script setup>
const props = defineProps({
FooBar: String
})
console.log({...props})
</script>
<template>
<h1>{{ FooBar }}</h1>
</template>
- use it like this
<script setup>
import Comp from "./Comp.vue"
</script>
<template>
<Comp :foo-bar="`hello`"/>
</template>
- see the code completion
What is expected?
renders hello
, OR code completion should not give me foo-bar
What is actually happening?
renders nothing
System Info
No response
Any additional comments?
No response
It seems that FooBar
is converted to -foo-bar
.
<Comp :foo-bar="`hello`"/>
is equal to
<Comp :fooBar="`hello`"/>
is not equal to
<Comp :FooBar="`hello`"/>
In the implementation of Vue, the key of props is only determined for equality using camelize(key)
, so fooBar
and FooBar
can coexist and represent two different props.
<script setup>
const props = defineProps({
FooBar: String,
fooBar: String
})
console.log({...props})
</script>
<template>
<h1>{{fooBar}} {{ FooBar }} </h1>
</template>
<script setup>
import Comp from "./Comp.vue"
</script>
<template>
<Comp :foo-bar="`hello`" :FooBar="`world`" />
</template>
That's definitely a bug. In that case, we have to convert FooBar
to -foo-bar
, which is not vue's shared hyphenate utility's desired output. We will use a custom hyphenate function in volar side. Fix for this issue will be available at vuejs/language-tools#3424
In fact, the hyphenate
function and the camelize
function are not reversible to each other.
For example, camelize(hyphenate('FooBar')) == 'fooBar'
, which has lost the information of the capital letter "F".
Therefore, if language-tools uses hyphenate to achieve the opposite effect of camelize, it must be aware that camelize does not perform any processing on the letter before the first hyphen. For example, the following equations must hold to achieve the expected behavior:
hyphenate('FooBar') === 'Foo-bar'
hyphenate('fooBar') === 'foo-bar'
Yes, I just simply checked if the argument begins with a capital letter. If so, I add a -
before the result
@so1ve Hmm I made a mistake when I found :-foo-bar
actually works in this case. But Iām still not sure what shall we suggest for prop FooBar
on the Volar side.