Whitespace is incorrectly stripped between tags in string templates
Version
3.0.1
Reproduction link
https://codepen.io/stowball/pen/VwjjQmr
Steps to reproduce
- Create a new app whose template is a tagged template literal with multiple tags with whitespace in-between
What is expected?
For the whitespace to be maintained, like in Vue 2 https://codepen.io/stowball/pen/ExyyQmN
What is actually happening?
All whitespace between tags is removed
Oh wow. Any template does it!
Here's an SFC: https://codepen.io/stowball/pen/MWeeQXK
Here's a UMD build using the app's innerHTML
: https://codepen.io/stowball/pen/LYZZQmO
This is an intended change. v3 uses the equivalent of v2's whitespace: 'condense'
in all cases, so whitespace between tags are only preserved if it contains no newlines:
<div>
<span>{{ foo }}</span> <span>{{ baz }}</span>
</div>
See https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler#options
I believe in v2 CLI scaffolded apps already use this behavior by default. In v3 this applies to runtime-compiled templates too.
I would have to say that this is a bad change. Many teams, mine included, use new lines exclusively between tags, including those in "sentences".
This change basically breaks many of our layouts where, for example, we intentionally bold words besides hyperlinks.
It is reasonable to expect that the compiled template behave exactly like the raw HTML provided, just with interpolations replaced, especially when the template was provided by said HTML file. HTML smartly handles all whitespace between tags, providing inline
superpowers, and so should Vue imo.
Looks like the same problem I’m having. https://stackoverflow.com/questions/64432182/vue-3-removes-white-space-between-inline-block-elements.
This is a breaking change from version 2 that I haven’t seen documented. I also agree it shouldn’t change what the user intended (raw HTML). There’s other solutions to this problem (e.g. using comments between the tags) which should be down to the user and not the compiler.
I've realized also inline v-if/v-else
is not work a migrated code from Vue2 in Vue3.
<div>
<div v-if="1">ccc</div> <div v-else>ddd</div>
</div>
Then I get,
[Vue warn]: Template compilation error: v-else/v-else-if has no adjacent v-if.
13 |
14 | <div>
15 | <div v-if="1">ccc</div> <div v-else>ddd</div>
| ^^^^^^^^^^^^^^^^^^^^^
16 | </div>
17 |
at <App>
But, when I use new line is only fine, not space(s) or tab(s).
<div>
<div v-if="1">ccc</div>
<div v-else>ddd</div>
</div>
with no errors.
My develop environments minify newline to space automatically like,
from
<div v-if="1">ccc</div>
<div v-else>ddd</div>
to
<div v-if="1">ccc</div> <div v-else>ddd</div>
So I'm getting tons of Vue warning when I try using Vue3... My temporary solutions are,
Solution 01
<div v-if="1">
ccc
</div><div v-else>
ddd
</div>
Solution 02
<div v-if="1">ccc</div><!--
--><div v-else>ddd</div>
Is there anyone who has a better idea for is issue? I'm thinking if I have to give up migration from Vue2 to Vue3.
This is an intended change. v3 uses the equivalent of v2's whitespace: 'condense' in all cases, so whitespace between tags are only preserved if it contains no newlines
@yyx990803 I'd like to also weigh in on this not being an ideal behavior, especially as a default.
This ended up causing a lot of unfortunate behavior for us in trying to migrate to vue 3 (and ultimately stopped us altogether). We had many places where text that used tags for things like highlighting or in-line formatting which ended up jumbled because vue 3 decided to ignore normal HTML whitespace rules.
Fundamentally, I feel like the issue is a lack of consistency between vue and HTML. Consider that in plain HTML, this: <i>a</i> <i>b</i>\n<i>c</i>
renders as "a b c". In vue-2, this renders as "a b c". In vue-3, this renders as "a bc". Having a paragraph or even a single sentence broken up across multiple lines in HTML is not exactly a strange behavior, and the fact that Vue-3 diverges from expectation was problematic.
As a user of pre-built, CDN-supplied Vue libraries in various websites, I am still looking for a way to modify the compiler behavior to the vue-2 default in vue-3. I asked around in the vue discord, and while there were people who both agreed and disagreed with what vue-3 should do, none of us could find a means to get the HTML behavior out of a CDN-hosted Vue.