【Vue】学习笔记-计算属性/侦听属性
需求
通常在UI上操作数据时候,会把计算值动态显示在UI上。如姓,名。
用户在修改姓或名时,全名就自动跟随着变化。
插值语法
<!--准备好一个容器--><div id="root">姓:<input type="text" v-model="firstName"> <br/><br/>名:<input type="text" v-model="lastName"> <br/><br/>全名:<span>{{firstName.slice(0.3)}}-{{lastName}}</span></div><script type="text/javascript">Vue.config.productionTip =false //阻止生产环境的提示信息//创建Vue实列const x=new Vue({el:'#root', data:{ firstName:'张',lastName:'三'},});</script>
Method实现
数据发生变化,模板就会被重新解析
<div id="root">姓:<input type="text" v-model="firstName"> <br/><br/>名:<input type="text" v-model="lastName"> <br/><br/>全名:<span>{{fullName()}}</span></div><script type="text/javascript">Vue.config.productionTip =false //阻止生产环境的提示信息//创建Vue实列const x=new Vue({el:'#root', data:{ firstName:'张',lastName:'三'},methods:{fullName(){console.log('@---') //每次模板都会重新解析return this.firstName+'-'+this.lastName;}}});</script>
Computed 计算属性
计算属性:
- 定义:要用的属性不存在,要通过已有属性计算得来
- 原理: 底层借助了object.defineproperty方法提供的getter和setter
- get函数什么时候执行?
(1)初次读取时会执行一次
(2)当以来的数据发生改变时候会被再次调用 - 优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便
- 备注:
1.计算属性最终会出现在vm上,直接读取使用即可
2.如果计算属性要被修改,那必须与set函数去相应修改,且set中要引起计算时以来的数据发生改变
<div id="root">姓:<input type="text" v-model="firstName"> <br/><br/>名:<input type="text" v-model="lastName"> <br/><br/>测试:<input type="text" v-model="x"> <br/><br/>全名:<span>{{fullName}}</span> <br/><br/>全名:<span>{{fullName}}</span> <br/><br/>全名:<span>{{fullName}}</span> <br/><br/></div><script type="text/javascript">Vue.config.productionTip =false //阻止生产环境的提示信息//创建Vue实列const vm=new Vue({el:'#root', data:{ firstName:'张',lastName:'三', x:'test'},computed:{fullName:{//get有什么作用?当有人读取fullName时.get就会被调用。且返回值就作为fullName的值//get什么时候被调用?初次读取fullName时 2.所以来的数据发生变化时 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]}}}});</script>
侦听属性
<!--准备好一个容器--><div id="root"><h1>今天天气很{{info}}.{{x}}</h1><!--插值语法--><button @click="changeWeather">切换天气-方法</button><!--绑定事件的时候:@xxx="yyy可以写一些简单的语句"--><button @click="isHot=!isHot;x++">切换天气-表达式</button><button @click="window.alert(1)">切换天气-弹窗</button></div><script type="text/javascript">Vue.config.productionTip =false //阻止Vue启动时生成提示//创建Vue实列const x=new Vue({el:'#root', data:{ isHot:true,x:1,window},computed:{info(){return this.isHot?'炎热':'凉爽'}},methods:{ changeWeather(){this.isHot=!this.isHotthis.x++}}});</script>
监视属性
监视属性watch:
- 当被监视的属性变化时, 回调函数自动调用, 进行相关操作
- 监视的属性必须存在,才能进行监视!!
- 监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视
<div id="root"><h2>今天天气很{{info}}</h2><button @click="changeWeather">切换天气</button></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',data:{isHot:true,},computed:{info(){return this.isHot ? '炎热' : '凉爽'}},methods: {changeWeather(){this.isHot = !this.isHot}},/* watch:{isHot:{immediate:true, //初始化时让handler调用一下//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>
深度监视
深度监视:
(1).Vue中的watch默认不监测对象内部值的改变(一层)。
(2).配置deep:true可以监测对象内部值改变(多层)。
备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视。
<!-- 准备好一个容器--><div id="root"><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">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',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:{// immediate:true, //初始化时让handler调用一下//handler什么时候调用?当isHot发生改变时。handler(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue)}},//监视多级结构中某个属性的变化/* 'numbers.a':{handler(){console.log('a被改变了')}} *///监视多级结构中所有属性的变化numbers:{deep:true,handler(){console.log('numbers改变了')}}}})</script>
监视属性简写
如果监视属性除了handler 没有其他配置项的话,可以进行简写
<!-- 准备好一个容器--><div id="root"><h2>今天天气很{{info}}</h2><button @click="changeWeather">切换天气</button></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',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',{immediate:true, //初始化时让handler调用一下deep:true,//深度监视handler(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue)}}) *///简写/* vm.$watch('isHot',(newValue,oldValue)=>{console.log('isHot被修改了',newValue,oldValue,this)}) */</script>
计算属性VS侦听属性
computed和watch之间的区别:
- computed能完成的功能,watch都可以完成。
- watch能完成的功能,computed不一定能完成,例如:
watch可以进行异步操作。
两个重要的小原则:
- 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
- 所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。
使用计算属性
new Vue({el:'#root', data:{ firstName:'张',lastName:'三', x:'test'},computed:{fullName:{return this.firstName+'-'+this.lastName}}}});
使用监视属性
const vm = new Vue({el:'#root',data:{firstName:'张',lastName:'三',fullName:'张-三'},watch:{firstName(val){setTimeout(()=>{console.log(this)this.fullName = val + '-' + this.lastName},1000);},lastName(val){this.fullName = this.firstName + '-' + val}}})