with 语法
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/with
vue 模版编译
- 模板编译为
render
函数,执行render
函数返回vnode
- 基于
vnode
在执行patch
和diff
- 使用
webpack vue-loader
,会在开发环境下编译模板
本质:template
最终也会被 vue-template-compiler
编译为 render
函数,执行 render
函数生成 vnode
,之后才是 Vue
最终执行的。
如下查看编译过程:
插值
const compiler = require('vue-template-compiler')
const template = `<p>{{message}}</p>`
// 编译
const { render } = compiler.compile(template)
console.log(render)
// with(this){return _c('p',[_v(_s(message))])}
// 相当于执行这个函数,例如下面:
// function(){with(this){return _c('p',[_v(_s(message))])}}
// with(this){return createElement('p',[createTextVNode(toString(message))])}
// h -> vnode
// createElement -> vnode
// const vm = new Vue({...})
// this -> vm
表达式
const compiler = require('vue-template-compiler')
const template = `<p>{{flag ? message : 'no message found'}}</p>`
// 编译
const { render } = compiler.compile(template)
console.log(render)
// with(this){return _c('p',[_v(_s(flag ? message : 'no message found'))])}
属性和动态属性
const compiler = require('vue-template-compiler')
const template = `
<div id="div1" class="container">
<img :src="imgUrl"/>
</div>
`
// 编译
const { render } = compiler.compile(template)
console.log(render)
// with(this){return _c('div',{staticClass:"container",attrs:{"id":"div1"}},[_c('img',{attrs:{"src":imgUrl}})])}
条件
const compiler = require('vue-template-compiler')
const template = `
<div>
<p v-if="flag === 'a'">A</p>
<p v-else>B</p>
</div>
`
// 编译
const { render } = compiler.compile(template)
console.log(render)
// with(this){return _c('div',[(flag === 'a')?_c('p',[_v("A")]):_c('p',[_v("B")])])}
循环
const compiler = require('vue-template-compiler')
const template = `
<ul>
<li v-for="item in list" :key="item.id">{{item.title}}</li>
</ul>
`
// 编译
const { render } = compiler.compile(template)
console.log(render)
// with(this){return _c('ul',_l((list),function(item){return _c('li',{key:item.id},[_v(_s(item.title))])}),0)}
事件
const compiler = require('vue-template-compiler')
const template = `<button @click="handlerClick">submit</button>`
// 编译
const { render } = compiler.compile(template)
console.log(render)
// with(this){return _c('button',{on:{"click":handlerClick}},[_v("submit")])}
v-model
const compiler = require('vue-template-compiler')
// v-model
const template = `<input type="text" v-model="name">`
// 编译
const { render } = compiler.compile(template)
console.log(render)
// 主要看 input 事件
// with(this){return _c('input',{directives:[{name:"model",rawName:"v-model",value:(name),expression:"name"}],attrs:{"type":"text"},domProps:{"value":(name)},on:{"input":function($event){if($event.target.composing)return;name=$event.target.value}}})}
render
- 模板到
render
函数,在到vnode
,在到渲染和更新 vue
组件可以使用render
代替template
- 在有些复杂情况中,不能用
template
,可以考虑使用render
react
一直都在使用render
(没有模板)
vue template explorer
Vue2:https://template-explorer.vuejs.org Vue3:https://vue-next-template-explorer.netlify.app