vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
45.65k stars 8k forks source link

Attribute Inheritance broken when comment in template root #9591

Open tanjiasong005 opened 7 months ago

tanjiasong005 commented 7 months ago

Vue version

3.3.8

Link to minimal reproduction

https://play.vuejs.org/#eNp9UsFOwzAM/RUvl4K0rkK7bd0kQJOAAyCYxCWX0XlbRppESTqGqv47Tkq7HYBb/N6z/WynZtfGjA4VsgnLXWGF8eDQV2bOlSiNth5qsLiBBjZWl5CQNOmpW12aH3yUhSBUSqZccVVo5TyUbguzkH+R3KGUGt60letBcslVnrXtqBEFHksjVx4pAsh3V/O6jslNk2cURVQoU3k4pKVeo5xxRjxnLRWNOP8lkfBCS20n8C4rnHIGGUnyrG/Ahsw7crcR29HeaUWD16FGyCuNkGifjBfknrMJRCZwKzL/+RAxbyscdnixw+LjF3zvjgHj7NmiQ3tAznrOr+wWfUsvXh/xSO+epOEqSep/yBd0WlbBYyu7qdSabJ/potv7eCOhtku3OHpUrhsqGA3KJuo5o5uF/f01+snueDSOeVw1tMXu3uHnnM5nadmDNAVaZonKQ5q22Foc4gNgKTwNGLCsA8/P03wDu53amQ==

Steps to reproduce

Create a Component with a comment in template root

<template>
<!-- comment -->
<div>
  Title
</div>
</template>

Use the component.

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

const msg = ref('Hello World!')
</script>

<template>
  <h1>{{ msg }}</h1>
  <input v-model="msg">
  <Comp style="color: blue;" />
</template>

What is expected?

image

What is actually happening?

image

System Info

No response

Any additional comments?

No response

Alfred-Skyblue commented 7 months ago

class、style、inheritAttrs are only effective when there is a single root element in the template.

https://vuejs.org/guide/components/attrs.html#attribute-inheritance

LinusBorg commented 7 months ago

Comments should be ignored in that consideration, though. They are in dev, which is making this a bug.

baiwusanyu-c commented 7 months ago

I think this is a playground bug. Vue's compiler will delete the comment node in the production mode build, but in the playground, it is a fragment.

baiwusanyu-c commented 7 months ago

image

image

Alfred-Skyblue commented 7 months ago

The behavior is inconsistent between the development and production env, and the reason is that commented-out nodes have not removed in the production env.

oliversanders commented 5 months ago

Also encountering this issue in Vue3 when migrating a Vue2 app which uses conditional (singular) roots, where there are template comments above each root option. The comments seem to be interpreted as fragments, and thus throwing the following warning about the class attribute being passed in. Attributes do not then get inherited to the current conditional root.

[Vue warn]: Extraneous non-props attributes (class) were passed to component but could not be automatically inherited because component renders fragment or text root nodes.

Without removing root-level template comments, or adding v-bind="$attrs" on every root element, this is causing inconsistent behaviour between local/dev/prod builds.

Here is a reproduction to the issue:

https://play.vuejs.org/#__PROD__eNqNVE1v2zAM/SuqLt2A2kaz7ZJlRdehh+3QFduAXXzxbCZRpy9IcpohyH8fJcWJ7DleDwEi8pF8JB+9ox+1zjct0Dld2Now7YgF1+qbUjKhlXHkkxIafwKkI0ujBLnMi8Tmgy/f99APagx/tHYRiyIWxFL4cCA0rxzgi5DFenbzk7k16aykjrF2UaArQFJeNa+s/VBSB1uXGWhKSop/URWfQh5Kqtb9r+qpv+m6J9xE5UWRdI5P6/5w/zfvcGTnE9aKKzMnPk7uw+wCjl5RZ2sll2yVP1klcY0BXlKkrhkH81U7pqQt6Twm8r6Kc/X8JdicaeGqs9drqH+P2J/s1ttK+mjAgtlASY8+V5kVuOi+//6ApBOnUE3LET3h/AZW8dZzjLC7VjZIO8EFtp+DvJhc/bD3WwfSdk15oh65D/iSorj87M+1fqL7Jn8b4nCeOMWBov05nPZicOAXWYbilg3zOcm1F3pYbZZFf8M2ZJOxJW74Atdd0mAmR1wSG/AFBoxlnp3JDNxGJmMpZ4OUiabwGUz940bL4WB3pIElk/BolLZkfzjZeKKISpyvdtjXnNwpxaGS+9fBfzxinGHMmIlKD7QYHf1FYIW48LVz2s6Lom4khjXA2cbkElwhtShuEVaYVjomIGuUuMWt5dfvsFPrUnsOVmS/jHpGeebaqAZTJRLyWYJwDV4U9mS8wF5WfBDWIzDw9Uj4+gN99b6AfYWN6gejH9SogLpd98VxDj9L8MOvzegnf0oT04pI9LD/C4sNMVk=

If you toggle between prod/dev modes and recent Vue versions v3.4 and v3.3, you will observe inconsistencies with how the class attribute is applied to the template with root-level comments.

Whilst I see there is a potential fix associated with the SFC playground (#9594), in practice I am seeing this issue on locally served dev builds (through vite) using v3.3.x. I would not expect the behaviour of attribute inheritance to differ between environments based on comments in the template - they should be ignored and not interpreted as fragments.

Edit: I note that for local dev builds using later revisions of v3.4 this seems to be now fixed, but this open issue is not linked to the specific change in the core that fixed it, so the behaviour might have been fixed by coincidence.

Edit 2: I've identified this behaviour was specifically fixed in v3.4.11, so can be considered a duplicate of https://github.com/vuejs/core/issues/5203, anybody else experiencing this should upgrade to v3.4 (v.3.4.15+) now v3.4 appears more stable.

skirtles-code commented 2 months ago

I think this is a playground bug. Vue's compiler will delete the comment node in the production mode build, but in the playground, it is a fragment.

Comments are not necessarily removed in production builds, it's controlled by a setting: https://vuejs.org/api/application.html#app-config-compileroptions-comments.

I've just tested using 3.4.23 and Vite. I can reproduce the problem described here if I set comments: true in the compilerOptions of the Vite plugin.