今天晚上,我在某个组件里看到了这样一段代码,简化来讲,大概长这样:

// Child.vue
<template v-if="false">
  <div>Foo</div>
</template>

// Parent.vue
<template>
  <Child />
</template>

按理来说,这里应该什么都不出现,但是子组件里的Foo却正常显示了。换成下面两种写法组件就能正常隐藏了。

第一种:

// Child.vue
<template>
  <div v-if="false">Foo</div>
</template>

// Parent.vue
<template>
  <Child />
</template>

第二种:

// Child.vue
<template>
  <div>Foo</div>
</template>

// Parent.vue
<template>
  <Child v-if="false"/>
</template>

我一开始怀疑是template的问题,但是官方文档有使用template的写法:

因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个 元素当做不可见的包裹元素,并在上面使用v-if。最终的渲染结果将不包含 元素。

<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>

后来看了一下vue-loader的文档,发现了这么一段:

模板

  • 每个 .vue 文件最多包含一个 <template>块。
  • 内容将被提取并传递给 vue-template-compiler 为字符串,预处理为 JavaScript 渲染函数,并最终注入到从 <script> 导出的组件中。

意思是,单文件组件的template相当于是一个标明需要交给Vue的渲染函数进行处理的内容范围的占位符,webpack处理的时候会直接提取出最外层template内的内容,忽略掉template这个标签本身,所以写在template上的属性和指令都是没有用的。

那为什么写在里面的template就能用呢?因为这两个根本不是一个东西,只是正好同名了而已。最外面的那个只是一个占位符,里面的则有实际的用途。

Logo

前往低代码交流专区

更多推荐