Currently we have an boolean option for vue-template-compiler
: preserveWhitespace
. It either removes all whitespace-only text nodes, or leave them untouched. There were already earlier questions about either behavior: #6200, #7701, #9021, #9127. I think the current behavior is kind of oversimplified to cover actual usage.
When we write a template we tend to leverage line breaks and indents to make it more readable, like:
<div class="item">
<div class="aside">Aside</div>
<div class="main">Main</div>
</div>
And if we choose to layout this component with inline formatting context, sometimes we may not want to precisely control the margin between the inner parts with CSS, instead of using the size of a whitespace (which is related to those font-*
styles). For similar cases we don't want these whitespace-only text nodes. This leads to preserveWhitespace: false
(and it even became the default behavior for Vue CLI 3: https://github.com/vuejs/vue-cli/commit/1864cef09e186cdf094fca876f8638a8ba1b4adb).
But when we craft some document/article-like content, this behavior becomes annoying. With preserveWhitespace: false
, the following template:
<p>
Welcome to <b>Vue.js</b> <i>world</i>.
Have fun!
</p>
Will generate:
<p>
Welcome to <b>Vue.js</b><i>world</i>.
Have fun!
</p>
Which looks like:
Welcome to Vue.jsworld. Have fun!
And this is clearly not desired.
In short, I suggest we offer a new compiler option, to apply the strategy React uses to handles whitespaces for JSX (source):
JSX removes whitespace at the beginning and ending of a line. It also removes blank lines. New lines adjacent to tags are removed; new lines that occur in the middle of string literals are condensed into a single space.
For examples:
<p>
Welcome to <b>Vue.js</b> <i>world</i>.
Have fun!
</p>
The whitespaces between <p>
and Welcome
are removed but the one between </b>
and <i>
and the one between .
and Have
are preserved thus giving us:
<p>Welcome to <b>Vue.js</b> <i>world</i>. Have fun!</p>
This seem to be much more reasonable IMO. And in this mode users will have more flexibility to better serve their different purposes.
In general, the proposal is:
preserveWhitespace
but mark it as deprecated.removeWhitespace: 'with-line-break' | 'any' | 'none'
.preserveWhitespace
if removeWhitespace
is specified.(Still need more suggestions on specific API.)
A summary of what is landed in e1abedb9:
whitespace
'preserve'
or 'condense'
.'preserve'
(exactly the same default behavior as it is now)preserveWhitespace
when a specific value is provided'condense'
:In condense
mode, the example template
<p>
Welcome to <b>Vue.js</b> <i>world</i>.
Have fun!
</p>
will be compiled as:
<p> Welcome to <b>Vue.js</b> <i>world</i>. Have fun! </p>
Essentially, this provides:
The reason for not entirely removing leading/ending whitespaces inside an element:
<span>foo</span>
<span>
bar
</span>
Will render as foo bar
instead of foobar
. This is also consistent with the current behavior.
We will likely use this new condense behavior as the default in 3.0.
I think this new option should also be added to vue-loader.
@a1p4ca vue-loader has compilerOptions which just passes through to the template compiler.
Hey, sorry for bumping a closed topic, but is this meant to also condense whitespace from html entities like
?
For example, in this part, the second
is not preserved while the first one is:
<span>
<inline-button text="1" />
<template v-if="someCondition">
<inline-button text="2" />
</template>
<inline-button text="3" />
</span>
Resulting in the buttons rendering like: 1 23
I tried making it preserve the by wrapping it in a span and even doing something silly like:
<span> </span>
which ended up being output as <span></span>
.
Most helpful comment
A summary of what is landed in e1abedb9:
whitespace
'preserve'
or'condense'
.'preserve'
(exactly the same default behavior as it is now)preserveWhitespace
when a specific value is provided'condense'
:In
condense
mode, the example templatewill be compiled as:
Essentially, this provides:
The reason for not entirely removing leading/ending whitespaces inside an element:
Will render as
foo bar
instead offoobar
. This is also consistent with the current behavior.We will likely use this new condense behavior as the default in 3.0.