10-Vue核心-监视属性
我们通过实现一个天气案例,引出监视属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>天气案例</title> <!--引入Vue--> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!--准备好一个容器--> <div id="root"> <!-- 三元表达式 条件表达式?表达式1:表达式2; a) 如果条件表达式为true,则运算后的结果是表达式1; b) 如果条件表达式为false,则运算后的结果是表达式2; --> <!--插值语法实现天气案例--> <h2>今天天气很{{isHot ? "炎热" : "凉爽"}}</h2> <!--计算属性实现天气案例--> <h2>今天天气很{{info}}</h2> <button @click="changeWeather">切换天气</button> </div> <script type="text/javascript"> // 阻止 vue 在启动时生成生产提示 Vue.config.productionTip = false; new Vue({ el:"#root", data(){ return{ isHot:true } }, methods:{ // 切换天气方法 changeWeather(){ this.isHot = !this.isHot } }, computed:{ //计算属性的简写形式 info(){ return this.isHot ? "炎热" : "凉爽" } } }) </script> </body> </html>
通过上面的天气案例,我们发现,如果能对普通属性 isHot 或者 计算属性 info 进行监视,当被监视的属性发生变化时,则可以进行相应的操作,这也就是我们即将引出的监视属性。
监视属性watch
1) 当被监视的属性发生变化时,handle()回调函数自动调用
2) 监视的属性必须存在,才能进行监视
3) 当监视的属性发生改变时,调用一次handle(newValue,oldValue)回调函数,其中newValue代表改变后的值,oldValue代表改变前的值
4) 配置项属性immediate默认为false,当immediate为true时,则初始化时调用一下handle()回调函数
监视属性的两种写法
1) new Vue 传入watch配置
const vm = new Vue({ el:"#root", data(){ return{ isHot:true } }, // 1.监视属性的第一种写法 watch:{ isHot:{ //immediate为true时,初始化时调用一下handler()函数 immediate:true, // 当属性isHot发生改变时,调用handler()函数 handler(newValue, oldValue){ console.log("isHot正在被修改...") console.log("修改后的值:" + newValue + "\t修改前的值:" + oldValue) //第一次初始化时,修改后的值:true 修改前的值:undefined } } } })
2) 通过vm实例对象进行监视,vm.$watch()
const vm = new Vue({ el:"#root", data(){ return{ isHot:true } }, }) // 2.监视属性的第二种写法 vm.$watch("isHot",{ //immediate为true时,初始化时调用一下handler()函数 immediate:true, // 当属性isHot发生改变时,调用handler()函数 handler(newValue, oldValue){ console.log("isHot正在被修改...") console.log("修改后的值:" + newValue + "\t修改前的值:" + oldValue) //第一次初始化时,修改后的值:true 修改前的值:undefined } })
使用监视属性,完成对天气案例的一些操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>天气案例_监视属性</title> <!--引入Vue--> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!--准备好一个容器--> <div id="root"> <!--监视属性实现天气案例--> <h2>今天天气很{{info}}</h2> <button @click="changeWeather">切换天气</button> </div> <script type="text/javascript"> // 阻止 vue 在启动时生成生产提示 Vue.config.productionTip = false; const vm = new Vue({ el:"#root", data(){ return{ isHot:true } }, methods:{ // 切换天气方法 changeWeather(){ this.isHot = !this.isHot } }, computed:{ // 计算属性的简写形式 info(){ return this.isHot ? "炎热" : "凉爽" } }, // // 1.监视属性的第一种写法 // watch:{ // // 监视普通属性 isHot // isHot:{ // //immediate为true时,初始化时调用一下handler()函数 // immediate:true, // // // 当属性isHot发生改变时,调用handler()函数 // handler(newValue, oldValue){ // console.log("isHot正在被修改...") // console.log("修改后的值:" + newValue + "\t修改前的值:" + oldValue) //第一次初始化时,修改后的值:true 修改前的值:undefined // } // }, // // 也可以监视计算属性 info // info:{ // //immediate为true时,初始化时调用一下handler()函数 // immediate:true, // // // 当计算属性info发生改变时,调用handler()函数 // handler(newValue, oldValue){ // console.log("info正在被修改...") // console.log("修改后的值:" + newValue + "\t修改前的值:" + oldValue) //第一次初始化时,修改后的值:炎热 修改前的值:undefined // } // } // } }) // 2.监视属性的第二种写法 vm.$watch("isHot",{ //immediate为true时,初始化时调用一下handler()函数 immediate:true, // 当属性isHot发生改变时,调用handler()函数 handler(newValue, oldValue){ console.log("isHot正在被修改...") console.log("修改后的值:" + newValue + "\t修改前的值:" + oldValue) //第一次初始化时,修改后的值:true 修改前的值:undefined } }) </script> </body> </html>
监视属性中多级结构的写法
1) 监视多级结构中某个属性的变化
"属性.xxx": {}
2) 监视多级结构中所有属性的变化\
属性:{} 或 "属性":{}
const vm=new Vue( { el:"#root", data() { return { numbers: { a: 10, b:20 } } } , watch: { // 监视多级结构中某个属性的变化,一定要用最原始的方法,"属性.xxx":{} // 监视普通属性 numbers 里面的 a "numbers.a": { // immediate为true时,初始化时调用一下handler()函数 // immediate:true, // 当属性isHot发生改变时,调用handler()函数 handler(newValue, oldValue) { console.log("numbers的a正在被修改...")
console.log("修改后的值:"+ newValue + "\t修改前的值:"+ oldValue) } } , // 监视多级结构中所有属性的变化,可以使用"属性":{},也可以属性:{} numbers: { // 深度监视,deep默认是false,不监测对象内部值的改变 // 也就是说,当deep=false时,numbers里面a或b发生改变时,是不会调用handler()函数,只有当numbers里面的所有属性发生改变,才会调用handler()函数 // 当deep=true时,只要number中的属性发生变化,就会调用handler()函数 deep:true, // immediate为true时,初始化时调用一下handler()函数 // immediate:true, // 当属性isHot发生改变时,调用handler()函数 handler(newValue, oldValue) { console.log("numbers正在被修改...") console.log("a修改后的值:"+ newValue.a + "\ta修改前的值:"+ oldValue.a)
console.log("b修改后的值:"+ newValue.b + "\tb修改前的值:"+ oldValue.b) } } } })
监视属性watch -- 深度监视
1) Vue中的watch默认不监测对象内部值的改变(一层),也就是默认不开启深度监测,deep的默认值为false。
2) 配置深度监测,deep:true可以监测对象内部值改变(多层)。
备注:
1) Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以
2) 使用watch时,根据数据的具体结构,决定是否采用深度监视
使用监视属性中的深度监视,完成对天气案例的一些操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>天气案例_深度监视</title> <!--引入Vue--> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!--准备好一个容器--> <div id="root"> <!--监视属性实现天气案例--> <h2>今天天气很{{info}}</h2> <button @click="changeWeather">切换天气</button> <!--分隔符<hr/>--> <hr/> <h3>a的值:{{numbers.a}}</h3> <button @click="numbers.a++">a自增按钮</button> <h3>b的值:{{numbers.b}}</h3> <button @click="numbers.b++">b自增按钮</button> <button @click="numbers = {a:100,b:200}">彻底替换掉numbers</button> </div> <script type="text/javascript"> // 阻止 vue 在启动时生成生产提示 Vue.config.productionTip = false; const vm = new Vue({ el:"#root", data(){ return{ isHot:true, numbers:{ a:10, b:20 } } }, methods:{ // 切换天气方法 changeWeather(){ this.isHot = !this.isHot } }, computed:{ // 计算属性的简写形式 info(){ return this.isHot ? "炎热" : "凉爽" } }, watch:{ // 监视普通属性 isHot isHot:{ // immediate为true时,初始化时调用一下handler()函数 // immediate:true, // 当属性isHot发生改变时,调用handler()函数 handler(newValue, oldValue){ console.log("isHot正在被修改...") console.log("修改后的值:" + newValue + "\t修改前的值:" + oldValue) } }, // 监视多级结构中某个属性的变化,一定要用最原始的方法,"属性.xxx":{} // 监视普通属性 numbers 里面的 a "numbers.a":{ // immediate为true时,初始化时调用一下handler()函数 // immediate:true, // 当属性isHot发生改变时,调用handler()函数 handler(newValue, oldValue){ console.log("numbers的a正在被修改...") console.log("修改后的值:" + newValue + "\t修改前的值:" + oldValue) } }, // 监视多级结构中所有属性的变化,可以使用"属性":{},也可以属性:{} numbers:{ // 深度监视,deep默认是false,不监测对象内部值的改变 // 也就是说,当deep=false时,numbers里面a或b发生改变时,是不会调用handler()函数,只有当numbers里面的所有属性发生改变,才会调用handler()函数 // 当deep=true时,只要number中的属性发生变化,就会调用handler()函数 deep:true, // immediate为true时,初始化时调用一下handler()函数 // immediate:true, // 当属性isHot发生改变时,调用handler()函数 handler(newValue, oldValue){ console.log("numbers正在被修改...") console.log("a修改后的值:" + newValue.a + "\ta修改前的值:" + oldValue.a) console.log("b修改后的值:" + newValue.b + "\tb修改前的值:" + oldValue.b) } } } }) </script> </body> </html>
监视属性的简写
如果监视属性,除了handler之外,没有其他的配置项了,可以进行简写
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>天气案例_监视属性_简写</title> <!--引入Vue--> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!--准备好一个容器--> <div id="root"> <!--监视属性实现天气案例--> <h2>今天天气很{{info}}</h2> <button @click="changeWeather">切换天气</button> </div> <script type="text/javascript"> // 阻止 vue 在启动时生成生产提示 Vue.config.productionTip = false; const vm = new Vue({ el:"#root", data(){ return{ isHot:true } }, methods:{ // 切换天气方法 changeWeather(){ this.isHot = !this.isHot } }, computed:{ // 计算属性的简写形式 info(){ return this.isHot ? "炎热" : "凉爽" } }, // 1.监视属性的第一种写法 watch:{ // 正常写法,监视普通属性 isHot // isHot:{ // // immediate为true时,初始化时调用一下handler()函数 // // immediate:true, // // // 深度监视,deep默认是false,不监测对象内部值的改变 // // deep:true, // // // 当属性isHot发生改变时,调用handler()函数 // handler(newValue, oldValue){ // console.log("isHot正在被修改...") // console.log("修改后的值:" + newValue + "\t修改前的值:" + oldValue) //第一次初始化时,修改后的值:true 修改前的值:undefined // } // }, // 简写写法,监视普通属性 isHot // 如果监视属性,除了handler之外,没有其他的配置项了,则可以进行简写 // isHot(newValue, oldValue){ // console.log("isHot正在被修改...") // console.log("修改后的值:" + newValue + "\t修改前的值:" + oldValue) //第一次初始化时,修改后的值:true 修改前的值:undefined // }, } }) // 2.监视属性的第二种写法 // 正常写法 // vm.$watch("isHot",{ // //immediate为true时,初始化时调用一下handler()函数 // immediate:true, // // // 当属性isHot发生改变时,调用handler()函数 // handler(newValue, oldValue){ // console.log("isHot正在被修改...") // console.log("修改后的值:" + newValue + "\t修改前的值:" + oldValue) //第一次初始化时,修改后的值:true 修改前的值:undefined // } // }) // 简写 // 注意,一般不写成箭头函数 vm.$watch("isHot",function (newValue, oldValue){ console.log("isHot正在被修改...") console.log("修改后的值:" + newValue + "\t修改前的值:" + oldValue) //第一次初始化时,修改后的值:true 修改前的值:undefined }) </script> </body> </html>