目录
一、天气案例
注意:绑定事件时,@xxx="yyy", yyy 不必须要写函数名,也可以写一些简单的语句,语句之间用分号 ; 隔开,但是里面的变量方法等只能去vm实例 或者 Vue的原型对象上找,如若使用 alert会报错,处理方法可以在vm 中的data中添加 window(window: window的简写),然后再写为window.alert()即可实现,但没必要
如:由于changeWeather比较简短,可以直接写到标签里,但注意此时不需要this ,用分号隔开 @click="isHot = !isHot; x++"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>document</title>
<!-- <script type="text/javascript" src="../script/vue.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}},{{x}}</h2>
<!-- <button @click="changeWeather">切换天气</button> -->
<!-- 由于changeWeather比较简短,可以直接写到标签里,但注意此时不需要this ,用分号隔开-->
<button @click="isHot = !isHot;x++">切换天气</button>
<!-- 绑定事件的时候:@xxx ="yyy",yyy可以写一些简单的语句 -->
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
isHot:true,
x:1
},
methods: {
/* changeWeather(){
this.isHot = !this.isHot
this.x++
} */
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
}
})
</script>
</html>
二、监视(侦听)属性
监视属性watch:
1. 当被监视的属性(也包含计算属性)变化时,回调函数(指handler)自动调用,进行相关操作
2. 监视的属性必须存在,才能进行监视!
3. 监视的两种写法:
(1). new Vue 时传入watch 配置
部分配置:
handler
handler什么时候调用?当isHot发生改变时
可以有两个参数: 1.newValue 2.oldValue
immediate:true 初始化时让handler调用一下,默认为false,这样就表示只有 isHot发生改变时才调用handler
deep:true 深度监视
(2).通过vm.$watch 方法监视,传入两个参数,
1.要监视的属性(属性要加引号,表示不是变量,之前的在Vue中不加,是因为在对象的键值对中默认简写)
2.配置对象
使用两种中的哪一种呢? 创建实例时已知想要监视哪个属性用第一种,创建实例时不知道监视谁,后续根据用户行为才知道,使用 vm.$watch(‘监视的属性’,配置对象)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>document</title>
<!-- <script type="text/javascript" src="../script/vue.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
isHot:true,
},
methods: {
changeWeather(){
this.isHot = !this.isHot
}
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
/* watch:{
isHot:{
// handler什么时候调用?当isHot发生改变时
handler(newValue,oldValue){
console.log(newValue,oldValue);
console.log('isHot被修改了');
},
immediate:true//初始化时让handler调用一下
}
} */
})
vm.$watch('isHot',{
handler(newValue,oldValue){
console.log(newValue,oldValue);
console.log('isHot被修改了');
},
immediate:true//初始化时让handler调用一下
})
</script>
</html>
三、深度监视
深度监视:
(1). Vue中的watch默认不监视对象内部值的改变(一层) obj:{name:’ds’,age:18} 这里的一层指的后面整个对象字面量,而不是里面的值是第一层,所以当监视属性为对象时应采用深度监视
(2). 配置deep:true可以监视对象内部值的改变(多层)
备注:
(1). Vue自身可以监视监视对象内部值的改变,但Vue为程序员提供的watch默认不可以!
如 vm.numbers.a = 12 ,会触发 numbers中的handler
但<button @click="numbers.a++">点我让a+ 1</button> 默认不触发numbers中的handler
(2 ). 使用watch时根据数据的具体结构,决定是否采用深度监视
监视多级结构中某个属性的变化: 'number.a' 注意要加引号
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
<hr>
<h3>a的值是:{{numbers.a}}</h3><br>
<button @click="numbers.a++">点我让a++</button>
<hr>
<h3>b的值是:{{numbers.b}}</h3><br>
<button @click="numbers.b++">点我让b++</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
isHot:true,
numbers:{
a:1,
b:1
}
},
methods: {
changeWeather(){
this.isHot = !this.isHot
}
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
watch:{
isHot:{
handler(newValue,oldValue){
console.log(newValue,oldValue);
console.log('isHot被修改了');
},
},
// 监视多级结构中某个属性的变化
/* 'numbers.a':{//报错原因是写了一个不合法的key
handler(){
console.log('a被改变了');
}
},
'numbers.b':{//报错原因是写了一个不合法的key
handler(){
console.log('b被改变了');
}
}, */
// 监视多级结构中所有属性的变化
numbers:{
deep:true,
handler(){
console.log('numbers被改变了');
}
}
}
})
</script>
</html>
四、监视的简写形式
简写形式的前提是不需要immediate,也不需要deep,即配置项中只有handler时就可以简写
nwe Vue时传入 watch配置的简写: 监视的属性(){ }
vm.$watch(监视的属性,配置对象 )的简写:vm.$watch(监视的属性,function(){ } ),不能写箭头函数
所有 Vue所管理的函数都不能写箭头函数,Vue所管理的函数:配置在methods中的,计算属性中的get,set,计算属性简写时的;监视属性中的handler,监视属性简写时的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>document</title>
<!-- <script type="text/javascript" src="../script/vue.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
isHot:true,
},
methods: {
changeWeather(){
this.isHot = !this.isHot
}
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
watch:{
// 完整形式
/* isHot:{
handler(newValue,oldValue){
console.log(newValue,oldValue);
console.log('isHot被修改了');
},
}, */
// 简写形式
/* isHot(){
console.log('isHot被修改了');
} */
}
})
// 正常写法
/* vm.$watch('isHot',{
handler(newValue,oldValue){
console.log(newValue,oldValue);
console.log('isHot被修改了');
},
}) */
// 简写
vm.$watch('isHot',function(){
console.log('isHot被修改了');
})
</script>
</html>
五、watch对比computed
computed 和 watch 之间的区别:
1. computed 能完成的功能,watch都可以完成
2. watch 能完成的功能,computed 不一定能完成,例如:watch可以进行异步操作
也就是它俩都能实现的操作时,可以使用 computed,但涉及到异步时应使用 watch
下面使用 计算属性设置异步时有误,因为return 交给了计时器中的箭头函数,而无法交给 fullName
computed: {
fullName(){
setTimeout(()=>{
return this.firstName + '-' + this.lastName
}, 1000)
}
},
两个重要的小原则:
1. 所被Vue管理的函数,最好写成普通函数,这样this 的指向才是vm 或 组件实例对象
2. 所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数、Promise的回调函数等),最好写成箭头函数,这样this的指向才是vm 或组件实例对象。
姓名案例使用监听属性的例子:使用监视时得自己把全名这个属性在data配置项中准备好
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>document</title>
<!-- <script type="text/javascript" src="../script/vue.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="root">
姓<input type="text" @keyup.enter="showInfo" v-model="firstName"><br>
名<input type="text" @keyup.enter="showInfo" v-model="lastName"><br>
全名:<span>{{fullName}}</span><br>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三',
fullName:'张-三'
},
watch:{
firstName(newValue){
setTimeout(()=>{
this.fullName = newValue + '-' + this.lastName
},1000);
},
lastName(newValue){
this.fullName = this.firstName + '-' + newValue
},
}
})
</script>
</html>