Vue2模板编译原理

vue模板编译

with语法

let obj = {
	a: 1,
	b: 2
}
with(obj) {
	console.log(a)
	console.log(b)
	console.log(c) // 报错
}
  • 改变{}内自由变量的查找规则,当作obj属性来查找
  • 如果找不到匹配的obj属性会报错
  • with要慎用,他打破了作用域规则,易读性变差

编译模板

  • 模板不是html,有指令、插值、JS表达式,能实现判断和循环
  • html是标签语言,只有JS才能实现循环、判断(图灵完备的)
  • 模板一定是转换为某种JS代码,即模板编译

模板编译

const compiler = require('vue-template-compiler')

// 插值
// const template = '<p>{{message}}</p>'
// with(this){return _c('p',[_v(_s(message))])}
// _c: createElement 类似h函数
// _v: createTextVNode
// _s: toString

// 表达式
// const template  = `<p>{{flag ? message : 'no message found'}}</p>`
// with(this){return _c('p',[_v(_s(flag ? message : 'no message found'))])}

// 属性、动态属性
// const template = `
//     <div id="div1" class="container">
//         <img :src="imgUrl">
//     </div>
// `
// with(this){return _c('div',{staticClass:"container",attrs:{"id":"div1"}},[_c('img',{attrs:{"src":imgUrl}})])}
// _c与h一样,_c('tagName', {staticClass, attrs}, [children])

// 条件
// const template = `
//     <div>
//         <p v-if="flag === 'a'">A</p>
//         <p v-else>B</p>
//     </div>
// `
// with(this){return _c('div',[(flag === 'a')?_c('p',[_v("A")]):_c('p',[_v("B")])])}
// 条件渲染会被直接转换成三元表达式

// 循环
// const template = `
//     <ul>
//         <li v-for="item in list" :key="item.id">{{item.title}}</li>
//     </ul>
// `
// with(this){return _c('ul',_l((list),function(item){return _c('li',{key:item.id},[_v(_s(item.title))])}),0)}
// _l: renderList

// 事件
// const template = `
//     <div @click="handleClick">A</div>
// `
// with(this){return _c('div',{on:{"click":handleClick}},[_v("A")])}

// v-model
const template = `
    <input v-model="val" />
`
// with(this){return _c('input',{directives:[{name:"model",rawName:"v-model",value:(val),expression:"val"}],domProps:{"value":(val)},on:{"input":function($event){if($event.target.composing)return;val=$event.target.value}}})}



// 编译
const res = compiler.compile(template)
console.log(res.render)

posted on 2021-03-25 09:39  是庸  阅读(74)  评论(0)    收藏  举报