计算属性
计算属性是通过逻辑业务的处理,返回一个逻辑处理后的属性。计算属性通过computed来使用
computed在处理上和methods相似,但不同的是,methods在使用时要执行里面的操作再返回值,而computed在执行前会检查用于计算的属性是否发生改变,如果没有改变,则使用上次缓存下来的值,而一旦里面的属性发生改变,computed会自动重新计算当前值
<div id="app">
<input type="text" v-model="first">
<input type="text" v-model="second">
<input type="text" v-model="third">
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
first: "",
second: ""
},
computed: {
// 只要计算属性中用到的值发生改变,就会重新计算该属性,如果没有改变,该计算所得的值会被缓存起来重复使用
third: function() {
return `${this.first}-----${this.second}`
}
}
})
</script>
在这段代码中,用于计算的first和second每次改变都会导致third重新计算,所以每次修改first和second时third就会随之改变。
setter方法
计算属性默认情况下使用getter方法,当也可以自己添加一个setter方法,这样在改变当前值时可以修改其他的值
<div id="app">
<input type="text" v-model="first">
<input type="text" v-model="second">
<input type="text" v-model="third">
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
first: "",
second: ""
},
computed: {
third: {
get: function() {
return `${this.first}-----${this.second}`
},
set: function(newVal) {
let val = newVal.split('-----')
this.first = val[0]
this.second = val[1]
}
}
}
})
</script>
这段代码实现了在改变first和second中任一个时会修改third,而修改third时first和second也会改变
监听属性
与计算属性computed构建一个不存在的值不同,监听属性watch是监听一个已存在的值,当监听的值发生改变时就进行定义好的逻辑操作。
<div id="app">
<input type="text" v-model="first">
<input type="text" v-model="second">
<input type="text" v-model="third">
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
first: "",
second: "",
third: ""
},
watch: {
"first": function(newVal, oldVal) {
//第一个参数为更新后的值,第二个参数为更新前的值
console.log(`first:${newVal}--------${oldVal}`)
this.third = `${this.first}---${this.second}`
},
"second": function(newVal, oldVal) {
console.log(`second:${newVal}--------${oldVal}`)
this.third = `${this.first}---${this.second}`
}
}
})
</script>
这里通过对first和second两个数进行监听,当两个数中任一个发生改变时就修改third的值。
上面的用法监听到了first和second的数据变化,这里这两个值都只是一个字符串,那么如果是对象的话呢
对于对象的监听
对于函数的监听,使用上面的方法,只有在函数重新赋值(改变函数的引用时有用)
<template>
<div id="app">
<input type="text" v-model="name">
<button @click="change">click</button>
</div>
</template>
<script>
export default {
name: 'app',
data(){
return{
testObj:{
id:1,
name:'john'
},
count:1,
name:'john'
}
},
methods:{
change(){
this.testObj={
id:++this.count,
name:this.name,
}
}
},
watch:{
testObj:{
handler(newVal,oldVal){
console.log('newVal',newVal)
console.log('oldVal',oldVal)
}
}
}
}
</script>
上面的代码在点击按钮时会打印出相应的内容,但是如果只修改部分属性,是不会显示内容的,如果我们要对单个属性进行修改,可以采用字符串形式监听
<template>
<div id="app">
<input type="text" v-model="name">
<button @click="change">click</button>
</div>
</template>
<script>
export default {
name: 'app',
data(){
return{
testObj:{
id:1,
name:'john'
},
name:'john'
}
},
methods:{
change(){
this.testObj.name=this.name;
}
},
watch:{
'testObj.name':{
handler(newVal,oldVal){
console.log('newVal',newVal)
console.log('oldVal',oldVal)
}
}
}
}
</script>
此外,也可以利用computed来获得属性的引用,以便于在watch中监听
computed:{
objName(){
return this.testObj.name
}
},
watch:{
objName:{
handler(newVal,oldVal){
console.log('newVal',newVal)
console.log('oldVal',oldVal)
}
}
}
若要对所有属性监听,可以采用computed来一个个监听,也可以通过设置deep:true来做到
watch:{
testObj:{
handler(newVal,oldVal){
console.log('newVal',newVal)
console.log('oldVal',oldVal)
},
deep:true
}
}
设置deep:true后,不管对象中哪一个属性发生变化,都会被监听到,触发相应的handler事件