前言
本文不是Vue.js的教程,只是一邊看官網Vue的教程文檔一邊記錄並總結學習過程中遇到的一些問題和思考的筆記。
1、vue和avalon一樣,都不支持VM初始時不存在的屬性
而在Angular里是可以支持的,因為angular采用臟檢查的方式實現雙向綁定,vue和avalon都是采用setter和getter實現雙向綁定
例,如下代碼在一秒后不會顯示出“xxcanghai”的字樣
<div id="app">
<h1>{{obj.text}}</h1>
</div>
<script>
var v = new Vue({
el: '#app',
data: {
obj:{}
}
});
setTimeout(function(){
v.obj.text="xxcanghai";//無效
},1000);
</script>
若給定初始值,則可生效,如下:
<div id="app">
<h1>{{obj.text}}</h1>
</div>
<script>
var v = new Vue({
el: '#app',
data: {
obj:{
text:"default Text" //給定初始值
}
}
});
setTimeout(function(){
v.obj.text="xxcanghai";//有效
},1000);
</script>
不過Vue其中比avalon好的一點是,Vue在只是對初始化時不存在的屬性賦值無效,但顯示是不會報錯的。而avalon則根本無法顯示,對於上述第一段代碼運行都會報錯(不知道最新的avalon是否修改此問題)
好在vue中提供了$set方法來解決這種賦值失敗的問題,如下:
<div i<div id="app">
<h1>{{obj.text}}</h1>
</div>
<script>
var v = new Vue({
el: '#app',
data: {
obj: {}
}
});
setTimeout(function() {
v.$set("obj.text", "xxcanghai");//有效
}, 1000);
</script>
雖然這種采用字符串來表示變量名的方式會導致無法使用強類型的預編譯檢查(TypeScript),但也至少算能解決問題吧。
2、input元素中屬性與v-model同時存在在以屬性為優先
如下代碼:當文本框中的value屬性與v-model沖突時會以input的value屬性為優先,並覆蓋v-model的屬性
最終console.log輸出的也是“inputText”
<div id="app">
<input type="text" v-model="a" value="inputText">
</div>
<script>
var v = new Vue({
el: '#app',
data: {
a: "vueText"
}
});
console.log(v.a);//inputText
</script>
對於復選框類型的input上述結論也同樣適用,如下:
<div id="app">
<input type="checkbox" v-model="isCheck" checked>
</div>
<script>
var v = new Vue({
el: '#app',
data: {
isCheck: false
}
});
console.log(v.isCheck);//true
</script>
復選框的v-model設定為false不選中,同時設定checked屬性選中,最終效果為以checked屬性優先,復選框被選中,同時v.isCheck屬性被改寫為true。
3、VM中的函數放到data屬性和methods屬性中的區別,以及函數調用時帶括號與不帶括號的區別
- Vue在實例化的時候有一個特殊的屬性即methods,我看官方文檔中把所有VM中的函數都放到methods屬性里面,經測試把函數寫在data和methods中都可以正常運行,那么兩者有何區別?
- 通過官方demo可知,在綁定函數的時候可以帶括號也可以不帶括號,對於有參數的函數那必須帶括號調用,但是對於無參函數帶括號調用與不帶括號調用的區別是什么?
以下測試:
<div id="app">
<button @click="dataFn">1.dataFn</button>
<!--輸出:<button>,[MouseEvent]-->
<button @click="dataFn()">2.dataFn()</button>
<!--輸出:Vue,[]-->
<button @click="methodsFn">3.methodsFn</button>
<!--輸出:Vue,[MouseEvent]-->
<button @click="methodsFn()">4.methodsFn()</button>
<!--輸出:Vue,[]-->
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
dataFn: function() {
console.log(this,arguments);
}
},
methods: {
methodsFn: function() {
console.log(this,arguments);
}
}
});
//xxcanghai@博客園
</script>
通過上述代碼對比可以得到以下結論:
- 若想要在事件響應函數中獲得Event對象,那么事件綁定時不能加括號,參見上述1、3示例。
- 若想在函數中this指向Vue實例化對象,函數調用時應當加括號。同時,所有在methods屬性中的函數,無論如何調用,this都指向當前Vue實例化對象。
- 遂最終結論為:應當把所有VM中的函數都放在methods中,同時對於事件的綁定應當使用無括號方式。即上述示例3中為最優方案。
PS:當然你也可以使用vue內置的$event
來顯示的傳遞event對象,以保證函數寫在任何位置都可以正常使用this和event。
<div id="app">
<button @click="dataFn($event)">5.dataFn($event)</button>
<!--輸出:Vue,[MouseEvent]-->
<button @click="methodsFn($event)">6.methodsFn($event)</button>
<!--輸出:Vue,[MouseEvent]-->
</div>