vue-template-compiler
vue-template-compiler该模块可用于将 Vue 2.0 模板预编译为渲染函数(template => ast => render)
实验
- 使用npm init -y 初始化项目
- npm install vue-template-compiler下载vue模板编译插件
- 创建一个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不建议一起用的原因