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)