要求:点击按钮后改变天气,并且后台输出的也改变。
先自己做一下,用的很简单的methods
<div id="btnDemo">
<h1>今天天气很{{weather}}</h1><br>
<button @click="changeWeather()">切换天气</button>
</div>
<script type="text/javascript">
const vm = new Vue({
el:'#btnDemo',
data: {
weather: '凉爽'
},
methods: {
changeWeather() {
if(this.weather == '凉爽') {
var fore = '凉爽';
this.weather = '炎热';
console.log("天气变化了,现在是:" + this.weather + ",原来是" + fore);
} else if(this.weather == '炎热') {
var fore = '炎热';
this.weather = '凉爽';
console.log("天气变化了,现在是:" + this.weather + ",原来是" + fore);
}
},
}
})
</script>
1.如果没用到vue,那么vue-devtools就不更新数据了(就算data那些数据改变了,vue-devtools也看不到)
2.当div绑定vm的时候,不管什么都会都vm实例中找,所以里面的@click="alert(1)"会报错,因为不会到除了vm的找(alert在windows)
//事实上也是围绕data来进行改变,因为data一变,就会重新加载,从而实现动态变化。
<div id="btnDemo">
<h1>今天天气很{{info}}</h1><br>
<button @click="changeWeather()">切换天气</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
//当vm创建时候知道自己需要监视的时候,写进去
const vm = new Vue({
el:'#btnDemo',
data: {
isHot: true
},
methods: {
changeWeather() {
this.isHot = !this.isHot;
}
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽';
},
},
watch: {
isHot: {
immediate: true, //初始化的时候就调用,也就是一进去就调用
handler(newValue, oldValue) {
console.log("天气变化,现在是" + (newValue ? '炎热' : '凉爽') +
",原来是" + (oldValue ? '炎热' : '凉爽'));
}
}
}
})
//后续业务需求的时候,在外面写
/*vm.$watch('isHot', {
immediate: true, //初始化的时候就调用,也就是一进去就调用
handler(newValue, oldValue) {
console.log("天气变化,现在是" + (newValue ? '炎热' : '凉爽') +
",原来是" + (oldValue ? '炎热' : '凉爽'));
}
})*/
</script>
注意:
1.不仅可以监视属性,也可以监视计算属性(computed)。
2.监视不存在的属性,虽然不会报错,但是没有意义。
1.当检视的属性的value是对象的时候({}),这时候监视的是它的地址值,而不是里面的对象属性。虽然可以直接将对象重新赋值,但是显然没有接下来的好用。
2.深度监视开启的话,对象内的属性变化也算是这个对象的值变化。
3.Vue默认可以监测到不管多里面的属性,如numbers.a.b…,但是watch不行,所以要把deep设置为true。
<div id="btnDemo">
<button @click="numbers.a++">a加1,现在的a{{numbers.a}}</button><br>
<button @click="numbers.b++">b加1,现在的b{{numbers.b}}</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el:'#btnDemo',
data: {
numbers: {
a: 1,
b: 2
}
},
watch: {
//监视多级结构中某个属性的变化
'numbers.a': {
handler() {
console.log("某个值改变了")
}
},
//监视对象内部值改变
numbers: {
deep: true,
handler() {
console.log("不管哪个值变了,我都变了");
}
}
}
})
</script>
要想简写,那么就只有handler,也就是没有immediate、deep以及其他。
//平常写法
/*isHot: {
immediate: true,
deep: true,
handler(newValue, oldValue) {
console.log("天气变化,现在是" + (newValue ? '炎热' : '凉爽') +
",原来是" + (oldValue ? '炎热' : '凉爽'));
}
}*/
//简写
isHot(newValue, oldValue) {
console.log("天气变化,现在是" + (newValue ? '炎热' : '凉爽') +
",原来是" + (oldValue ? '炎热' : '凉爽'));
}
或者
vm.$watch('isHot',function(newValue, oldValue){
console.log("天气变化,现在是" + (newValue ? '炎热' : '凉爽') +
",原来是" + (oldValue ? '炎热' : '凉爽'));
})
注意:这里还是不能用箭头函数,this还是从vm变成了window
1.computed可以完成的,watch都能完成。
//computed
computed: {
fullName(){
return this.lastName + '-' + this.firstName;
}
}
//watch
watch: {
firstName(val){
this.fullName = this.lastName + '-' + val;
},
lastName(val){
this.fullName = val + '-' + this.firstName;
}
}
2.watch能完成的功能,computed不一定能完成,如:watch可以进行异步操作,如以下
watch: {
firstName(val){
setTimeout(() => {
/*1.这里不能写为非箭头函数,
因为箭头函数没有返回值,
那么this向外查找才能找到this为vm,
而如果是function,那么这个this就变成了window
(定时器指定的回调是由js引擎回调的,并且指定了this就是window)
2.具体this怎么找的:首先箭头函数没有this,
向外找到了firstName这个普通函数形式的属性,
而这个属性又是属于vm的,
所以this就是vm
这也就是为什么要写成普通函数的形式,
因为用到this的时候会用到*/
this.fullName = this.lastName + '-' + val;
}, 1000);
},
lastName(val){
this.fullName = val + '-' + this.firstName;
}
}
但是computed做不到
//错误代码
computed: {
fullName(){
setTimeout(() => {
return this.lastName + '-' + this.firstName;
}, 1000);
}
}
这里错误的原因就是return返回给了setTimeout内部的函数,但是并没有返回给fullName,导致fullName没有返回值,从而没法进行修改。
3.不被Vue管理的函数(定时器回调、ajax回调、promise回调),最好写成箭头形式,这样this指向的才是vm或组件实例对象。