Subscribe on changes!

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

avatar
Mar 17th 2023

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

avatar
Mar 20th 2023

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"

avatar
Mar 20th 2023

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?

avatar
Mar 21st 2023

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