この記事では、vue の実装を 3 つのステップで説明します (コード付き)。必要な方は参考にしていただければ幸いです。
Vue は現在、双方向のデータ バインディングを実行できるフレームワークとして人気があります。私が知っている理由は次のとおりです。
1. dom 構造を変更する従来の操作は非常に無駄な (つまり、遅い) 操作です。
2. dom 構造を変更するロジックを js 層に置くと、パフォーマンスが向上します。
3. データとビューの分離は、よりオブジェクト指向プログラミングに沿っています。 mvvm
vue の実装も、react と同様に仮想 dom を使用して実装されます。 js を使用してテンプレートを通じてレンダリングされた結果の dom。
vue を実装する手順はおそらく次の 3 つの手順です:1. 応答性: vue は dota の各属性値の変更をどのように監視しますか?
2. テンプレート エンジン: Vue のテンプレートはどのように解析され、命令はどのように処理されるのでしょうか?
3. テンプレートのレンダリング: data 内のデータをテンプレートに追加して HTML にレンダリングする方法は?
ステップ 1: 応答性
応答性の実装は主にオブジェクトのメソッドに依存します:
Object.defineProperty
このメソッドは、オブジェクト内の属性の変更を監視し、論理的な処理を実行できます。
dome は次のとおりです:
var obj={} var _name ='zhangsan' Object.defineProperty(obj,'name',{ get:function() { console.log('get') return _name }, set: function(newVal) { console.log('set') _name=newVal } })
ここで、name または access の値を変更します。 name の値 情報が出力されます。
そして、vue でのシミュレーションの実装は次のようになります。
var vm ={} var data={name:'张三',age:20} var key,value; for(key in data) { (function(key){ Object.defineProperty(vm,key,{ //绑定到vm上 get:function(){ console.log('get') return data[key]; }, set:function(newVal){ console.log('set'); data[key]=newVal } }) })(key) //闭包处理 }
実際、Java を勉強した学生なら、Get についてよく知っているはずです。 Java クラスで直接生成し、メソッドを設定します。
テンプレートは、次の理由から JS コードに変換する必要があります。
#1. -for)、must これは js を使用してのみ実現できます。
2. 仮想 dom のレンダリングは js を使用して実現する必要があります。 (レンダー関数)
テンプレート 1
<div id="app"> <p>{{price}}</p> </div>
テンプレート 1
with(this) { //this就是vm return _c( 'p', { attrs:{'id':'app'} }, [ // _c是createElement // _v是createTextVNode // _s是toString方法 _c('p',[_v(_s(price))]) ] ) }
によって変換されたレンダリング テンプレート 2
<div id="app"> <div> <input v-model="title"> <button v-on:click="add">submit</button> </div> <div> <ul> <li v-for="item in list">{{item}}</li> </ul> </div> </div>
テンプレート 2 によって変換されたレンダリング
with (this) { return _c( 'p', { attrs: { "id": "app" } }, [ _c( 'p', [ _c( 'input', { //指令 directives: [ { name: "model", rawName: "v-model", value: (title), //vm.title expression: "title" } ], domProps: { "value": (title) //vm.title }, on: { "input": function ($event) { if ($event.target.composing) return; title = $event.target.value } } } ), _v(" "), _c( 'button', { on: { "click": add } //vm.add }, [ _v("submit") ] ) ] ), _v(" "), _c( 'p', [ _c( 'ul', _l( (list), function (item) { return _c( 'li', [ _v(_s(item)) ] ) } ) ) ] ) ] ) }
これは、レンダリングに使用されるレンダリング関数です。
vm._update(Vnode) { const prevVonde=vm._Vnode vm._Vnode=Vnode; if(!prevVnode) { //如果没有之前的vnode,第一次渲染 vm.$el=vm._patch_(vm.$el,Vnode) }else { vm.$el=vm._patch_(prevVnode,Vnode) } } function updataComponent() { //vm._reander就是解析模板的rende函数,返回了一个vnode vm._update(vm._render()) }
ここの vm_.patch_ には、複雑な diff アルゴリズムが含まれています。レンダリングは DOM の違いに基づいており、多くの再帰呼び出しが使用され、効率の問題が多く発生します。
以上がvue 実装の 3 つのステップ (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。