vue.js入门(2)——vue.js里的数据操作(data,methods,computed,watch)
关于vue.js的学习官方文档里有教程https://cn.vuejs.org/v2/guide/赞一下vue.js的维护人员,我会按照官方的API里整合的目录分模块进行学习本章内容是有关vue的数据处理,主要介绍data,computed,method,watch,有关props值传递,会单独开一章玩一下。ok,进入正题。(如对数据操作感兴趣的请看 个人对computer和filte...
关于vue.js的学习官方文档里有教程
https://cn.vuejs.org/v2/guide/
赞一下vue.js的维护人员,我会按照官方的API里整合的目录分模块进行学习
本章内容是有关vue的数据处理,主要介绍data,computed,method,watch,有关props值传递,会单独开一章玩一下。ok,进入正题。(如对数据操作感兴趣的请看 个人对computer和filter工具使用的一些见解,传送门,另外关于本文,说实话,很多错误,是自己初学的时候瞎写的,如对data的数据双向绑定感兴趣,请看这个链接)
1.data
关于data,很多人的第一印象就是,这个东西很简单,不就是把数据写到data里,就可以用双括号绑定数据了吗?(那你跟我的想法相同,然后踩到坑里无法自拔了)先来看一下官方文档:
Vue 实例的数据对象。Vue 将会递归将 data 的属性转换为 getter/setter,从而让 data 的属性能够响应数据变化。对象必须是纯粹的对象 (含有零个或多个的 key/value 对):浏览器 API 创建的原生对象,原型上的属性会被忽略。大概来说,data 应该只能是数据 - 不推荐观察拥有状态行为的对象。
一旦观察过,不需要再次在数据对象上添加响应式属性。因此推荐在创建实例之前,就声明所有的根级响应式属性。
实例创建之后,可以通过 vm.$data 访问原始数据对象。Vue 实例也代理了 data 对象上所有的属性,因此访问 vm.a 等价于访问 vm.$data.a。
以 _ 或 $ 开头的属性 不会 被 Vue 实例代理,因为它们可能和 Vue 内置的属性、API 方法冲突。你可以使用例如 vm.$data._property 的方式访问这些属性。
当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
如果需要,可以通过将 vm.$data 传入 JSON.parse(JSON.stringify(...)) 得到深拷贝的原始数据对象。
以上即为官网对于data的说明,并不是三言两语,反而比很多其他听起来更复杂的对象或方法描述更详细,对于红字部分来一一验证或说明。
首先创建实例后,按照官网提供的方法,输出vm.$data 访问一下data,下面是一个小demo。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>data处理</title>
<link rel="stylesheet" type="text/css" href="/static/css/common.css" >
</head>
<body>
<div id="demo">${name}</div>
</body>
<script src="/static/js/vue.js"></script>
<script src="/static/js/jquery-1.11.1.js"></script>
<script>
var vm = new Vue({
delimiters:['${','}'],
el:"#demo",
data:{
"name":"dkr"
}
})
console.log(vm.$data);
</script>
</html>
可以看到控制台打印:
Vue 将会递归将 data 的属性转换为 getter/setter,从而让 data 的属性能够响应数据变化,所以数据是通过get和set方法进行数据绑定的。
然后来“作”一下,把name改成$name or _name,控制台可以输出值,但无法渲染到dom上,还会报错
当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。这个特性跟组件有关,在后面讲组件的时候会讲到,大致了解一下,可以听不懂,就是组件的data如果用对象的方式声明,A组件和B组件会共用这个data对象里面的值,因此需要通过声明函数,通过函数返回值,使得A组件和B组件的内容不共用。(其实就是你所创建的某个东西,在计算机里是否存在同一区域的问题,如果存在同一区域,那肯定是共用该区域的内容,如果是不同区域,即使名字相同,也只是同名同姓的两个人,本质上不是一个人)
2.methods
method在官网里的描述不是很多就一句话:
methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的 this 自动绑定为 Vue 实例。
只要注意一下method里的this指针指向的是创建的vue实例即可。
关于method的好处,个人觉得他可以统一管理某个组件里用到的方法,而不需要像平常做的项目一样,引入不知道多少个common文件,东拼西凑,代码维护起来很不方便。他的用法就是通过v-on监听事件是否触发,再绑定method里的函数。(关于v-on的用法上一章说的比较细,这里就不具体演示了)
写个小demo看一下this对象。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>data处理</title>
<link rel="stylesheet" type="text/css" href="/static/css/common.css" >
</head>
<body>
<div id="demo">
<button @click="helloWorld" v-text="name"></button>
</div>
</body>
<script src="/static/js/vue.js"></script>
<script src="/static/js/jquery-1.11.1.js"></script>
<script>
var vm = new Vue({
delimiters:['${','}'],
el:"#demo",
data:{
"name":"dkr"
},
methods:{
helloWorld:function(){
console.log("hello world");
console.log(this);
}
}
})
</script>
</html>
3.computed
官网描述:
计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。注意,如果某个依赖 (比如非响应式属性) 在该实例范畴之外,则计算属性是不会被更新的。补充一条:this指针默认指向创建的vue实例。
关于computed,个人理解他是用于数据的计算,并可以直接返回结果值,由于返回的是值,因此可以直接使用该数据,而不是绑定函数,驱动computed执行的是数据是否变化这个条件,所以可以理解为,computed里面的函数监听了数据是否变化。(跟method里监听鼠标点击,巴拉巴拉的操作其实差不多,只是各司其职)
写个简单的demo了解一下,实际项目中涉及的复杂计算请多多了解一些常用的计算工具。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>data处理</title>
<link rel="stylesheet" type="text/css" href="/static/css/common.css" >
</head>
<body>
<div id="demo">
<button @click="helloWorld" v-text="name"></button>
<input type="number" v-model="A">
<input type="number" v-model="B">
<div>${Add}</div>
</div>
</body>
<script src="/static/js/vue.js"></script>
<script src="/static/js/jquery-1.11.1.js"></script>
<script>
var vm = new Vue({
delimiters:['${','}'],
el:"#demo",
data:{
"name":"dkr",
"A":0,
"B":0,
},
methods:{
helloWorld:function(){
console.log("hello world");
console.log(this);
}
},
computed:{
Add:function(){
return this.A + this.B;
}
}
})
</script>
</html>
可以看到我把Add函数的返回值直接用双括号绑定的方法渲染在模板里。
4.watch
官网的介绍感觉不是很详细:
一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch()
,遍历 watch 对象的每一个属性。
关于watch的使用其实有很多坑,deep参数的使用,新值旧值的获取等。
为了说明deep参数,我将测试三种类型的数据,分别是
str :字符串
arr:数组
json:对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>data处理</title>
<link rel="stylesheet" type="text/css" href="/static/css/common.css" >
</head>
<body>
<div id="demo">
<button @click="helloWorld" v-text="name"></button>
<input type="number" v-model="A">
<input type="number" v-model="B">
<div>${Add}</div>
<button @click="changeArr">改变对象数组值</button>
<button @click="changeStr">改变str值</button>
<button @click="changeObj">改变obj值</button>
</div>
</body>
<script src="/static/js/vue.js"></script>
<script src="/static/js/jquery-1.11.1.js"></script>
<script>
var vm = new Vue({
delimiters:['${','}'],
el:"#demo",
data:{
"name":"dkr",
"A":0,
"B":0,
"arr":[{
"name":"lalala",
"sex":"nan",
},{
"name":"hahaha",
"sex":"nan",
},{
"name":"xixixi",
"sex":"nv",
},],
"str":"hello world",
"obj":{
"name":"diudiudiu",
"sex":"nv",
}
},
methods:{
helloWorld:function(){
console.log("hello world");
console.log(this);
},
changeArr:function(){
this.arr.push("nihao");
},
changeStr:function(){
this.str = "hello vue";
},
changeObj:function(){
this.obj.name="dididi";
}
},
computed:{
Add:function(){
return this.A + this.B;
}
},
watch:{
"arr":{
handler:function(val,oldVal){
console.log("监听到了arr数据变化");
console.log(JSON.stringify(val)===JSON.stringify(oldVal)); //true
},
//deep:true,
},
"str":{
handler:function(val,oldVal){
console.log("监听到了str数据变化");
console.log(val,oldVal); //hello vue , hello world
},
//deep:true,
},
"obj":{
handler:function(val,oldVal){
console.log("监听到了obj数据变化");
console.log(val === oldVal); //true
},
deep:true,
},
}
})
</script>
</html>
分别点击三个button触发事件,获得以下结果
arr和str不需要深度监控,就可以探测到数据的变化(如果你的数组是对象数组,改变了某个对象里的某个值,其实可以归为下面一类,也是需要深度监控才能监听到)
json对象需要深度监控,才能检测到某个数据的变化,否则不会触发监听事件(当然,如果你新增一个键值对,那么,不需要深度监控也能监听到)
arr和json对象,val === oldval,都是新的值,是因为数组和对象共用同一块空间。
str类型能够顺利输出新值和旧值。
关于数据的基本操作,到此为止。有什么看不懂或者写错的地方,欢迎联系我,我电话110
更多推荐
所有评论(0)