使用template进行条件渲染

如下所示,有一段内容:

<h1>尊贵的年费会员</h1>
<div>此处内容仅年费会员可见!</div>
<h1>亲爱的普通用户</h1>
<div>您不是年费会员无权访问,请前往用户中心充值!</div>

这段内容如果想要加v-if进行条件渲染,一种做法是在外面套一个<div>,代码如下:

<div v-if="hasAuthority">
	<h1>尊贵的年费会员</h1>
	<div>此处内容仅年费会员可见!</div>
</div>
<div v-else>
	<h1>亲爱的普通用户</h1>
	<div>您不是年费会员无权访问,请前往用户中心充值!</div>
</div>

但这样的话,渲染出来的html就会多出没用的div,这种情况下可以使用<template>,它可以作为不可见的包裹元素,最终渲染结果将不包含<template>,代码如下:

<template v-if="hasAuthority">
	<h1>尊贵的年费会员</h1>
	<div>此处内容仅年费会员可见!</div>
</template>
<template v-else>
	<h1>亲爱的普通用户</h1>
	<div>您不是年费会员无权访问,请前往用户中心充值!</div>
</template>

为什么不推荐使用template进行列表渲染

Vue官方文档上给了一个案例,使用template进行列表渲染:

vue3在template上加方法 vue template key_Vue


本人自己也去试了一下,这样的做法本身没有问题,<template>可以进行列表渲染。但是熟悉Vue的同学都知道,v-for需要绑定key,这样才能让虚拟DOM高效更新。问题就出在这里,如果试图给<template>绑定key,那么控制台就会报错:

<template> cannot be keyed. Place the key on real elements instead.

相信大家看到这个提示就明白问题出在哪里了。上一节内容讲到,<template>元素不会出现在最终的渲染结果中。假如给<template>元素绑定key,相当于key值就丢失了,等于没有绑定。

有的同学可能会问,key可以给内部元素绑定吗?答案是可以的,但强烈不推荐。原因是如果内部有很多平级的元素,就得给每个元素都加一个key,如下所示:

<ul>
	<template v-for="(item, index) in items">
		<li :key="item.id">{{ item.msg }}</li>
		<li class="divider" :key="item.id"></li>
	</template>
</ul>

别以为这样就没问题了,按上面的逻辑,每一次循环就会有两个元素带有一模一样的key,显然这样是会报错的:

[Vue warn]: Duplicate keys detected: ‘xxx’. This may cause an update error

所以最好的解决方案就是不要使用<template>进行列表渲染。