项目场景:
数据模板中 watch默认不检测对象内部值的改变(一层),如果内部值发生变化怎么监视
问题描述
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>天气案例</title>
<script src="../js/vue.js"></script>
</head>
<!--
总结:深度监视
Vue中的watch默认不监测对象内部值的改变(一层) 配置deep:true可以监测对象内部值的改变(多层)
备注:
vue中自身可以监测对象内部值的改变 但vue中提供的watch默认不可以
使用watch时根据数据的具体结构 决定是否采用深度监视
-->
<body>
<div id="app">
<h2>今天天气很{{info}}</h2>
<span @click='changeWeather'>切换天气</span>
<h3>a的值是:{{numbers.a}}</h3>
<button @click='numbers.a++'>点我让a+1</button>
<h3>b的值是:{{numbers.b}}</h3>
<button @click='numbers.b++'>点我让b+1</button>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
isHot: true,
numbers: {
a: 1,
b: 1
}
},
methods: {
changeWeather() {
this.isHot = !this.isHot;
}
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽'
}
},
watch: {
// isHot:{
// // immediate:true,初始化时 就调用一次
// // //handler什么时候调用?当isHot发生改变时
// // handler(newValue,oldValue){
// // console.log('isHot被修改了',newValue,oldValue);
// // }
// },
// 监视多级结构中某个属性的变化
// 'numbers.a':{
// handler(){
// console.log('a被改变');
// }
// }
// 监视对象内部值的改变(多层)
// numbers:{
// deep:true,
// handler(newValue,oldValue){
// console.log('numbers改变了');
// }
// },
// 简写
isHot(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue);
}
},
})
// 第二种方式
// vm.$watch('isHot', (newValue, oldValue)){
// console.log('isHot被修改了', newValue, oldValue);
// };
</script>
</body>
</html>
原因分析:
Vue中的watch默认不监测对象内部值的改变(一层) 配置deep:true可以监测对象内部值的改变(多层)
备注:
vue中自身可以监测对象内部值的改变 但vue中提供的watch默认不可以
使用watch时根据数据的具体结构 决定是否采用深度监视
解决方案:
配置deep:true
监视属性与计算属性的区别(姓名案例)
监视属性实现
<div id="app">
姓: <input type="text" v-model="firstName"><br>
名: <input type="text" v-model="lastName"><br>
姓名:<span>{{fullName}}</span><br>
</div>
<script>
const vm = new Vue({
el:'#app',
data:{
firstName:'张',
lastName:'飞',
fullName:''
},
watch:{
// 侦听属性可异步操作
firstName(val){
this.fullName = val + this.lastName
console.log(this);
},
lastName(val){
this.fullName = this.firstName + val
}
}
});
</script>
计算属性实现
<div id="app">
姓: <input type="text" v-model="firstName"><br>
名: <input type="text" v-model="lastName"><br>
姓名:<span>{{fullName}}</span><br>
</div>
<script>
const vm = new Vue({
el:'#app',
data:{
firstName:'张',
lastName:'飞'
},
computed:{
fullName:{
//get有什么作用? 当有人读取fullName时 get就会被调用 且返回值就作为fullName的值
//什么时候调用?1 初次读取fullName时 2 所依赖的数据发生变化时
get(){
console.log('@---fullName');
// console.log(this);//此处的this是vm
return this.firstName + '-' + this.lastName;
},
// set什么时候调用?当定义的fullName被修改的时候
set(value){
console.log('set',value);
const arr = value.split("-");
this.firstName = arr[0]
this.lastName = arr[1]
}
}
}
});
</script>
总结:
computed能完成的功能(靠的是返回值) ,watch都能完成,watch能完成的功能 computed不一定能完成 因为watch可异步操作
两个小原则:
1 所有被vue管理的函数 最好写成普通函数 这样this的指向才是vm 或者组件实例
2 所有不被vue所管理的函数 (定时器的回调 ajax的回调 promise的回调) 可写成箭头函数 这样this的指向才是vm或者
组件实例对象