在vue.js里面,v-for和v-if是可以一起使用作用在某个元素上,网上看到一篇文章说永远不要把v-for和v-if同时用在同一个元素上,感觉有点瞎扯,官网也注明了可以一起使用的,还把两个指令的优先级给说明了:

当v-if和v-for一起使用时,v-for的优先级更高,为了方便理解举个栗子:

<div id="app">
<ul>
<li v-for="item in Nums" v-if="item%2==0">{{item}}->偶数</li>
<li v-else-if="item%3==0">{{item}}->可以被3整除的奇数</li>
<li v-else>{{item}}->其它奇数</li>
</ul>
</div>
<script>
new Vue({
el:"#app",
data:{
Nums:[0,1,2,3,4,5,6,7,8,9,10,11,12]
}
})
</script>

比较简单昂,就是用v-for循环一个数组,然后分别用v-if、v-else-if和v-else做判断,渲染如下:

很多人刚开始一起用v-for和v-if时多少有点不习惯,如下:

<li v-for="item in Nums" v-if="item%2==0">{{item}}->偶数</li>
<li v-else-if="item%3==0">{{item}}->可以被3整除的奇数</li>
<li v-else>{{item}}->其它奇数</li>

第2和第3行<li>标签的代码里用到了item,但是item是在第一个<li>里定义了,这样不是不能获取到的吗?其实在源码内部,这三行代码都封装为一个返回一个三元表达式的函数了,作为v-for实现代码的一个参数,然后在v-for遍历数组时依次执行这函数来输出数据的

对于例子里的模板经过在编译阶段生成AST对象后会调用generate函数生成render函数,如下:

它会优先处理v-for指令,然后处于v-if、v-else-if、v-else之类的指令(可以看到v-once的优先级高于v-for和v-else),对于例子里的模板生成的render函数如下:

_c(
'div',
{attrs: {"id": "app"}},
[
_c(
'ul',
_l((Nums),function(item) {
return (item % 2 == 0) ? _c('li', [_v(_s(item) + "->偶数")])
: (item % 3 == 0) ? _c('li', [_v(_s(item) + "->可以被3整除的奇数")])
: _c('li', [_v(_s(item) + "->其它奇数")])
})
)
]
)

writer by:大沙漠 QQ:22969969

_l对应的就是v-for的实现函数,可以看到vue内部把v-if的代码封装为了一个匿名函数,传递给了v-for,而在v-for最后实现时,它是通过遍历Nums,依次执行参数2的,_l对应的函数如下:

function renderList(val, render) {              //渲染v-for指令
var ret, i, l, keys, key;
if (Array.isArray(val) || typeof val === 'string') { //如果val是个数组
ret = new Array(val.length); //将ret定义成val一样大小的数组
for (i = 0, l = val.length; i < l; i++) { //遍历val数组
ret[i] = render(val[i], i); //依次调用render函数,参数1为值 参数2为索引 返回VNode,并把结果VNode保存到ret里面   ;例子里的Nums是个数组,因此是执行到这里的
}
} else if (typeof val === 'number') {
ret = new Array(val);
for (i = 0; i < val; i++) {
ret[i] = render(i + 1, i);
}
} else if (isObject(val)) { //如果val是一个对象
keys = Object.keys(val);
ret = new Array(keys.length);
for (i = 0, l = keys.length; i < l; i++) {
key = keys[i];
ret[i] = render(val[key], key, i); //执行的时候传递三个参数,分别是值、key和索引
}
}
if (isDef(ret)) { //如果ret存在(成功调用了)
(ret)._isVList = true; //则给该数组添加一个_isVList属性,值为true
}
return ret //最后返回ret
}

对于对象来说,逻辑是一样的,只是在逻辑上多个几个细分支,就不介绍了。

Vue.js 从源码理解v-for和v-if的优先级的高低的更多相关文章

  1. 从vue.js的源码分析,input和textarea上的v-model指令到底做了什么

    v-model是 vue.js 中用于在表单表单元素上创建双向数据绑定,它的本质只是一个语法糖,在单向数据绑定的基础上,增加了监听用户输入事件并更新数据的功能:对,它本质上只是一个语法糖,但到底是一个 ...

  2. 深入Vue.js从源码开始(二)

    从入口开始 我们之前提到过 Vue.js 构建过程,在 web 应用下,我们来分析 Runtime + Compiler 构建出来的 Vue.js,它的入口是 src/platforms/web/en ...

  3. vue2.x源码理解

    也不知道哪股风潮,钻研源码竟成了深入理解的标配.我只想说一句,说的很对 准备工作 从GitHub上面下载vue的源码(https://github.com/vuejs/vue) 了解下Flow,Flo ...

  4. 一张思维导图辅助你深入了解 Vue | Vue-Router | Vuex 源码架构

    1.前言 本文内容讲解的内容:一张思维导图辅助你深入了解 Vue | Vue-Router | Vuex 源码架构. 项目地址:https://github.com/biaochenxuying/vu ...

  5. [百度地图] 用于类似 DWZ UI 框架的 百度地图 功能封装类 [MultiZMap.js] 实例源码

    MultiZMap 功能说明 MultiZMap.js 本类方法功能大多使用 prototype 原型 实现,它是 ZMap 的多加载版本,主要用于类似 DWZ 这个 多标签的 UI 的框架: 包含的 ...

  6. HashMap源码理解一下?

    HashMap 是一个散列桶(本质是数组+链表),散列桶就是数据结构里面的散列表,每个数组元素是一个Node节点,该节点又链接着多个节点形成一个链表,故一个数组元素 = 一个链表,利用了数组线性查找和 ...

  7. Caffe源码理解2:SyncedMemory CPU和GPU间的数据同步

    目录 写在前面 成员变量的含义及作用 构造与析构 内存同步管理 参考 博客:blog.shinelee.me | 博客园 | CSDN 写在前面 在Caffe源码理解1中介绍了Blob类,其中的数据成 ...

  8. 基于SpringBoot的Environment源码理解实现分散配置

    前提 org.springframework.core.env.Environment是当前应用运行环境的公开接口,主要包括应用程序运行环境的两个关键方面:配置文件(profiles)和属性.Envi ...

  9. jedis的源码理解-基础篇

    [jedis的源码理解-基础篇][http://my.oschina.net/u/944165/blog/127998] (关注实现关键功能的类)   基于jedis 2.2.0-SNAPSHOT   ...

随机推荐

  1. .NET Core Install for Ubuntu 14.04

      Add the dotnet apt-get feed In order to install .NET Core on Ubuntu or Linux Mint, you need to fir ...

  2. FluentData 学习 第一弹

    地址: http://fluentdata.codeplex.com/ 前世: FluentData 我们公司用的一个增删改查的里面的持久层.之前还不知道 这个持久层叫FluentData.  某天看 ...

  3. 安全性与收尾工作 创建基本的安全策略 精通ASP-NET-MVC-5-弗瑞曼

  4. PairProgramming 个人第三次作业

    Github地址:主仓库 https://github.com/Yanyixiao/PairProgramming.git Partner博客园地址: https://www.cnblogs.com/ ...

  5. oracle 11g数据库服务器安装

    系统:windows7旗舰版 64位.oracle数据库服务器版本:oracle11g. 一.下载   1.登录oracle账户: 首先打开谷歌浏览器,输入网址[英文版网址:https://www.o ...

  6. Shell之用户与权限

    用户与组 早期Linux系统设计为了能够实现多用户.多进程高效的利用服务器资源,在此种情况下,为了能够保证用户与用户之间的文件不被随意的访问及修改.删除等操作,用户.组的管理能在某种程序上实现管理用户 ...

  7. 探究HashMap1.8的扩容

    扩容前 扩容后 机制 else { // preserve order Node<K,V> loHead = null, loTail = null;//低指针 Node<K,V&g ...

  8. 网络收发与Nginx事件间的对应关系

    主机A可以想象是家里面的一台笔记本,也就是客户端,主机B可以想象成服务器上跑着nginx 主机A发送一个http的get请求到主机B经历了哪些请求. 在数据流: 应用层发送了一个get请求,传输层中, ...

  9. JAVA String对象和字符串常量的关系解析

    JAVA String对象和字符串常量的关系解析 1 字符串内部列表 JAVA中所有的对象都存放在堆里面,包括String对象.字符串常量保存在JAVA的.class文件的常量池中,在编译期就确定好了 ...

  10. 小白学习VUE第二课:环境搭建 VUE Node.js VSCode template模板

    环境搭建 VUE Node.js VSCode template模板: 首先安装node:http://www.runoob.com/nodejs/nodejs-install-setup.html ...