在Vue單文件組件的template標籤上使用v-if不生效的原因

今天晚上,我在某個組件裏看到了這樣一段代碼,簡化來講,大概長這樣:

// 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就能用呢?因爲這兩個根本不是一個東西,只是正好同名了而已。最外面的那個只是一個佔位符,裏面的則有實際的用途。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章