フロントエンド理論面接-vueテーマ

7294 ワード

一.vueフレームワークとは
Vueは、ユーザーインタフェースを構築するための漸進的なフレームワークです.他の大型フレームワークとは異なり,Vueは底から上へ層毎に適用できるように設計されている.Vueのコアライブラリは、ビューレイヤのみに注目し、使いやすいだけでなく、サードパーティのライブラリや既存のプロジェクトとの統合も容易です.一方、Vueは、近代的なツールチェーンやさまざまなサポートクラスライブラリと組み合わせて使用される場合、複雑な単一ページアプリケーションを駆動することができます.(vue公式説明)(1)プログレッシブフレームワークとは何か、Vueの最も基本的な宣言レンダリング機能のみを使用すれば、Vueをテンプレートエンジンとして完全に使用することができます.コンポーネント化開発方式で開発したい場合は、Vueの中のコンポーネントシステムをさらに使用することができます.SPA(単ページアプリケーション)を作成する場合は、Vue内のクライアントルーティング機能を使用するコンポーネントが多くなると、いくつかのデータを共有する必要がある場合は、Vue内のステータス管理を使用することができます.チームで統一的な開発プロセスや仕様を実行したい場合は、構築ツールを使用するので、プロジェクトの複雑さに応じてVue内の機能を自主的に選択することができます.
(2)VueはMVVMモードデータ駆動ページに基づくフレームワークであり、データをビューにバインドする.単一ページアプリケーションを実現する技術に属する.まとめたいくつかの特徴:1)シンプル2)軽量3)高速4)データ駆動5)モジュールフレンドリー6)コンポーネント化
vueはデータ駆動双方向バインドによってページを開発するのが簡単で、開発者はdomを手動で修正する必要はありません.Vueはデータの双方向バインドによってすべてがより簡単になります.そのデータは双方向バインディングを駆動し、下層はObjectを通過する.defineProperty()定義のデータset、get関数の原理実装.
(3)、コンポーネント化開発により、プロジェクトの拡張性、移植性を向上させ、コード再利用性を向上させる.
(4)、単一ページアプリケーションの体験、ローカルコンポーネントのインタフェースの更新、ユーザーの体験をより迅速かつ省時間にする.
単一ページアプリケーションはSPAとも呼ばれ、すべてのアクティビティを1つのWebページに限定し、そのWebページの初期化時にのみ対応するHTML、JavaScript、CSSをロードします.ロードが完了し、ページは再ロードまたはジャンプされず、中のコンポーネントまたはモジュールだけがhash、またはhistory apiを通じてインタラクティブとジャンプを行い、ajaxを通じてデータを引き出して応答機能を実現し、アプリケーション全体がhtmlであるため、単一ページと呼ばれます.
(5)、jsのコードは無形の規範であり、チームが協力してコードの読解性が高い
二.vueフレームワーク実現原理
データエージェント、データハイジャック、テンプレート解析、変異配列メソッド、双方向バインド
1).データエージェント
データエージェントの正常な状況を簡単に紹介します.私たちはデータをdataに書きます.
var vm = new Vue({
 el:'#app',
 data:{
    title: 'hello world'    
  }
methods:{
 changeTitle:function(){          
    this.title ='hello vue'        
  }  
}
})
console.log(vm.title)


データエージェントがなく、dataのtitleを変更する場合は、methodsのchangeTitleはこのように変更するしかありません.data.title='hello vue',以下のconsoleもconsoleに変更するしかない.log(vm.data.title)は、データエージェントがこのような機能です.
2). 実装の原理
dataの中の属性を巡回することによって、各属性をobjectを通過する.defineProperty()getterとsetterを設定し、dataの各プロパティをdataと同じレベルのオブジェクトにコピーします.トリガーされたgetterはdata内の対応する属性のgetterをトリガーし、ここのsetterはdata内の対応する属性のsetterをトリガーし、エージェントを実現します.実装コードは次のとおりです.
var self = this;
 // this vue  ,  vm

Object.keys(this.data).forEach(function(key){ 
Object.defineProperty(this,key,{
    // this.title,  vm.title
  enumerable:false,
  configurable:true,        
  get: function getter (){            
    return self.data[key];
  //    data[key] getter
  },      
  set:function setter (newVal){
     self.data[key]=newVal;
  //    data[key] setter     
  } 
});
}

3).双方向バインド
データ変更----->ビューの更新
ビュー更新(input、textarea)-->データ変動
ビュー更新-->データ変動という方向のバインドは簡単で、主にイベントリスニングによってデータを変更します.例えばinputはinputイベントをリスニングし、inputイベントをトリガーするとdataを変更します.以下では主にデータ変動----->ビュー更新という方向のバインドを理解する.
4). データハイジャック
データの変動をどのように実現し、バインドデータに対応するビューを更新するかを自分で考えてみましょう.
答えはobjectですdefineProperty、objectを通ります.この設定を参照してください.data内のすべての属性は、各属性のsetterに対応するコールバック関数を通知し、ここでのコールバック関数にはdomビューで再レンダリングする関数、$watchで追加するコールバック関数などが含まれており、objectを通過する.definePropertyはデータをハイジャックしました.このようにデータに値を再割り当てすると.title='hello vue'では、setter関数がトリガーされ、domビューの再レンダリング関数がトリガーされ、データの変動が実現され、ビューの更新に対応します.
5). パブリッシュ→サブスクリプションモード
では、問題が発生しました.setterでバインドされているすべてのコールバック関数をトリガーするにはどうすればいいのでしょうか.
このデータをバインドするコールバック関数が1つ以上ある以上、私たちはすべてのコールバック関数を1つの配列の中に置いて、いったんデータのsetterをトリガすると、配列トリガの中のすべてのコールバック関数を遍歴して、私たちはこれらのコールバック関数を購読者と呼びます.配列は、次のインスタンスコードに示すように、setter関数の最近の親役割ドメインで定義することが望ましい.
Object.keys(this.data).forEach(function(key){
  var subs = []; //                 
  Object.defineProperty(this.data, key,{ // this.data.title
     enumerable:false,
     configurable:true,
     get:function getter (){
         console.log('       ')          
        return this.data[key]; //                
      },
    set:function setter (newVal){
      if(newVal === this.data[key]){
            return;  //         ,    ,        
      }
      this.data[key]=newVal; //      
      subs.forEach(function(){
       //   subs                
      })       
    }   
 });
}

では、問題はまた来て、どのようにしてバインドデータのすべてのコールバック関数を1つの配列に入れますか?
私たちはgetterの中で手足を作ることができて、私たちはデータにアクセスするだけで対応するデータのgetterをトリガーすることを知っていて、私たちはまず1つのグローバル変数targetを設定することができて、もし私たちがdataの中でtitle属性に1人の購読者(changeTitle関数)を追加するならば、私たちはまずtarget=changeTitleを設定して、changeTitle関数をtargetの中にキャッシュして、それからthisにアクセスすることができます.titleはtitleのgetterをトリガーし、getterでtargetというグローバル変数の値をsubs配列に追加し、追加が完了したらグローバル変数targetをnullに設定し、他の購読者を追加します.インスタンスコードは次のとおりです.
Object.keys(this.data).forEach(function(key){
  var subs = []; //                 
  Object.defineProperty(this.data, key,{ // this.data.title
     enumerable:false,
     configurable:true,
     get:function getter (){
         console.log('       ') 
         if (target) {
           subs.push(target);            
         }         
        return this.data[key]; //                
      },
    set:function setter (newVal){
      if(newVal === this.data[key]){
            return;  //         ,    ,        
      }
      this.data[key]=newVal; //      
      subs.forEach(function(){
       //   subs                
      })       
    }   
 });
}

上のコードは分かりやすくするために簡略化されていますが、実際には購読者を構造関数watcherと書いて、購読者をインスタンス化するときに対応するデータにアクセスし、対応するgetterをトリガーし、詳細なコードはDMQの自分でMVVMを実現することができます.
6). テンプレート解析
上記の2つのステップでは、データが変動すると、対応するバインドデータのサブスクライバに通知されます.次に、ビュー更新関数という特殊なサブスクライバを簡単に紹介します.ほとんどのデータに対応するビュー更新関数が追加されているので、ビュー更新関数を簡単に理解します.
次のコードがあるとしたら、どうやって対応するhtmlに解析しますか?

{{title}}


まず,解析命令v-model=「title」,v-on:click=「changeTitle」,さらに{{title}}を対応するデータに置き換えるなど,ビュー更新関数の用途を簡単に紹介する.
上の問題に戻って、テンプレートをどのように解析しますか?すべてのdomノードにサブノードを含めると
ノード属性にv-modelが含まれている場合、ビュー更新関数はinputのvalueをtitleに設定する値になります.
ノードがテキストノードの場合、ビュー更新関数は、カッコ内の値'title'を正規表現で取り出し、テキストノードの値をdataに設定します['title']
ノード属性にv-on:xxxxが含まれている場合、ビュー更新関数は、まず正規取得イベントタイプがclickであり、その後、その属性の値がchangeTitleである場合、イベントのコールバック関数はthisである.methods['changeTitle']は、ノードclickイベントをaddEventListenerで傍受します.
ビュー更新関数もdata対応属性の購読者であることを知っておく必要があります.ビュー更新関数をどのようにトリガーするか分からない場合は、上のパブリケーション-サブスクリプションモードをもう一度見ることができます.
可能性のあるパートナーには疑問があるかもしれませんが、inputノードの値がどのように変化した後、次のh 1ノードのtitle値も変化しますか?すべてのノードを巡回した後、ノードに属性v-modelが含まれている場合はaddEventListenerでinputイベントを傍受し、inputイベントをトリガーしdata['title']の値を変更するとtitleのsetterがトリガーされ、すべてのサブスクライバに通知されます.
7). 傍受配列の変化
各配列要素を監視できません.もし私たち自身が配列の変化を監視するならば、objectを使うことを考えるかもしれません.definePropertyは配列の各要素を遍歴してsetterを設定しますが、vueソースコードにはこのように書かれていません.各配列要素definePropertyに対してコード自体の複雑さの増加とコード実行効率の低下をもたらすからです.
8). へんいはいれつほうしき
配列の各要素をdefinePropertyで監視できない以上、配列のメソッド(push,pop,shift,unshift,splice,sort,reverse)を書き換えて配列を変更することができます.
vueドキュメントには次のように書かれています.
Vueには、配列を観察する変異法のセットが含まれているため、ビューの更新もトリガーされます.これらの方法は次のとおりです.
push()

pop()

shift()

unshift()

splice()

sort()

reverse()

変異配列法の欠陥
vueドキュメントにおける変異配列法の欠陥
JavaScriptの制限により、Vueは以下の変動する配列を検出できません.
インデックスを使用して直接アイテムを設定する場合、例えばvm.items[indexOfItem] = newValue
配列の長さを変更すると、例えばvm.items.length=newLength同時ドキュメントでは、上記の2つの問題をどのように解決するかについても説明しています.
最後に
以上はvueのいくつかの基本原理に対する自分の理解である.どのような問題に直面するか推測できないので、より多くの答えを記録するしかありません.