vue的模板编译

85 阅读2分钟

vue-template-compiler

vue-template-compiler该模块可用于将 Vue 2.0 模板预编译为渲染函数(template => ast => render)

实验

  1. 使用npm init -y 初始化项目
  2. npm install vue-template-compiler下载vue模板编译插件
  3. 创建一个index.js文件,在里面引入上述插件
const compiler = require('vue-template-compiler')
const template=`<div id="app"><p v-if="isShow" v-for="item in items">{{ item.title }}</p></div>`
const res=compiler.compile(template)
console.log(res)
console.log(res.render)

输出内容:

{
  ast: {
    type: 1,
    tag: 'div',
    attrsList: [ [Object] ],
    attrsMap: { id: 'app' },
    rawAttrsMap: {},
    parent: undefined,
    children: [ [Object] ],
    plain: false,
    attrs: [ [Object] ],
    static: false,
    staticRoot: false
  },
  render: `with(this){return _c('div',{attrs:{"id":"app"}},_l((items),function(item){return (isShow)?_c('p',[_v(_s(item.title))]):_e()}),0)}`,
  staticRenderFns: [],
  errors: [],
  tips: []
}
with(this){return _c('div',{attrs:{"id":"app"}},_l((items),function(item){return (isShow)?_c('p',[_v(_s(item.title))]):_e()}),0)}

_xx指令集详解

1、_c

负责生成组件或HTML元素的 VNode,_c是所有render helper方法中最复杂,也是最核心的一个方法,其它的 _xx 都是它的组成部分。_c函数执行后,返回vnode

@param {*} a 标签名
@param {*} b 属性的JSON字符串
@param {*} c 子节点数组
@param {*} d 节点的规范化类型
@returns VNode or Array<VNode>
`vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)`

2、 _v

为文本节点创建 VNode

3、 _s

将值转换为字符串形式,普通值 => String(val),对象 => JSON.stringify(val)

4、_l

renderList,渲染列表,运行时渲染 v-for 列表的帮助函数,循环遍历 val 值,依次为每一项执行 render 方法生成 VNode,最终返回一个 VNode 数组

5、_e

为空节点创建 VNode

6、_n

将值转换为数字

为什么Vue中的v-if和v-for不建议一起用

因为带来性能方面的浪费(每次渲染都会先循环再进行条件判断)

就用这个做例子:

<div id="app">
    <p v-if="isShow" v-for="item in items">
        {{ item.title }}
    </p>
</div>

最后生成代码:

with(this){return _c('div',{attrs:{"id":"app"}},_l((items),function(item){return (isShow)?_c('p',[_v(_s(item.title))]):_e()}),0)}

可以看到,_l((items)后紧跟着function(items),这样的执行方式是没遍历一个item,都要执行function里的方法(判断isShow),造成性能方面的浪费

正确使用方式

将v-for与v-if置于不同标签

<div id="app">
  <template v-if="isShow">
    <p v-for="item in items">{{item.title}}</p>
  </template>
</div>

最后生成代码:

with(this){return _c('div',{attrs:{"id":"app"}},[(isShow)?_l((items),function(item){return _c('p',[_v(_s(item.title))])}):_e()],2)}

可以看到,先判断isShow,然后才执行遍历。

以上就是Vue中的v-if和v-for不建议一起用的原因