入口文件
import { initMixin } from './init'
import { lifecycleMixin } from './lifecycle/index'
import { renderMixin } from './vdom/index'
function Vue(options) {
this.__init(options);
}
initMixin(Vue);
lifecycleMixin(Vue);
renderMixin(Vue);
export default Vue
生命周期挂在render方法 lifecycle/index.js
import { patch } from '../vdom/patch';
export function mountComponent(vm) {
vm._update(vm._render());
}
export function lifecycleMixin(Vue) {
Vue.prototype._update = function(vnode) {
const vm = this;
patch(vm.$el, vnode);
}
}
render转vnode vdom/index.js
import {
createElement,
createTextVnode
} from './vnode.js'
export function renderMixin(Vue) {
Vue.prototype._c = function() {
return createElement(...arguments);
}
Vue.prototype._s = function(value) {
if(value === null) return;
return typeof value === 'object' ? JSON.stringify(value): value;
}
Vue.prototype._v = function(text) {
return createTextVnode(text);
}
Vue.prototype._render = function() {
const vm = this,
render = vm.$options.render,
vnode = render.call(vm);
return vnode;
}
}
实现功能文件 vdom/vnode.js
function createElement(tag, attrs = {}, ...children) {
return vnode(tag, attrs, children);
}
function createTextVnode(text) {
return vnode(undefined, undefined, undefined, text);
}
function vnode(tag, props, children, text) {
return {
tag,
props,
children,
text
}
}
export {
createElement,
createTextVnode
}
打补丁挂载页面 vdom/patch.js
function patch(oldNode, vnode) {
let el = createElement(vnode),
parentElement = oldNode.parentNode;
parentElement.insertBefore(el, oldNode.nextSibling);
parentElement.removeChild(oldNode);
}
function createElement(vnode) {
const { tag, props, children, text } = vnode;
if(typeof tag === 'string') {
vnode.el = document.createElement(tag);
updateProps(vnode, props);
children.map(child => {
vnode.el.appendChild(createElement(child));
})
}else {
vnode.el = document.createTextNode(text);
}
return vnode.el;
}
function updateProps(vnode) {
console.log(vnode, 1111);
const el = vnode.el,
newProps = vnode.props || {};
for(let key in newProps) {
if(key === "style") {
for(let skey in newProps.style) {
el.style[skey] = newProps.style[skey];
}
}else if(key === 'class'){
el.className = el.class;
}else {
el.setAttribute(key, newProps[key]);
}
}
}
export {
patch
}
- 挂载之前:

- 打补丁挂载之后
