generate生成渲染函数字符串

175 阅读3分钟

开篇

下面主要将ast转换为render

slot插槽

匿名插槽

<!--template-->
Vue.component('slot1',{
    template : `<div>
        <slot></slot>
    </div>`
})
<slot1>匿名插槽</slot1><!--ast-->
{
    attrsList: []
    attrsMap: {},
    children : [
        {type: 3, text: '匿名插槽'}
    ],
    rawAttrsMap : {},
    tag: "slot1",
    type: 1
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('slot1', [_v("匿名插槽")])
  }
})

具名插槽

<!--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
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('slot2', {
      scopedSlots: _u([{
        key: "header",
        fn: function () {
          return [_v("具名插槽")]
        },
        proxy: true
      }])
    })
  }
})

作用域插槽

<!--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
}
​
<!--render-->
(function anonymous() {
    with(this) {
        return _c('slot3', {
          scopedSlots: _u([{
            key: "header",
            fn: function (user) {
              return [_v(_s(user))]
            }
          }])
        })
    }
 }

指令

v-text

<!--template-->
<div id='box'>
    <span v-text="a"></span>
</div><!--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,
}
​
<!--render-->
(function anonymous() {
  with (this) {
    return _c("div", { attrs: { id: "box" } }, [
      _c("span", { domProps: { textContent: _s(a) } }),
    ]);
  }
});

v-html

<!--template-->
<div id='box'>
    <div v-html="c"></div>
</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'}
    }
}
​
<!--render-->
(function anonymous() {
  with (this) {
    return _c("div", { attrs: { id: "box" } }, [
      _c("div", { domProps: { innerHTML: _s(c) } }),
    ]);
  }
});

v-show

<!--template-->
<p v-show="d">4</p><!--render-->
(function anonymous() {
  with(this) {
    return _c('p', {
      directives: [{
        name: "show",
        rawName: "v-show",
        value: (d),
        expression: "d"
      }]
    }, [_v("4")])
  }
})

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'}}
}
​
<!--render-->
(function anonymous() {
  with (this) {
    return d
      ? _c("div", [_v("5")])
      : g
      ? _c("div", [_v("6")])
      : _c("div", [_v("7")]);
  }
})

v-for

<!--template-->
<div id='box'>
    <span v-for="(item,index) in 3" :key='index'>{{item}}</span>
</div>
​
<!--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'}
    }
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('div', {
      attrs: {
        "id": "box"
      }
    }, _l((3), function (item, index) {
      return _c('span', {
        key: index
      }, [_v(_s(item))])
    }), 0)
  }
})

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"
        }
    }
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('button', {
      on: {
        "click": onclicks
      }
    }, [_v(_s(count))])
  }
})

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}
    }
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('img', {
      attrs: {
        "src": t,
        "alt": "picture"
      }
    })
  }
})

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'}
    }
}
​
<!--render-->
(function anonymous() {
  with (this) {
    return _c("input", {
      directives: [
        {
          name: "model",
          rawName: "v-model",
          value: s,
          expression: "s",
        },
      ],
      domProps: {
        value: s,
      },
      on: {
        input: function ($event) {
          if ($event.target.composing) return;
          s = $event.target.value;
        },
      },
    });
  }
})

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"
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('blog', {
      scopedSlots: _u([{
        key: "header",
        fn: function () {
          return [_v("123")]
        },
        proxy: true
      }])
    })
  }
})

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
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('div', {
      pre: true
    }, [_v("{{t}}")])
  }
})

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: ''}
    }
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('span', {}, [_v(_s(t))])
  }
})

v-once

<!--template-->
<div v-once>{{t}}</div><!--ast-->
{
    attrsList: []
    attrsMap: {v-once: ''},
    rawAttrsMap : [
        { v-once: {name: 'v-once', value: ''} }
    ]
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _m(0)
  }
})

Attribute(属性)

key

<!--template-->
<div>
    <div v-for="(item,index) in 3" :key="index">{{item}}</div>
</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'}
    }
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('div', _l((3), function (item, index) {
      return _c('div', {
        key: index
      }, [_v(_s(item))])
    }), 0)
  }
})

ref

<!--template-->
<p ref="p"></p><!--ast-->
{
    attrsList: [],
    attrsMap: {ref: 'p'},
    rawAttrsMap : {
        ref: {name: 'ref', value: 'p'}
    },
    ref: ""p"",
    refInFor: false
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('p', {
      ref: "p"
    })
  }
}  

is

<!--template-->
<component :is="g2"></component><!--ast-->
{
    attrsList: [],
    attrsMap: {:is: 'g2'},
    component: "g2",
    rawAttrsMap : {
        :is: {name: ':is', value: 'g2'}
    },
    tag: "component"
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c(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++'}
    }
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('button', {
      on: {
        "click": () => count++
      }
    }, [_v(_s(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'}
    }
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('blog-test', {
      on: {
        "change": 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: ''}
    }]
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('div', {
      directives: [{
        name: "test",
        rawName: "v-test"
      }]
    })
  }
})

过滤器

<!--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
        }
    ]
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('div', _l((arr), function (item, index) {
      return _c('div', {
        key: item.id
      }, [_v(_s(_f("select")(item)))])
    }), 0)
  }
})

组件

<!--template-->
<to></to><!--ast-->
{
    attrsList: [],
    attrsMap: {},
    children: [],
    rawAttrsMap: {},
    tag: "to",
    type: 1,
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('to')
  }
})

标签

表达式

<!--template-->
<div>{{t}}</div><!--ast-->
{
    ...,
    children : [
        {
            expression: "_s(t)",
            static: false,
            text: "{{t}}",
            tokens : [{@binding: 't'}]
        }
    ]
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('div', [_v(_s(t))])
  }
})

计算属性

<!--template-->
<div>{{gs}}</div><!--ast-->
{
    ...,
    children : [
        {
            expression: "_s(gs)",
            text: "{{gs}}",
            token : [{@binding: 'gs'}]
        }
    ]
}
​
<!--render-->
(function anonymous() {
  with(this) {
    return _c('div', [_v(_s(gs))])
  }
})