Subscribe on changes!

It's not possible to access a kebab-cased attribute as camel-case and other way around in attrs

avatar
Nov 25th 2021

Version

3.2.22

Reproduction link

sfc.vuejs.org/

Steps to reproduce

  • Pass an aria-label to a component with :aria-label="foo" and :ariaLabel="foo"
  • Read the attribute in the component with the attrs parameter.

Parent.vue

<script setup>
import { ref } from 'vue'
import Comp from './Comp.vue';

const ariaLabel = 'This is an aria-label';
</script>

<template>
  <Comp aria-label="This is an aria-label" />
  <Comp :aria-label="ariaLabel" />
  <Comp :ariaLabel="ariaLabel" />
</template>

Comp.vue

<script setup>
import { ref, useAttrs, computed } from 'vue'

const attrs = useAttrs();
const hasKebabCaseAriaLabel = computed(() => Boolean(attrs['aria-label']));
const hasCamelCaseAriaLabel = computed(() => Boolean(attrs.ariaLabel));
</script>

<template>
  <div>
    <div>
      kebab-case attr: {{ hasKebabCaseAriaLabel }}
    </div>
    <div>
      camelCase attr: {{ hasCamelCaseAriaLabel }}
    </div>
    
    <hr />
  </div>
</template>

Output: ``` kebab-case attr: true camelCase attr: false

kebab-case attr: true camelCase attr: false

kebab-case attr: false camelCase attr: true


```html
<div aria-label="This is an aria-label"></div>
<div aria-label="This is an aria-label"></div>
<div aria-label="This is an aria-label"></div>

What is expected?

Vue should be able to infer an attribute regardless of is case as they are used camel-cased in the HTML.

aria-label in this example, will be used as camel-case in all three usages.

What is actually happening?

When aria-label is passed with kebab-case attrs.ariaLabel returns undefined and when it's passed with camel-case attrs['aria-label'] returns undefined.

avatar
Nov 25th 2021

I would say this is expected because that's how HTML attributes and are not adapted like props are when it comes to their naming. Also, this would be a breaking change

avatar
Nov 25th 2021

It's sad to hear it would be a breaking change because it's controversial to be able to pass attributes in both cases while creating elements but not possible to read them in the same way.

Here is an example to that uses both cases to create elements.

This would make library developers' lives easier.

avatar
Dec 4th 2021

@posva That's not the case. In SVG elements, not only the attributes are case sensitive, even the tags them selves are. This is a fundamental problem with Vue and that's a reason why I choose to create my own framework.

avatar
Dec 5th 2021

Not saying that there's no room to optimize SVG-related stuff, but I don't see how that's related to the specific issue here?

avatar
Dec 5th 2021

Not saying that there's no room to optimize SVG-related stuff, but I don't see how that's related to the specific issue here?

You're not realizing that tags appear in html can have and do have case sensitive attributes and tag names, which vue have completely no way to deal with.

Not mentioning XML namespaces which vue relies on for its v-xxx directives, users just can't deal with custom namespaces using vue.

avatar
Dec 5th 2021

I'm aware of that Vue does handle SVG differently: it has a built-in list of tags and attributes that are marked as SVG related. That's a very stubborn way of telling if a tag should be svg: once SVG adds some new attributes to it and it's not on the built-in list, users will have no way but dirty hacks to get it working. One other way of the story is that most users just don't have the need to deal with SVGs and the part of code for handling SVGs are just built-in with no-way to strip them out for those who don't need them.

This is probably off-topic but I have to mention here:

The same thing applies to all other scenarios that Vue attemps to "take care" for users: Users won't have a chance to deal with custom namespaces/strange or non-standard runtimes/built-in keywords etc, and once users want to handle things more manually or more detailed, they will fail and have no way to solve the problem within the "beauty" of Vue.

Just think about the feeling of sitting on an automated vehicle whose computer went mad but you have no way to take over.