持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情
文章vue2 模版编译render转虚拟节点的初步分析 把基本过程分析了出来,现在主要是实现我们用到的_rende()方法,这个方法是放在vdom的文件夹下,
我们还要混入render方法,可以看下代码 index.js
import { initMixin } from './init.js'
import { lifecycleMixin } from './lifecycle.js'
import { renderMixin } from './vdom/index.js'
class Vue{
constructor(options) {
this._init(options)
}
}
initMixin(Vue) // 初始化方法,里面是模版编译
lifecycleMixin(Vue) // 混入生命周期方法
renderMixin(Vue) // 这是render的混入方法,也就是我们要报_render方法,引入到Vue的事例上
export default Vue
vdom文件夹里的index.js 看下代码 在这个方法里我们要扩展,我们拼接字符串里用到的_c,_v,_s方法
// 我们在vnode.js引入这两个犯法
import { createElement, createTextVnode } from './vnode.js'
function renderMixin(Vue) { // 专门管渲染的
// 我们需要把_c _v _s 方法都写在这个方法里
Vue.prototype._c = function() { // 创建元素
return createElement(...arguments)
}
Vue.prototype._s = function(value) { // 替换掉属性 主要是替换age name这些变量
if (value===null) { // 这里需要判断是null的情况
return
} else { // 有值的情况才作处理
return typeof value==="object"?JSON.stringify(value):value
}
}
Vue.prototype._v = function(text) { // 创建文本节点
return createTextVnode(text)
}
// 这次我们主要是实现_render方法,
Vue.prototype._render = function() {
const vm = this;
const render = vm.$options.render
const vnode = render()
console.log(vnode)
}
}
export {
renderMixin
}
我们可以看下vnode.js
// 其实这里很简单,我们就是把vnode的几个重要属性已对象的方式返回就可以了
function createElement(tag,attr={},...children) { // 创建元素的vnode
return vnode(tag,attr,children) // 元素之前前三个 标签 属性 和子元素
}
function createTextVnode(text) { // 创建文本的vnode
return vnode(undefined,undefined,undefined,text) // 文本节点前面三个全是空,后面才是文本
}
function vnode(tag,props,children,text) { // 生成vnode的基础方法
return {
tag,
props,
children,
text,
}
}
export {
createElement,
createTextVnode
}
咱们可以看下我们打印的vnode
这是我们自己生成的虚拟dom,和vue2源码生成的vnode差不多,其实写的原理都一样。其实转化虚拟节点还是比较简单的,主要是我们之前拼接好的模版字符串,之后就是在我们在混入renderMixin里,实现了_c,_v,_s这些方法,而且这些方法恰恰返回的就是虚拟节点,转化为虚拟节点这个方法,相对间简单点和字符串拼接相比。