vuejs / core

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

@vue/compat does not pass class attr from parent to child when child has a comment node #7909

Open markrian opened 1 year ago

markrian commented 1 year ago

Vue version

@vue/compat 3.2.47

Link to minimal reproduction

https://codepen.io/markrian/pen/abajbGb

Steps to reproduce

The main code in the minimal reproduction is quite simple and self-explanatory:

const template = '<p class="bad">{{ text }}</p>';

const Child = {
  props: ["text"],
  template,
};

const ChildWithCommentNode = {
  props: ["text"],
  template: `
    <!-- A comment node -->
    ${template}
  `
};

const App = {
  components: {
    Child,
    ChildWithCommentNode,
  },
  template: `
    <Child class="good" text="this should be green and is" />
    <ChildWithCommentNode class="good" text="this should be green but is not" />
  `
};

Because of the comment node in ChildWithCommentNode's template, that instance doesn't have the good CSS class applied.

It does in Vue 2 (demo), and pure Vue 3 (demo).

What is expected?

The child component's single element node should have the class applied from the parent.

What is actually happening?

The class is not applied.

System Info

No response

Any additional comments?

No response

baiwusanyu-c commented 1 year ago

This is not a bug, there is an extra ' ' in your template, please try <!-- A comment node -->${template}, the reason for this problem is because in the compat mode of vue3, in order to ensure compatibility, the whitespace of the compiler defaults to preserve. You can circumvent this problem by modifying the configuration. app.config.compilerOptions.whitespace = "condense"

markrian commented 1 year ago

Thanks for the response, @baiwusanyu-c!

We can't set whitespace: 'condense' as that has much broader consequences.

So, you're saying that the extra whitespace means there's no single root node, so the class fallthrough doesn't apply?

baiwusanyu-c commented 1 year ago

Thanks for the response, @baiwusanyu-c!

We can't set whitespace: 'condense' as that has much broader consequences.

So, you're saying that the extra whitespace means there's no single root node, so the class fallthrough doesn't apply?

image

Yes, by observing the compiled rendering function, you will find that there is an extra whitespace, which makes it no longer a single root node, but a fragment. You know, fragments will not inherit properties from parent components of