ブログで私が共有する基本的な使用VUE機能をレンダリング
我々は、単に彼が機能をレンダリングする方法について話このブログは達成されました
公式のマップを取得する最初の
我々は時間の初期化を持っている例では、仮想関数をレンダリングし、DOMによって生成されたHTMLがコンパイルされ、ビューは仮想現実のDOMのDOMに応じて層を生成します。
その後、応答データとを変更する時間を持っている場合、関数は思い出すだろうレンダリング、時間に更新された機能は、新しい仮想DOMを返しレンダリング、この新しい仮想のDOMと直接前に交換する必要はありません、彼は、古いものと新しいDOMを比較しますその後、差分アルゴリズム、結果は最小の変更は、更新はDOM、実際のDOMを取る逆流の多数の発生を回避し、再描画する必要がありました
レンダリング機能は、タイミングをトリガ
それはデータに応じて変化するときに私が言っただけで、すでに最上部に、トリガされる機能をレンダリングし、その後、あなたはVUEの応答性の原則について話をする必要があり
前原理はVUEデータハイジャックを実装していることを聞いて、彼は最終的にもそれをハイジャックし、データを行う方法ですか?
VUEインスタンスデータが初期化にオブジェクトのすべての属性を追加する内部VUE源は、内部見ることができます
function observe (obj) {
// 迭代对象的所有属性
// 并使用Object.defineProperty()转换成getter/setters
Object.keys(obj).forEach(key => {
let internalValue = obj[key]
// 每个属性分配一个Dep实例
const dep = new Dep()
Object.defineProperty(obj, key, {
// getter负责注册订阅者
get () {
dep.depend()
return internalValue
},
// setter负责通知改变
set (newVal) {
const changed = internalValue !== newVal
internalValue = newVal
// 触发后重新计算
if (changed) {
dep.notify()
}
}
})
})
return obj
}
オブジェクトが通知を介して伝送されるので挙動に基づいて、データが変更されたリスナーのウォッチャは、その後、DOMを更新するために、レンダリング関数を呼び出すウォッチャ伝え、そこに元の特性プラスワン依存オブジェクトを変更しません
JSX文法はの機能をレンダリング
JSXの事JS内で定義されたクラスのXML構文は、jsのコードは、私がブログを使用しています内側には、JSエンジンによって解釈、解析できる機能自体をレンダリング書かれているが、気持ちは非常にJSXの内側に、非常に冗長ですはじめに、ラベルのすべての属性を返すことができ、私は別の例を感じないとhtml
render() {
const { count, onChange } = this;
return (
<div>
<componment
style={{ marginTop: "10px" }}
count={count}
type="button"
onChange={onChange}
/>
<componment
style={{ marginTop: "10px" }}
count={count}
type="button"
domPropsInnerHTML={`hello ${this.count}.`}
onChange={onChange}
/>
</div>
);
}
簡単に二つの成分をレンダリングすることができるコードの先頭は
JSX文法の使用は、バベルプラグイン、必要なときことに留意すべきである公式の接続プラグイン
createElement
render函数里边用的createElement方法创建的vnode,createElement方法在vue的源码里边是对_createElement方法的封装,之前是由五个参数的,其中有一个参数是对子节点的犯规,
我们使用的createElement在经过规范化之后,默认返回的一个vnode类型的数组
vnode有四个属性
- tag
- data
- context
- children
第一个是节点的名称 首先会对tag进行一个判断,如果是字符串的话,会去看是不是html规范的一些检点,如果是的话会创建一个普通的vnode节点
如果是以恶搞注册过的组件名称,则会createComponent 创建一个组件类型的vnode
如果都不是则会创建一个位置的标签
什么是vnode
所谓虚拟DOM,是一个用于表示真实 DOM 结构和属性的 JavaScript 对象,这个对象用于对比虚拟 DOM 和当前真实 DOM 的差异化,然后进行局部渲染从而实现性能上的优化。
vnode的渲染
在render函数生成完毕虚拟dom树之后 就开始了vnode的首次渲染,vue里边调用的是_update方法
// src/core/instance/lifecycle.js
Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) {
const vm: Component = this
if (vm._isMounted) {
callHook(vm, 'beforeUpdate')
}
const prevEl = vm.$el
const prevVnode = vm._vnode
const prevActiveInstance = activeInstance
activeInstance = vm
vm._vnode = vnode
if (!prevVnode) {
// 初始化渲染
vm.$el = vm.__patch__(
vm.$el, vnode, hydrating, false /* removeOnly */,
vm.$options._parentElm,
vm.$options._refElm
)
// no need for the ref nodes after initial patch
// this prevents keeping a detached DOM tree in memory (#5851)
vm.$options._parentElm = vm.$options._refElm = null
} else {
// 更新渲染
vm.$el = vm.__patch__(prevVnode, vnode)
}
activeInstance = prevActiveInstance
// update __vue__ reference
if (prevEl) {
prevEl.__vue__ = null
}
if (vm.$el) {
vm.$el.__vue__ = vm
}
// if parent is an HOC, update its $el as well
if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
vm.$parent.$el = vm.$el
}
// updated hook is called by the scheduler to ensure that children are
// updated in a parent's updated hook.
}
可以看出不管如何最终都是调用的__patch__方法
这个__patch__方法主要有两个作用 第一个是创建真实dom 另外一个是发生变化之后把新老的虚拟dom进行对比然后更新真实dom
这个方法对应的方法是createPatchFunction() 有兴趣的可以去源码里边搜一下
结束语
以上是我对render函数的从响应到渲染还有他的作用的理解 有不对的地方欢迎批评指正