(九)终端指令

终端指令

有些指令我们希望在编译它之前先不要编译它的子节点,这种指令我们定义为终端指令即Terminal Directives。比如v-if、v-for这种都是终端指令。

实现

1
2
3
4
5
6
7
function compileElement (el) {
var hasAttrs = el.hasAttributes()
var attrs = hasAttrs && toArray(el.attributes)
if (!checkTerminalDirectives(el, attrs)) {
compileDirectives(el, attrs)
}
}

我们在compileDirectives之前加入了checkTerminalDirectives功能,checkTerminalDirectives首先遍历所有的指令然后解析,如果指令定义中的terminal属性为true,则该指令是一个终端指令,对于后续的指令解析不再进行。

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 checkTerminalDirectives (el, attrs) {
// skip v-else block, but only if following v-if
if (el.hasAttribute('v-else')) {
var prev = el.previousElementSibling
if (prev && prev.hasAttribute('v-if')) {
return skip
}
}
var attr, name, value, matched, arg, def
for (var i = 0, j = attrs.length; i < j; i++) {
attr = attrs[i]
name = attr.name
if ((matched = name.match(dirAttrRE))) {
def = publicDirectives[matched[1]]
if (def && def.terminal) {
isTerminal = true
var descriptor = {
name: matched[1],
raw: attr.value,
attr: attr.name,
arg: matched[2],
expression: attr.value,
def: def
}
vm._bindDir(descriptor, el)
return true
}
}
}
return false
}