码迷,mamicode.com
首页 > 其他好文 > 详细

Vue—v

时间:2019-10-17 18:02:12      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:ram   slot   dash   alt   val   item   param   ide   fun   

v-for 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>
<div id='app'>
<p v-for='(item, index) in arr'>{{item.name}}-{{index}}</p>
</div>
</body>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
arr:[
{id: 1, name: 'Lucy'},
{id: 2, name: 'Jack'},
{id: 3, name: 'Tom'}
]
}
})
</script>

对于v-for指令,通过processFor方法来进行解析

processFor函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function  (el) {
var exp;
if ((exp = getAndRemoveAttr(el, 'v-for'))) {
var res = parseFor(exp);
if (res) {
extend(el, res);
} else {
warn$2(
("Invalid v-for expression: " + exp),
el.rawAttrsMap['v-for']
);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var forAliasRE = /([sS]*?)s+(?:in|of)s+([sS]*)/;
function parseFor (exp) {
var inMatch = exp.match(forAliasRE);
if (!inMatch) { return }
var res = {};
res.for = inMatch[2].trim();
var alias = inMatch[1].trim().replace(stripParensRE, '');
var iteratorMatch = alias.match(forIteratorRE);
if (iteratorMatch) {
res.alias = alias.replace(forIteratorRE, '').trim();
res.iterator1 = iteratorMatch[1].trim();
if (iteratorMatch[2]) {
res.iterator2 = iteratorMatch[2].trim();
}
} else {
res.alias = alias;
}
return res
}

forAliasRE可知,v-for中使用inof是一致的

此时inMatch的值为

1
2
3
4
5
6
7
8
[
"(item, index) in arr",
"(item, index)",
"arr",
index: 0,
input: "(item, index) in arr",
groups: undefined
]

v-for有一下几种形式

1
2
3
v-for="item in items"
v-for="(item, index) in items"
v-for="(value, key, index) in object"

value是属性值,key是属性名,index是索引值

AST结构

经过静态内容处理后的p标签对应AST结构为
技术图片

下面便是根据AST结果生成对应的ren 大专栏  Vue—vder字符串

genFor函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function genFor (
el,
state,
altGen,
altHelper
) {
var exp = el.for;
var alias = el.alias;
var iterator1 = el.iterator1 ? ("," + (el.iterator1)) : '';
var iterator2 = el.iterator2 ? ("," + (el.iterator2)) : '';

if ("development" !== 'production' &&
state.maybeComponent(el) &&
el.tag !== 'slot' &&
el.tag !== 'template' &&
!el.key
) {
state.warn(
"<" + (el.tag) + " v-for="" + alias + " in " + exp + "">: component lists rendered with " +
"v-for should have explicit keys. " +
"See https://vuejs.org/guide/list.html#key for more info.",
true
);
}

el.forProcessed = true; // avoid recursion
return (altHelper || '_l') + "((" + exp + ")," +
"function(" + alias + iterator1 + iterator2 + "){" +
"return " + ((altGen || genElement)(el, state)) +
'})'
}

该函数返回了一个_l函数的字符串

1
_l((arr),function(item,index){return _c('p',[_v(_s(item.name)+"-"+_s(index))])})

_c是创建一个 vnode 对象
_v是创建一个 vnode文本节点
_l函数就是对应的renderList函数

renderList函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function renderList (
val,
render
) {
var ret, i, l, keys, key;
if (Array.isArray(val) || typeof val === 'string') {
ret = new Array(val.length);
for (i = 0, l = val.length; i < l; i++) {
ret[i] = render(val[i], i);
}
} 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)) {
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);
}
}
if (isDef(ret)) {
(ret)._isVList = true;
}
return ret
}

返回的数据
技术图片

我们这里传入的val就是arr , render 就是生成 p 段落的 render 函数
代码中的三段 if 判断是因为我们v-for可以遍历的不止数组和对象,还有数组和字符串
最终返回的 ret 是一个 VNode 数组 每一个元素都是一个 p 便签对应的 VNode

Vue—v

标签:ram   slot   dash   alt   val   item   param   ide   fun   

原文地址:https://www.cnblogs.com/sanxiandoupi/p/11693163.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!