vue
使用 v-if="arr.length>0"
配套 v-else
使用, v-if
和 v-else
同时生效,这算不算是一个 bug 呢?有什么办法可以解决呢?
代码:
var arr = [{title: "xxx", content: "内容"}, {title: "测试", content: "结果"}]
<a v-if="arr.length < 5" href="javascript:void(0);" v-for='list in arr'>
<div class='list'>
{{list.title}}
</div>
</a>
<a v-else>
<div v-for='list in arr'>
{{list.content}}
</div>
</a>
我用的Vue.js 1.0.26版本,确实出现的结果不是期待的那样,v-if和v-else的部分都出现了,但也不完全是那样。我的运行结果是,页面渲染了这样的三行:
前两行是第一个v-for渲染的title,后面一个是v-else元素,但是这个元素没有被编译(compile)。出现了指令未编译的情况,我觉得这算是个bug。
出现这样问题的原因是:
v-for指令优先级比v-if高
v-for是terminal的指令
细看compile过程:
compile第一个v-for元素:
由于v-for优先级比v-if高,所以先compile v-for,把v-if还是当成一个属性(attr)留在元素上。
由于v-for是terminal的指令,中断了这个a元素的子元素的compile,转而compile它的兄弟元素,即:
而compile时发现这是一个v-else指令,而对这个指令的compile规则是:如果前面的兄弟节点有v-if属性,那么就暂时跳过(skip)这个v-else对应的元素。因为v-else的显示与否是和对应v-if中的表达式的值相关联的。
之后就是实例化之前compile的v-for指令,v-for指令的terminal的,它会单独创建一个fragment,将它的子元素放进去,并从DOM上移除,之后再v-for自己生成的fragment上进行单独的部分compile(partial compile)。这里面才会去compile v-if和下面的{{list.title}}表达式。
问题就出现在这里,因为v-for在link的时候将它的子元素(含有v-if)的元素移除了,而之前v-else的元素又被跳过了,因此最后的结果就是第一个v-for执行了,后面的v-else也在,但是没有被编译执行。