vue中的监视属性
案例 页面有一行文字,今天天气状况炎热/凉爽,这个炎热和凉爽是动态变化的,通过按钮点击切换
实现方法同样有许多种,简单的就是用三元表达式写在插值表达式({{ 三元表达式 }})里面,但依旧不太好(逻辑长) 还可以定义点击事件,在点击事件执行的方法里面进行判断data属性里面的值,如果是炎热就修改属性值为凉爽~如果凉爽则修改为炎热 也可以用computed计算属性,插值表达式里面写计算属性,计算属性里面判断后返回文字,点击事件需要修改data属性值,(如例一) 基于计算属性,可以用简便方法,如例子二直接在点击事件里面写表达式
案例一:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> </head> <body> <!----> <!-- 例一 --> <div id = "app"> 今天天气情况:{{fun}} <button @click="funClick">切换</button> </div> <script> var vm = new Vue({ el: "#app", data :{ weather: true }, computed: {//计算属性 传入配置对象 fun(){//当不需要set时,可以用这种简便方法写,它默认调用的get方法 return this.weather ? "凉爽" :"炎热";//如果weather为true则返回凉爽,false则返回炎热 } }, methods: { funClick(){//点击事件 this.weather = !this.weather;//取反以后再赋值给data里面的属性 } } }) </script> </body> </html>
例二:点击事件可以不用写一个函数,可以直接在里面写表达式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> </head> <body> <!----> <!-- 例一 --> <div id = "app"> 今天天气情况:{{fun}} <button @click="weather = !weather">切换</button> </div> <script> var vm = new Vue({ el: "#app", data :{ weather: true }, computed: {//计算属性 传入配置对象 fun(){//当不需要set时,可以用这种简便方法写,它默认调用的get方法 return this.weather ? "凉爽" :"炎热";//如果weather为true则返回凉爽,false则返回炎热 } }, methods: { /*funClick(){//点击事件 this.weather = !this.weather;//取反以后再赋值给data里面的属性 }*/ } }) </script> </body> </html>
但是当我们还需要做一些其他操作时,比如需要提示天气降温添加衣服时,就需要监听天气状态,当天气状态发生改变时做出提示,就需要用到监视属性了
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> </head> <body> <!-- --> <!-- 例一 --> <div id = "app"> 今天天气情况:{{fun}} {{tip}} <button @click="weather = !weather">切换</button> </div> <script> var vm = new Vue({ el: "#app", data :{ weather: true, tip: "" }, computed: {//计算属性 传入配置对象 fun(){//当不需要set时,可以用这种简便方法写,它默认调用的get方法 return this.weather ? "凉爽" :"炎热";//如果weather为true则返回凉爽,false则返回炎热 } }, methods: { //因为点击事件已经直接在上面写了表达式,所以不需要再写方法 }, watch: {//监听,同样传入一个配置对象 weather: {//名对应data中的属性,表示监听weather的数据变化情况 immediate: false,//true表示初始化时调用一次handler handler(newValue,oldValue){//写handler函数,该函数在监听的属性发生变化时会调用执行,有两个参数,第一个参数是新值,第二个是旧值 /* * 可以在这里面添加其他逻辑,比如在监听到属性发生改变时,提示天气炎热需要加衣服等等其他逻辑 * */ console.log("" , newValue , oldValue ) if (this.weather == true){ this.tip = "请注意降温"; } } } } }) </script> </body> </html>
另外,它不仅可以监听data里面的属性,还可以监听计算属性里面的东西,当计算属性发生了改变,它也可以达到同等的效果
同时,它还有其他的写法,如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> </head> <body> <!-- --> <!-- 例一 --> <div id = "app"> 今天天气情况:{{fun}} {{tip}} <button @click="weather = !weather">切换</button> </div> <script> var vm = new Vue({ el: "#app", data :{ weather: true, tip: "" }, computed: {//计算属性 传入配置对象 fun(){//当不需要set时,可以用这种简便方法写,它默认调用的get方法 return this.weather ? "凉爽" :"炎热";//如果weather为true则返回凉爽,false则返回炎热 } }, methods: { //因为点击事件已经直接在上面写了表达式,所以不需要再写方法 }, /*watch: {//监听,同样传入一个配置对象 weather: {//名对应data中的属性,表示监听weather的数据变化情况 immediate: false,//true表示初始化时调用一次handler handler(newValue,oldValue){//写handler函数,该函数在监听的属性发生变化时会调用执行,有两个参数,第一个参数是新值,第二个是旧值 /!* * 可以在这里面添加其他逻辑,比如在监听到属性发生改变时,提示天气炎热需要加衣服等等其他逻辑 * *!/ console.log("" , newValue , oldValue ) if (this.weather == true){ this.tip = "请注意降温"; } } } }*/ }) //在保证vm已经被实例化的前提下,监视还可以这样写 vm.$watch("weather",{//第一个参数传入需要监视的属性,第二个参数传入配置对象,配置对象内容跟上面一模一样 immediate: false,//true表示初始化时调用一次handler handler(newValue,oldValue){//写handler函数,该函数在监听的属性发生变化时会调用执行,有两个参数,第一个参数是新值,第二个是旧值 /* * 可以在这里面添加其他逻辑,比如在监听到属性发生改变时,提示天气炎热需要加衣服等等其他逻辑 * */ console.log("" , newValue , oldValue ) if (this.weather == true){ this.tip = "请注意降温"; } } }) </script> </body> </html>
vue的多层级的监视(监视test下的a属性):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> </head> <body> <!-- --> <!-- 例一 --> <div id = "app"> <span>a的值{{test.a}}</span> <button @click="test.a++">a++</button> <span>b的值{{test.b}}</span> <button @click="test.b++">b++</button> </div> <script> var vm = new Vue({ el: "#app", data :{ test:{ a: 1, b: 2 } }, computed: {//计算属性 传入配置对象 }, methods: { }, }) //在保证vm已经被实例化的前提下,监视还可以这样写 //vue的深度监视(监视多级下的某个属性,必须写全),如果想要监视test下的a的话,则需要用引号引起来并逐级,而如果想要监听某个属性里面的全部属性的话,则需要 vm.$watch('test.a',{//第一个参数传入需要监视的属性,第二个参数传入配置对象,配置对象内容跟上面一模一样 deep: true,//而如果想要监听某个属性里面的所有属性的变化的话,则需要添加这个配置,目前是监听了a里面所有的属性变化 immediate: false,//true表示初始化时调用一次handler 'handler'(newValue,oldValue){// /* * 可以在这里面添加其他逻辑,比如在监听到属性发生改变时,提示天气炎热需要加衣服等等其他逻辑 * */ console.log("" , newValue , oldValue ) } }) </script> </body> </html>
最后补充一下,vue的计算属性和监视属性在实现功能上,可能会有重合的地方,比如一个需求可以用计算属性实现也可以用监视属性实现(我前面的计算属性那个案例就可以用监视属性实现),这种情况哪种简单就用哪种。但是~~~还有一种情况,可能必须要用监视属性实现,比如同样是那个计算属性的案例,它需要在name变化后一秒再执行,因为计算属性展示的是计算属性里面的返回值,当你用了延时执行方法后,return就变成了延时执行方法的返回值了,而不是计算属性的返回值,页面得不到计算属性的返回值就会出问题,这种情况只能用监视属性,因为监视属性没有返回值,它是直接通过代码修改了data里面的属性,导致页面数据展示发生改变。
但是~~~还有一个注意事项,如果在监视属性里面写延时函数的话,必须要用箭头函数写,因为用普通函数写的话,this表达的就不是vm实例对象了,将无法通过代码给vm的data属性重新赋值。
总结
1.所有被vue管理的函数,最好写成普通函数,这样this的只想才是vm 或者组件实例对象
2.所有不被vue管理的函数(定时器的回调函数,ajax的回调函数等),最好写成箭头函数( ()=>{} )这样this的指向才是vm或者组件实例对象