Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attribute text on a html tag overrides inner content #12211

Open
silencerspirit opened this issue Oct 18, 2024 · 7 comments · May be fixed by #12212
Open

Attribute text on a html tag overrides inner content #12211

silencerspirit opened this issue Oct 18, 2024 · 7 comments · May be fixed by #12212

Comments

@silencerspirit
Copy link

Vue version

3.5.12

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-v477mx?file=src%2FApp.vue

Steps to reproduce

Add to html tag a attribute text

What is expected?

attribute text does not override content html tag a

What is actually happening?

attribute text overrides content html tag a

System Info

No response

Any additional comments?

No response

@DENCREAT
Copy link

same issue on 3.4.7

@jh-leong jh-leong added the 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. label Oct 18, 2024
@edison1105 edison1105 added 🔩 p2-edge-case and removed 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. labels Oct 18, 2024
@jh-leong
Copy link
Member

Thanks for reporting this.

The issue occurs because Vue sets the text as a property on the <a> element, and while <a> doesn't have a text attribute, it does have a text property via HTMLAnchorElement(https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement/text). This causes the property to override the inner content.

As a workaround, you can use ^text to prevent Vue from setting text as a prop. This will ensure that the text value is treated as an attribute instead.

@silencerspirit
Copy link
Author

Thanks for the lightning-fast response and fix! 🤝

@DENCREAT
Copy link

Thank you for the clarification.

To explain my use case a bit more, I'm encountering the issue with overriding inner content when using v-bind in combination with our CMS component, which maps its own fields to an HTML element (e.g., for a banner).

Here’s an example of what I'm working with:

const cmsBanner = {
  "id": "ui_banner_1",
  "text": "Some description",
  "target": "_blank",
  "href": "/some-href",
};
<a v-bind="cmsBanner">
  <img src="..." />
</a>

In this scenario, I’m not sure how the ^text solution would apply or help, since the text is part of the CMS data structure. Could you provide further clarification on how I might implement ^text in this case, or suggest an alternative approach to prevent the text property from overriding the inner content of the anchor tag?

Thank you in advance!

@DENCREAT
Copy link

@jh-leong thanks a lot for the quick fix

@jh-leong
Copy link
Member

In this scenario, I’m not sure how the ^text solution would apply or help, since the text is part of the CMS data structure. Could you provide further clarification on how I might implement ^text in this case, or suggest an alternative approach to prevent the text property from overriding the inner content of the anchor tag?

If the text property isn't needed, you can remove it before binding like this:

const cmsBanner = {
  id: 'ui_banner_1',
  text: 'Some description',
  target: '_blank',
  href: '/some-href',
};
const obj = { ...cmsBanner };
delete obj.text;

Playground

@tomtheisen
Copy link

In this scenario, I’m not sure how the ^text solution would apply or help, since the text is part of the CMS data structure. Could you provide further clarification on how I might implement ^text in this case, or suggest an alternative approach to prevent the text property from overriding the inner content of the anchor tag?

If the text property isn't needed, you can remove it before binding like this:

const cmsBanner = {
  id: 'ui_banner_1',
  text: 'Some description',
  target: '_blank',
  href: '/some-href',
};
const obj = { ...cmsBanner };
delete obj.text;

Playground

You can also do it this way to avoid the delete.

const { text, ...obj } = cmsBanner;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants