目录
两个重要API,反应应聘者熟练程度。
1、不会立即执行,在监听到数据变化了才会改变,
指定 immediate: true 将立即以表达式的当前值触发回调,即在 wacth 中声明了 firstName 之后就会立即执行里面的 handler 方法,如果为 false 就跟原来的效果一样,不会在绑定的时候就执行
computed 用来监控自己定义的变量,该变量在 data 内没有声明,直接在 computed 里面定义,页面上可直接使用。
- //基础使用
- {{msg}}
- <input v-model="name" />
- //计算属性
- computed:{
- msg:function(){
- return this.name
- }
- }
在输入框中,改变 name 值得时候,msg 也会跟着改变。这是因为 computed 监听自己的属性 msg,发现 name 一旦变动,msg 立马会更新。
注意:msg 不可在 data 中定义,否则会报错(计算属性不可在data中定义,会报错)
- <input v-model="full" ><br>
- <input v-model="first" > <br>
- <input v-model="second" >
- data(){
- return{
- first:'美女',
- second:'姐姐'
- }
- },
- computed:{
- full:{
- get(){ //回调函数 当需要读取当前属性值是执行,
- // 根据相关数据计算并返回当前属性的值
- return this.first + ' ' + this.second
- },
- set(val){ //监视当前属性值的变化,
- //当属性值发生变化时执行,更新相关的属性数据
- let names = val.split(' ')
- this.first = names[0]
- this.second = names[1]
- }
- }
- }
get 方法:first 和 second 改变时,会调用 get 方法,更新 full 的值。
set 方法:修改 full 的值时,会调用 set 方法,val 是 full 的最新值。
计算属性是基于它们的依赖项的值结果进行缓存的,只要依赖的变量不变, 都直接从缓存取结果
我们通过方法,拼接数据,也可以实现该效果,代码如下。
- <div> {{ full() }} </div>
- data(){
- return{
- first:'美女',
- second:'姐姐'
- }
- },
- methods:{
- full(){
- return this.first + ' ' + this.second
- }
- }
一个页面内,数据有可能多次使用,我们把 computed 和 method 两个方法放一起实现,并把这个数据在页面内多次引用,试看以下效果。
- <div>
- computed计算值:
- {{full}} {{full}} {{full}} {{full}}
- </div>
-
- <div>
- methods计算值:
- {{fullt}} {{fullt}} {{fullt}} {{fullt}}
- </div>
-
- data(){
- return{
- first:'美女',
- second:'姐姐'
- }
- },
- computed:{
- full:function(){
- console.log('computed')
- return this.first + ' ' + this.second
- }
- },
- methods:{
- fullt(){
- console.log('method')
- return this.first + ' ' + this.second
- }
- }
运行结果为:

根据结果,我们不难发现,根据方法获取到的数据,使用几次就需要重新计算几次,但计算属性不是,而是基于它们的响应式依赖进行缓存的,之后依赖属性值发生改变的时候,才会重新计算。由于它计算次数少,所以性能更高些。
watch 是监测 Vue 实例上的数据变动,通俗地讲,就是检测 data 内声明的数据。不仅可以监测简单数据,还可以监测对象或对象属性。
- <input v-model="first" > <br>
- data(){
- return{
- first:'美女',
- }
- },
- watch:{
- first( newVal , oldVal ){
- console.log('newVal',newVal) // first 的最新值
- console.log('oldVal',oldVal) // first上一个值
- }
- }
- // 修改 first的值的时候,立马会打印最新值
监听对象的时候,需要使用深度监听。
- <input v-model="per.name">
- data(){
- return{
- per:{
- name:'倩倩',
- age:'18'
- }
- }
- },
- watch:{
- per:{
- handler(oldVal,newVal){
- console.log('newVal',newVal)
- console.log('oldVal',oldVal)
- },
- deep:true,
- }
- },
修改 per.name 的时候,发现 newVal 和 oldVal 的值是一样的,是因为他们存储的指针指向的是同一个地方,所以深度监听虽然可以监听到对象的变化,但是无法监听到具体的是哪个属性发生变化了。
- // 方法1:直接引用对象的属性
- <input v-model="per.name">
- data(){
- return{
- per:{
- name:'倩倩',
- age:'18'
- }
- }
- },
- watch:{
- 'per.name':function(newVal,oldVal){
- console.log('newVal->',newVal)
- console.log('oldVal->',oldVal)
- }
- }
也可以借助 computed 作为中间转换,如下:
- <input v-model="per.name">
-
- data(){
- return{
- per:{
- name:'倩倩',
- age:'18'
- }
- }
- },
- watch:{
- perName(){
- console.log('name改变了')
- }
- },
- computed:{
- perName:function(){
- return this.per.name
- }
- }
- props:{
- mm:String
- },
- //不使用 immediate
- watch:{
- mm(newV,oldV){
- console.log('newV',newV)
- console.log('oldV',oldV)
- }
- }
-
- //使用 immediate
- watch:{
- mm:{
- immediate:true,
- handler(newV,oldV){
- console.log('newV',newV)
- console.log('oldV',oldV)
- }
- }
不使用 immediate 时,第一次加载页面时,watch 监听的 mm 中的打印并没有执行。
使用 immediate 时,第一次加载时也会打印结果:newV 11 oldV undefined。
immediate 主要作用就是组件加载时,会立即触发回调函数。
computed 监控的数据在 data 中没有(不用)声明
computed 不支持异步,当 computed 中有异步操作时,无法监听数据的变化
computed 具有缓存,页面重新渲染,值不变时,会直接返回之前的计算结果,不会重新计算
如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,一般使用 - ------computed
computed 计算属性值是函数时,默认使用get方法。如果属性是完整写法时,属性有一个get和set方法,当数据发生变化时会调用set方法
- computed:{
- //属性值为函数
- perName:function(){
- return this.per.name
- },
- //完整写法
- full:{
- get(){ },
- set(val){ }
- }
- },
监测的数据必须在 data 中声明或 props 中数据
支持异步操作
没有缓存,页面重新渲染时,值不改变时也会执行
当一个属性值发生变化时,就需要执行相应的操作
监听数据发生变化时,会触发其他操作,函数有两个参数:
- immediate :组件加载立即触发回调函数
- deep:深度监听,主要针对复杂数据,如监听对象时,添加深度监听,任意的
- 属性值改变都会触发。
- 注意:对象添加深度监听之后,输出的新旧值是一样的。
computed 页面重新渲染时,不会重复计算,而 watch 会重新计算,所以 computed 性能更高些。
当需要进行数值计算,并且依赖于其它数据时,应该使用 computed ,因为可以利用 computed 的缓存特性,避免每次获取值时都要重新计算。
当需要在数据变化时执行异步操作或开销较大的操作时,应该使用 watch,computed 不支持异步。如果需要限制执行操作的频率,可借助 computed 作为中间状态。