閱讀前,建議先參考Day:1閱讀指南&為何選擇這個題目,再來考慮是否花時間閱讀
題目:三十天用Vue.jS打造一個網路商城
挑戰內容:利用慕課網(IMOOC)的「Vue2.0+Node.js+MongoDB 全棧打造商城系統」的課程嘗試在30天內打造網路商城。
適合閱讀者:有VueJS基礎的人
不適合閱讀者:沒有VueJS基礎的人(因為我省略很多前提)
警告:我只是Vue的初學習者,肯定會有錯誤,歡迎指出!
以下功能應該很常見,就是在輸入框中輸入aaaa,也可以同步顯示aaaa
我想這個是學習VueJS的人,第一次學會做出的效果。
可是,我們可以不用VueJS就實現這個功能嗎?可以
只要在input的DOM上加事件監聽事件
,讓input只要測到keyup
鍵盤事件發生時,就自動把輸入的value傳到display的innerHTML中
<body>
<input type="text" id="input">
<br>
<br>
<span id="display"></span>
</body>
<script>
// 一個添加物件屬性的函式
document.getElementById("input").addEventListener("keyup", function (event) {
document.getElementById("display").innerHTML = event.target.value;
})
</script>
可是,這頂多只能稱為單向數據綁定
,因為我們不能用其他方式反向去操縱input中的value
首先介紹,Object.defineProperty()這個函式
Object.defineProperty()
這個函式可以改變物件
的屬性
及其value
比如說,假設我們有一個obj物件
//創建一個obj物件,然後附上context屬性,其value為hi~~~
var obj = {
context: "hi~~~"
}
console.log(obj) //回傳{context: "hi~~~"}
這時候想要改變obj的context屬性內容有幾種做法
obj.context="nice to meet you"
console.log(obj) //回傳{context: "nice to meet you"}
或是也可以用Object.definePropert()
Object.defineProperty(obj, "context", {
value: "nice to meet you" //回傳{context: "nice to meet you"}
})
所以勒,那幹嘛用Object.defineProperty?而且這個數據雙向綁定有什麼關係?
因為 Object.defineProperty()
有一個set()函式
可以用,當他偵測到obj屬性
的內容
被更改時就會被觸發,因此可以做一些事情。
Object.defineProperty(obj, "context", {
set() { //當有人嘗試更改obj.context的內容時就會觸發console.log()
console.log("討厭,想偷改我的內容>.<")
}
})
了解這個set()後,就可以用來做雙向數據綁定
<body>
<input type="text" id="input">
<br>
<br>
<span id="display"></span>
</body>
<script>
var obj = {
}
Object.defineProperty(obj, "context", {
set(val) { //當有人嘗試更改obj.context的內容時就會觸以下事件
document.getElementById("input").value = val
//把obj.context被更改的新值傳入輸入框(input)
document.getElementById("display").innerHTML = val
//把obj.context被更改的新值傳入顯示區(display)
}
})
document.getElementById("input").addEventListener("keyup", function (event) {
obj.context = event.target.value;
}) //當輸入框(input)內容被輸入value時,也會把 obj.context改變為value
![](https://media.giphy.com/media/3Nr88xdKfAdRgU3aKO/giphy.gif)
綜上所述,只要運用addEventListener()
和Object.defineProperty()
,其實不需要Vue.JS也可以實現雙向數據綁定
恩...是不是跟Vue.JS很像呢!!!沒錯,因為VueJS的雙向數據綁定就是這樣實現的。
好吧,雖然我說這樣可以完成雙向數據綁定,但其實我並沒有做成功。我雖然透過操作object成功改變了input的值。但當我更改輸入框(input)的value時,卻導致object.context變成了undefined
有沒有人知道為什麼會這樣呢XD?(請參考以下GIF圖檔)
感謝教學
Vue 如何雙向綁定資料的機制這塊講得滿好懂的 ~
BTW
好吧,雖然我說這樣可以完成雙向數據綁定,但其實我並沒有做成功。我雖然透過操作object成功改變了input的值。但當我更改輸入框(input)的value時,卻導致object.context變成了undefined
我想了一下,這個問題可能是 set()
內沒有把 obj.context
的值放到某個地方儲存,也沒有用 get()
設定告知 obj.context
要去哪邊求值後返回而導致
以下是我修改後的 code
let obj = {} // 空殼,取值與設定值的過程會被 defineProperty 介入
let _obj = {} // 存放實際值的地方
Object.defineProperty(obj, "context", {
set(val) {
document.getElementById("input").value = val
document.getElementById("display").innerHTML = val
_obj.context = val // 將 context 實際值放到 _obj 中
},
get() {
return _obj.context // 返回 _obj 中的 context 實際值
}
})
document.getElementById("input").addEventListener("keyup", function (event) {
obj.context = event.target.value;
// console.log(event.target.value)
})
附上 codepen
https://codepen.io/ayugioh2003/pen/vYYjWqe?editors=1011