Vue学习笔记-1
目录
前言
本文不是 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]-->
<span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"dataFn()"</span>></span>2.dataFn()<span class="hljs-tag"></<span class="hljs-name">button</span>></span>
<span class="hljs-comment"><!--输出:Vue,[]--></span>
<span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"methodsFn"</span>></span>3.methodsFn<span class="hljs-tag"></<span class="hljs-name">button</span>></span>
<span class="hljs-comment"><!--输出:Vue,[MouseEvent]--></span>
<span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"methodsFn()"</span>></span>4.methodsFn()<span class="hljs-tag"></<span class="hljs-name">button</span>></span>
<span class="hljs-comment"><!--输出:Vue,[]--></span>
</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]-->
<span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"methodsFn($event)"</span>></span>6.methodsFn($event)<span class="hljs-tag"></<span class="hljs-name">button</span>></span>
<span class="hljs-comment"><!--输出:Vue,[MouseEvent]--></span>
</div>
相关笔记
Vue 学习笔记 -1(http://www.cnblogs.com/xxcanghai/p/5849038.html)
Vue 学习笔记 -2(http://www.cnblogs.com/xxcanghai/p/6098663.html)