跳到主要内容位置

vue模板被编译成什么

v-model 原理 看下面代码#

通过给 input 元素监听 input 事件 使 $event.target.value 等于绑定值

with 语法#

// 如果想要改变 obj 中每一项的值,一般写法可能会是这样:
// 重复写了 3 次的“obj”
obj.a = 2;
obj.b = 3;
obj.c = 4;
// 而用了 with 的写法,会有一个简单的快捷方式
with (obj) {
a = 3; //a=obj.a
b = 4;
c = 5;
}

模板编译(vue-template-compiler)#

模板会编译为 render 函数,执行 render 函数会返回 vnode 基础 vnode 执行 patch(补丁) 和 diff(对比)(渲染和更新)

集成 webpack vue-loader,会在开发环境下编译模板 引入 vue 得话会再运行时才编译 这样性能就不行 都是再开发环境下打包编译好再发布的

//模板编译
const compiler = require('vue-template-compiler')
// 插值
const template = `<p>{{message}}</p>`
with(this){return createElement('p',[createTextVNode(toString(message))])}
// h -> vnode
// createElement -> vnode
// 表达式
// 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}})])}
// // 条件
// 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)}
// 事件
// const template = `
// <button @click="clickHandler">submit</button>
// `
// with(this){return _c('button',{on:{"click":clickHandler}},[_v("submit")])}
// v-model !!!
const template = `<input type="text" v-model="name">`
// 主要看 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 函数
// 它们返回 vnode
// patch(补丁)
// 编译
const res = compiler.compile(template)
console.log(res.render)
// ---------------分割线--------------
// // 从 vue 源码中找到缩写函数的含义
// function installRenderHelpers (target) {
// target._o = markOnce;
// target._n = toNumber;
// target._s = toString;
// target._l = renderList;
// target._t = renderSlot;
// target._q = looseEqual;
// target._i = looseIndexOf;
// target._m = renderStatic;
// target._f = resolveFilter;
// target._k = checkKeyCodes;
// target._b = bindObjectProps;
// target._v = createTextVNode;
// target._e = createEmptyVNode;
// target._u = resolveScopedSlots;
// target._g = bindObjectListeners;
// target._d = bindDynamicKeys;
// target._p = prependModifier;
// }
最近更新于