本文參考http://www.javashuo.com/article/p-enjxjgpp-gp.htmlhtml
首先先說個面試題哈,就是vue中的v-model是如何實現雙向數據綁定的
咳咳,下面開始背誦經典面試題了
首先當我new一個vue實例的時候,裏面在data裏聲明的數據,都會以getter和setter的形式保存,觸發了一個方法,就是Object.defineProperty。這個方法裏面有set和get兩個方法。保存數據。當數據發生了變化,setter會通知到watch,從而數據驅動了視圖的變化~(固然這個不是絕對正確的,僅是本身總結)vue
那麼這個Object.defineProperty這個方法是幹啥的呢。面試
它會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 並返回這個對象。設計模式
該方法容許精確添加或修改對象的屬性。經過賦值操做添加的普通屬性是可枚舉的,可以在屬性枚舉期間呈現出來(for…in 或 Object.keys 方法), 這些屬性的值能夠被改變,也能夠被刪除。這個方法容許修改默認的額外選項(或配置)。默認狀況下,使用 Object.defineProperty() 添加的屬性值是不可修改的。瀏覽器
var obj = {}; Object.defineProperty(obj, 'test', { get: ()=>{console.log('get被調用了')}, set: ()=>{console.log('set被調用了')} })
在瀏覽器控制器中當我給對象賦值的時候,調用了set函數,當我讀取對象的值的時候,調用了get函數。函數
看到這裏對vue的雙向數據綁定或者是MVVM這種設計模式亦或是vue最大的優勢等一系列面試題有了更深的理解。spa
而後說回用原生JS實現數據雙向綁定
代碼以下設計
<input type="text" id="input_1"> <span id="span_1"></span> <script> var obj = {}; Object.defineProperty(obj, 'test', { set: (newVal)=>{ document.getElementById('input_1').value = newVal; document.getElementById('span_1').innerHTML = newVal; } }); document.addEventListener('keyup', (e)=>{ obj.test = e.target.value; //事件監聽 }) </script>
在此時我在頁面上就能夠實現我輸入到input框的內容同步到span標籤上,而且在控制檯給obj.test賦值也會同步到input和span標籤。雙向綁定