开篇
下面主要将template里面包含的slot插槽,指令,属性,自定义事件,自定义指令,过滤器,组件,标签等转换为ast
slot插槽
匿名插槽
<!--template-->
Vue.component('slot1',{
template : `<div>
<slot></slot>
</div>`
})
<slot1>匿名插槽</slot1>
<!--ast-->
{
attrsList: []
attrsMap: {},
children : [
{type: 3, text: '匿名插槽'}
],
rawAttrsMap : {},
tag: "slot1",
type: 1
}
具名插槽
<!--template-->
Vue.component('slot2',{
template : `
<div>
<slot name='header'></slot>
</div>
`
})
<slot2><template #header>具名插槽</template></slot2>
<!--ast-->
{
attrsList: [],
attrsMap: {},
children: [],
rawAttrsMap: {},
scopedSlots : {
"header" : {
attrsList: [],
attrsMap: {#header: ''},
children : [{type: 3, text: '具名插槽'}],
rawAttrsMap : {
#header: {name: '#header', value: ''}
},
slotScope: "_empty_",
slotTarget: ""header"",
slotTargetDynamic: false,
tag: "template",
type: 1
}
},
tag: "slot2",
type: 1
}
作用域插槽
<!--template-->
<slot3><template v-slot:header="user">{{user}}</template></slot3>
Vue.component('slot3',{
template : `
<div>
<slot :list='arr' name='header'></slot>
</div>
`,
data(){
return {
arr : [1,2,3]
}
}
})
<!--ast-->
{
...,
scopedSlots : {
"header" : {
attrsList: [],
attrsMap: {v-slot:header: 'user'},
children : [
{
expression: "_s(user)",
text: "{{user}}",
tokens : [{@binding: 'user'}],
type: 2
}
],
rawAttrsMap : {
v-slot:header : {
name: 'v-slot:header', value: 'user'
}
},
slotScope: "user",
slotTarget: ""header"",
slotTargetDynamic: false,
tag: "template",
type: 1
}
},
tag: "slot3",
type: 1
}
指令:
v-text
<!--template-->
<span v-text="a"></span>
<!--ast-->
{
attrsList : [{name: 'v-text', value: 'a'}],
attrsMap : {v-text: 'a'},
directives : [{
arg: null,
isDynamicArg: false,
modifiers: undefined,
name: "text",
rawName: "v-text",
value: "a"
}],
rawAttrsMap : {v-text: {name: 'v-text', value: 'a'}},
tag: "span",
type: 1,
}
v-html
<!--template-->
<div v-html="c"></div>
<!--ast-->
{
attrsList : [{name: 'v-html', value: 'c'}],
attrsMap : {v-html: "c"},
directives : [{
name: "html",
rawName: "v-html",
value: "c"
}],
rawAttrsMap : {
v-html: {name: 'v-html', value: 'c'}
}
}
v-show
更上面差不多
v-if v-else-if v-else
<!--template-->
<div v-if="d">5</div>
<div v-else-if="g">6</div>
<div v-else>7</div>
<!--ast-->
{
attrsList: [],
attrsMap: {v-if: 'd'},
if: "d",
ifConditions : [
{
block : 当前节点,
exp : "d"
},
{
block : 当前节点,
exp : "g"
},
{
block : 当前节点,
exp : undefined
},
],
rawAttrsMap : {v-if: {name: 'v-if', value: 'd'}}
}
v-for
<!--template-->
<span v-for="(item,index) in 3" :key='index'>{{item}}</span>
<!--ast-->
{
alias: "item",
attrsList: [],
attrsMap: {v-for: '(item,index) in 3', :key: 'index'},
children : [{
expression: "_s(item)",
static: false,
text: "{{item}}",
token : [{@binding: 'item'}],
type: 2
}],
for: "3",
iterator1: "index",
key : "index"
rawAttrsMap : {
:key : {name: ':key', value: 'item.id'},
v-for: {name: 'v-for', value: '(item,index) in 3'}
}
}
v-on
<!--template-->
<button @click="onclicks">{{count}}</button>
<!--ast-->
{
attrsList : [{name: '@click', value: 'onclicks'}],
attrsMap: {@click: 'onclicks'},
children : [
{type: 2, expression: '_s(count)', tokens: Array(1), text: '{{count}}', tokens:[{@binding: 'count'}]}
],
events : [{value: 'onclicks', dynamic: false}],
rawAttrsMap : {
@click : {
name: "@click",
value: "onclicks"
}
}
}
v-bind
<!--template-->
<img :src='t'/ alt="picture">
<!--ast-->
{
attrs : [
{name: 'src', value: 't', dynamic: false},
{name: 'alt', value: '"picture"', dynamic: undefined}
],
attrsList : [
{name: ':src', value: 't'},
{name: 'alt', value: 'picture'}
],
attrsMap : {
:src: "t",
alt: "picture"
},
rawAttrsMap : {
:src: {name: ':src', value: 't', start: 325, end: 333},
alt: {name: 'alt', value: 'picture', start: 334, end: 347}
}
}
v-model
<!--template-->
<input v-model='s'/>
<!--ast-->
{
attrsList : [{name: 'v-model', value: 's'}],
attrsMap: {v-model: 's'},
directives : [
{name: 'model', rawName: 'v-model', value: 's', arg: null, isDynamicArg: false}
],
rawAttrsMap : {
v-model: {name: 'v-model', value: 's'}
}
}
v-slot
<!--template-->
<blog>
<template v-slot:header>123</template>
</blog>
<!--ast-->
{
attrsList: [],
attrsMap: {},
children: [],
rawAttrsMap: {},
scopedSlots : {
"header": {
attrsList: [],
attrsMap: {v-slot:header: ''},
rawAttrsMap : {
v-slot:header: {name: 'v-slot:header', value: ''}
},
slotScope: "_empty_",
slotTarget: ""header"",
slotTargetDynamic: false
}
},
tag: "blog"
}
v-pre
<!--template-->
<div v-pre>{{t}}</div>
<!--ast-->
{
attrsList : [],
attrsMap: {v-pre: ''},
children : [
{type: 3, text: '{{t}}',static: true}
],
pre: true,
rawAttrsMap : {
v-pre: {name: 'v-pre', value: ''}
},
staticInFor: false
}
v-cloak
<!--template-->
<span v-cloak>{{t}}</span>
<!--ast-->
{
attrsList : [
{name: 'v-cloak', value: ''}
],
attrsMap: {v-cloak: ''},
directives : [
{
arg: null,
isDynamicArg: false,
modifiers: undefined,
name: "cloak",
rawName: "v-cloak",
value: ""
}
],
rawAttrsMap : {
v-cloak: {name: 'v-cloak', value: ''}
}
}
v-once
<!--template-->
<div v-once>{{t}}</div>
<!--ast-->
{
attrsList: []
attrsMap: {v-once: ''},
rawAttrsMap : [
{ v-once: {name: 'v-once', value: ''} }
]
}
Attribute(属性)
key
<!--template-->
<div v-for="(item,index) in 3" :key="index">{{item}}</div>
<!--ast-->
{
alias: "item",
attrsList: [],
attrsMap: {v-for: '(item,index) in 3', :key: 'index'},
for: "3",
iterator1: "index",
rawAttrsMap : {
:key: {name: ':key', value: 'index'},
v-for: {name: 'v-for', value: '(item,index) in 3'}
}
}
ref
<!--template-->
<p ref="p"></p>
<!--ast-->
{
attrsList: [],
attrsMap: {ref: 'p'},
rawAttrsMap : {
ref: {name: 'ref', value: 'p'}
},
ref: ""p"",
refInFor: false
}
is
<!--template-->
<component :is="g2"></component>
<!--ast-->
{
attrsList: [],
attrsMap: {:is: 'g2'},
component: "g2",
rawAttrsMap : {
:is: {name: ':is', value: 'g2'}
},
tag: "component"
}
自定义事件
原生标签
<!--template-->
<button @click="() => count++">{{count}}</button>
<!--ast-->
{
attrsList : [
{name: '@click', value: '() => count++'}
],
attrsMap: {@click: '() => count++'},
events : {
click: {value: '() => count++', dynamic: false}
},
rawAttrsMap : {
@click: {name: '@click', value: '() => count++'}
}
}
组件标签
<!--template-->
<blog-test @change="onclicks"></blog-test>
<!--ast-->
{
attrsList : [{name: '@change', value: 'onclicks'}],
attrsMap: {@change: 'onclicks'},
events : {
change: {value: 'onclicks', dynamic: false}
},
rawAttrsMap : {
@change: {name: '@change', value: 'onclicks'}
}
}
自定义指令
<!--template-->
<div v-test></div>
<!--ast-->
{
attrsList : [
{name: 'v-test', value: ''}
],
attrsMap: {v-test: ''},
children : [{...}],
directives : [{name: 'test', rawName: 'v-test', value: '', arg: null, isDynamicArg: false, …}],
rawAttrsMap : [{
v-test: {name: 'v-test', value: ''}
}]
}
过滤器
<!--template-->
<div v-for="(item,index) in arr" :key="item.id">{{ item | select}}</div>
<!--ast-->
{
...,
children : [
{
expression: "_s(_f("select")(item))",
text: "{{ item | select}}",
tokens : [ {@binding: '_f("select")(item)'} ],
type : 2
}
]
}
组件
<!--template-->
<to></to>
<!--ast-->
{
attrsList: [],
attrsMap: {},
children: [],
rawAttrsMap: {},
tag: "to",
type: 1,
}
标签
表达式
<!--template-->
<div>{{t}}</div>
<!--ast-->
{
...,
children : [
{
expression: "_s(t)",
static: false,
text: "{{t}}",
tokens : [{@binding: 't'}]
}
]
}
计算属性
<!--template-->
<div>{{gs}}</div>
<!--ast-->
{
...,
children : [
{
expression: "_s(gs)",
text: "{{gs}}",
token : [{@binding: 'gs'}]
}
]
}