Vue的computed和watch的区别

一、computed

1、 定义

计算属性,类似于过滤器,对绑定到view的数据进行处理。

2、 示例(get)
data: {
   firstName: 'Foo',
   lastName: 'Bar'
},
computed: {
  fullName: function () {
    return this.firstName + ' ' + this.lastName
  }
}

计算属性不可在data里面定义。变量不可被重复定义和赋值
不支持异步

3、get和set
data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
	  fullName:{
	  		//回调函数 当需要读取当前属性值fullName时执行,根据相关数据计算并返回当前属性的值
		   get(){ 
		      return this.firstName + ' ' + this.lastName
		    },
		    //监视当前属性值fullName的变化,当属性值发生变化时执行,更新相关的属性数据
		   set(val){
		       //val就是fullName的最新属性值
		       console.log(val)
		        const names = val.split(' ');
		        console.log(names)
		        this.firstName = names[0];
		        this.lastName = names[1];
		   }
	  }
 }

二、 watch

1、 定义

watch是一个观察的动作

2、 示例
data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
},
watch: {
	//监听firstName 
     firstName: function (val) {
	     this.fullName = val + ' ' + this.lastName
	 },
	 //监听lastName 
  	lastName: function (val) {
	     this.fullName = this.firstName + ' ' + val
	}
}
// 监听firstName和lastName的变化

监听数据必须是data中声明过或者父组件传递过来的props中的数据
支持异步

3、 监听简单数据类型
data(){
   return{
     'first':2
   }
},
watch:{
   first(){
    console.log(this.first)
   }
},	

4、 监听复杂数据类型

1、监听复杂数据类型需用深度监听

data(){
  return{
      'first':{
        second:0
     }
  }
},
watch:{
  secondChange:{
     handler(oldVal,newVal){
       console.log(oldVal)
       console.log(newVal)
     },
     deep:true
  }
},

2、console.log打印的结果,发现oldVal和newVal值是一样的,所以深度监听虽然可以监听到对象的变化,但是无法监听到具体对象里面那个属性的变化
3、oldVal和newVal值一样的原因是它们索引同一个对象/数组。Vue 不会保留修改之前值的副本
4、深度监听对应的函数名必须为handler,否则无效果,因为watcher里面对应的是对handler的调用

5、 监听对象单个属性

方法一:可以直接对用对象.属性的方法拿到属性

	 data(){
          return{
            'first':{
              second:0
            }
          }
        },
        watch:{
          first.second:function(newVal,oldVal){
            console.log(newVal,oldVal);
          }
        },
    

方法二:watch如果想要监听对象的单个属性的变化,**必须用computed作为中间件转化,**因为computed可以取到对应的属性值

data(){
      return{
        'first':{
          second:0
        }
      }
    },
    computed:{
      secondChange(){
        return this.first.second
      }
    },
    watch:{
      secondChange(){
        console.log('second属性值变化了')
      }
    },

三、 computed和watch的区别

1、 computed特性

1.是计算值,
2.应用:就是简化tempalte里面{{}}计算和 处理props或$emit的传值
3.具有缓存性,页面重新渲染值不变化,计算属性会立即返回之前的计算结果,而不必再次执行函数
4.不支持异步
5.不能在data中定义

2、 watch特性

1.是观察的动作,
2.应用:监听props,$emit或本组件的值执行异步操作
3.无缓存性,页面重新渲染时值不变化也会执行
4.支持异步
5.监听数据必须是data中声明过或者父组件传递过来的props中的数据。可以配合computed使用

4.props传值处理

4.1 常见错误

传入的值想作为局部变量来使用,直接使用会

props:['listShop'],
    data(){
      return{}
    },
    created(){
      this.listShop=30
}

在这里插入图片描述
这个错误是说的避免直接修改父组件传入的值,因为会改变父组件的值。

4.2 解决方案1

简单数据类型解决方案:
所以可以在data中重新定义一个变量,改变指向,但是也只是针对简单数据类型,因为复杂数据类型栈存贮的是指针,

props:['listShop'],
    data(){
      return{
        listShopChild:this.listShop
      }
    },
    created(){
      this.listShopChild=30
    }
    
4.3 存在问题

复杂数据类型栈存贮的是指针。所以赋值给新的变量也会改变原始的变量值
1.可以手动深度克隆一个复杂的数据出来,循环或者递归都行。
数组深度克隆:

var x = [1,2,3];
var y = [];
for (var i = 0; i < x.length; i++) {
    y[i]=x[i];
}
console.log(y);  //[1,2,3]
y.push(4);
console.log(y);  //[1,2,3,4]
console.log(x);  //[1,2,3]

对象深度克隆:

var x = {a:1,b:2};
var y = {};
for(var i in x){
    y[i] = x[i];
}
console.log(y);  //Object {a: 1, b: 2}
y.c = 3;
console.log(y);  //Object {a: 1, b: 2, c: 3}
console.log(x);  //Object {a: 1, b: 2}

函数深度克隆:

var x = function(){console.log(1);};
var y = x;
y = function(){console.log(2);};
x();  //1
y();  //2

你可能感兴趣的:(vue.js,javascript,前端)