什么时候使用computed或者watch:默认加载数据的时候,不触发事件
使用计算属性computed的一个实例:vuex中使用state里面的共享数据。当共享数据发生改变时,如果使用computed进行监听,就会很好的将改变之后的数据展现到页面当中去,也可以不使用,但有可能出现数据无法正常显示的问题。
vuex和computed的区别,vuex是存储和传递数据的,computed是用来改变数据的,即监听发生改变的数据并渲染到页面当中去。
vue中的计算属性computed实现当数据发生改变时,数据实时更新到页面中去,而"不会出现数据改变了但是在页面上还没有显示",
computed是一个跟data平级的,他里面的属性不需要在data中定义,而是直接在computed里直接定义,引用跟data里的属性一样引用,computed里的属性本质是一个方法,但是引用他的时候当做一个属性来引用,而不是方法来引用,引用时一定不要加(),计算属性会被缓存起来,方便下次调用,当数据没有发生改变时,计算属性不会重新计算。
1.支持缓存,只有数据发生改变,才会重新进行计算
2.不支持异步,当computed内有异步操作时无效,无法监听数据的变化
3.computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过的数据通过计算得到的,
响应式依赖就是指watcher,data里面的数据发生改变,watcher就会更新,但watcher不会立即执行,会异步渲染。
4.如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
5.如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
例如
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id='itany'>
<input type="text"v-model="firstname">
<input type="text"v-model="lastname">
<input type="text"v-model="name">
<p>{{name}}</p>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<script>
new Vue({
el:'#itany',
data:{
firstname:'',
lastname:'',
},
//由以下代码可以看出computed监听的属性值是name,默认执行的是getter方法,并且要return,return的值就是监听的属性值name.
computed:{
//方法1:
'name':function () {
return this.firstname+this.lastname; //name依赖的值是firstname和lastname(多对一),name不需要在data中声明,但是firstname和lastname需要在data中声明,或者从props中获取。
},
// 方法2:get方法: /*'name': { get: function () { return this.firstName + ' ' + this.lastName }
//set方法与get方法相反,当监听的属性值发生变化时才会执行,也就是当改变name的值之后,它依赖的firstName和lastName的值也会相应改变。因此set方法改变的是被依赖的值。
set: function (name) { var arr = name.split(' '); // 以空格来分,将一个字符串分割成了两个字符串 this.firstName = arr[0] this.lastName = arr[1] }
}*/
},
})
</script>
</body>
</html>
在watch跟computed差不多,watch跟data平级,watch中的属性也是一个方法,但是不需要return,也必须要在data先定义该属性,
不支持缓存,数据变,直接会触发相应的操作;
watch支持异步;
监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id='itany'>
<input type="text"v-model="firstname">
<input type="text"v-model="lastname">
<input type="text"v-model="name">
<p>{{name}}</p>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<script>
new Vue({
el:'#itany',
data:{
firstname:'',
lastname:'',
name:''
},
watch:{
//当firstname改变时去执行函数,进而改变name的值
'firstname':function () {
this.name= this.firstname;
},
//当lastname改变时去执行函数,进而去改变nam的值
'lastname':function () {
this.name= this.firstname+this.lastname;
},
},
})
</script>
</body>
</html>
//watch使用的示例2(重点)
//physical和delivering依赖于busidata
watch:{
busidata(newValue,oldValue){
console.log(newValue)
//配送费
this.physical=newValue.physical
//起送价
this.delivering=newValue.delivering
}
}
由该示例可以看出,watch监听的值是busidata,当basidata改变时,执行函数,physical和delivering的值也相应改变,因此是一对多的关系。‘一’代表的是被依赖值busidata,‘多’代表的是依赖值physical和delivering。而computed是多对一的关系,‘多’代表的是被依赖值,‘一’代表的是依赖值。由此可以辨别什么时候使用watch,什么时候使用computed.
watch使用示例三:deep深度监听:
当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。
<input type="text" v-model="cityName.name"/>
new Vue({
el: '#root',
data: {
cityName: {id: 1, name: 'shanghai'}
},
watch: {
//监听整个cityName对象,可以监听到cityName.name的变化
cityName: {
handler(newName, oldName) { // ... }, //当cityName发生改变时需要执行的函数,使用handler方法。
deep: true, //深度监听
immediate: true //最初绑定值的时候也执行函数,则就需要用到immediate属性。
}
}
如果只需要监听对象中的一个属性值,则可以做以下优化:使用字符串的形式监听对象属性:
-
watch: {
-
'cityName.name': { //只监听cityName.name的变化
-
handler(newName, oldName) {
-
// ...
-
},
-
deep: true,
-
immediate: true
-
}
-
}
watch示例三:
watch: {
rfid: 'scanRFID',
},
methods: {
scanRFID: function(newVal,oldVal) {
console.log(newVal)
console.log(oldVal)
console.log("执行")
},
}
//watch也可以这样用: