8-3、computed计算属性
计算属性:
1.定义:要用的属性不存在,要通过已有属性计算得来。
2.原理:底层借助了Objcet.defineproperty方法提供的getter和setter。
3.get函数什么时候执行?
(1).初次读取时会执行一次。
(2).当依赖的数据发生改变时会被再次调用。
4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
5.备注:
(1).计算属性最终会出现在vm上,直接读取使用即可。
(2).如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>姓名案例_计算属性基本实现</title> <script type="text/javascript" src="Vue/js/vue.js"></script> </head> <body> <div id="app"> 姓:<input type="text" v-model="firstName"/><br> 名:<input type="text" v-model="lastName"/><br> 全名:<span>{{fullName}}</span> </div> </body> <script type="text/javascript"> const vm =new Vue({ el:'#app', data:{ firstName:'张', lastName:'三', }, computed:{ fullName:{ //get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值 //get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。 get(){ console.log('get被调用了') // 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> </html>
8-4、计算属性简写
把computed里面的东西进行简写,确定只读取不修改(只有get没有set)
//完整写法 /* fullName:{ get(){ console.log('get被调用了') return this.firstName + '-' + this.lastName }, set(value){ console.log('set',value) const arr = value.split('-') this.firstName = arr[0] this.lastName = arr[1] } } */ //简写 确定只读取不修改(只有get没有set) fullName(){ console.log('get被调用了') return this.firstName + '-' + this.lastName }
9、监视属性
9-1、watch监视属性
监视属性watch:
1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作
2.监视的属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>天气案例_监视属性</title> <!-- 引入Vue --> <script type="text/javascript" src="Vue/js/vue.js"></script> </head> <body> <div id="app"> <h2>今天天气很{{info}}</h2> <button @click="changeWeather">切换天气</button> </div> </body> <script type="text/javascript"> const vm = new Vue({ el:'#app', data:{ isHot:true, }, computed:{ info(){ return this.isHot ? '炎热' : '凉爽' } }, methods: { changeWeather(){ this.isHot = !this.isHot } }, /* watch:{ isHot:{ immediate:true, //初始化时让handler调用一下,默认为false //handler什么时候调用?当isHot发生改变时。 handler(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue) } } } */ }) vm.$watch('isHot',{ immediate:true, //初始化时让handler调用一下 //handler什么时候调用?当isHot发生改变时。 handler(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue) } }) </script> </html>
9-2、深度监视属性
一、深度监视:
(1).Vue中的watch默认不监测对象内部值的改变(一层)。
(2).配置deep:true可以监测对象内部值改变(多层)。
二、备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>天气案例_深度监视</title> <script type="text/javascript" src="Vue/js/vue.js"></script> </head> <body> <div id="app"> <h2>今天天气很{{info}}</h2> <button @click="changeWeather">切换天气</button> <hr/> <h3>a的值是:{{numbers.a}}</h3> <button @click="numbers.a++">点我让a+1</button> <h3>b的值是:{{numbers.b}}</h3> <button @click="numbers.b++">点我让b+1</button> <button @click="numbers = {a:666,b:888}">彻底替换掉numbers</button> {{numbers.c.d.e}} </div> </body> <script type="text/javascript"> const vm = new Vue({ el:'#app', data:{ isHot:true, numbers:{ a:1, b:1, c:{ d:{ e:100 } } } }, computed:{ info(){ return this.isHot ? '炎热' : '凉爽' } }, methods: { changeWeather(){ this.isHot = !this.isHot } }, watch:{ isHot:{ handler(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue) } }, //监视多级结构中某个属性的变化 /* 'numbers.a':{ handler(){ console.log('a被改变了') } } */ //监视多级结构中所有属性的变化 numbers:{ deep:true, handler(){ console.log('numbers改变了') } } } }) </script> </html>
9-3、监视属性简写
当配置项里面不需要immediate和deep时可以简写
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>天气案例_监视属性_简写</title> <script type="text/javascript" src="Vue/js/vue.js"></script> </head> <body> <div id="app"> <h2>今天天气很{{info}}</h2> <button @click="changeWeather">切换天气</button> </div> </body> <script type="text/javascript"> const vm = new Vue({ el:'#app', data:{ isHot:true, }, computed:{ info(){ return this.isHot ? '炎热' : '凉爽' } }, methods: { changeWeather(){ this.isHot = !this.isHot } }, watch:{ //完整写法 /* isHot:{ // immediate:true, //初始化时让handler调用一下 // deep:true,//深度监视 handler(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue) } }, */ //简写 isHot(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue,this) } } }) //完整写法 /* vm.$watch('isHot',{ deep:true,//深度监视 handler(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue) } }) */ //简写,这里的this指的是window /* vm.$watch('isHot',(newValue,oldValue)=>{ console.log('isHot被修改了',newValue,oldValue,this) }) */ </script> </html>
9-4、computed与watch比较
一、computed和watch之间的区别:
1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
二、两个重要的小原则:
1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>姓名案例_watch实现</title> <script type="text/javascript" src="Vue/js/vue.js"></script> </head> <body> <div id="app"> 姓:<input type="text" v-model="firstName"> <br/><br/> 名:<input type="text" v-model="lastName"> <br/><br/> 全名:<span>{{fullName}}</span> <br/><br/> </div> </body> <script type="text/javascript"> const vm = new Vue({ el:'#app', data:{ firstName:'张', lastName:'三', fullName:'张-三' }, watch:{ /* firstName(val){ this.fullName = val + '-' + this.lastName } }, */ firstName(val){ setTimeout(()=>{ console.log(this) this.fullName = val + '-' + this.lastName },1000); }, lastName(val){ this.fullName = this.firstName + '-' + val } } }) </script> </html>
10、绑定样式
10-1、style与class样式
1. class样式
写法:class="xxx" xxx可以是字符串、对象、数组。
字符串写法适用于:类名不确定,要动态获取。
对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
2. style样式
:style="{fontSize: xxx}"其中xxx是动态值。
:style="[a,b]"其中a、b是样式对象(key),且样式对象必须是存在的。
案例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>绑定样式</title> <style> .basic{ width: 400px; height: 100px; border: 1px solid black; } .happy{ border: 4px solid red;; background-color: rgba(255, 255, 0, 0.644); background: linear-gradient(30deg,yellow,pink,orange,yellow); } .sad{ border: 4px dashed rgb(2, 197, 2); background-color: gray; } .normal{ background-color: skyblue; } .a1{ background-color: yellowgreen; } .a2{ font-size: 30px; text-shadow:2px 2px 10px red; } .a3{ border-radius: 20px; } </style> <script type="text/javascript" src="Vue/js/vue.js"></script> </head> <body> <div id="app"> <!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 --> <div class="basic" :class="mood" @click="changeMood">{{name}}</div> <br/><br/> <!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 --> <div class="basic" :class="classArr">{{name}}</div> <br/><br/> <!-- 绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用 --> <div class="basic" :class="classObj">{{name}}</div> <br/><br/> <!-- 绑定style样式--对象写法 --> <div class="basic" :style="styleObj">{{name}}</div> <br/><br/> <!-- 绑定style样式--数组写法 --> <div class="basic" :style="styleArr">{{name}}</div> </div> </body> <script type="text/javascript"> const vm = new Vue({ el:'#app', data:{ name:'111', mood:'normal', classArr:['a1','a2','a3'], classObj:{ a1:false, a2:false, }, styleObj:{ fontSize: '40px', color:'red', }, styleObj2:{ backgroundColor:'orange' }, styleArr:[ { fontSize: '40px', color:'blue', }, { backgroundColor:'gray' } ] }, methods: { changeMood(){ const arr = ['happy','sad','normal'] const index = Math.floor(Math.random()*3) this.mood = arr[index] } }, }) </script> </html>
11、条件渲染
11-1、隐藏div的方法:
1、div的visibility控制div的隐藏和显示
style="visibility: none;"
2、设置display属性 可以是div隐藏后释放占用的页面空间
style="display: none;"
3、opacity设置元素透明度为0
style="opacity:0;"