什么是API、computed和watch的区别及各个原理

什么是API(通俗易懂)

官方回答:
API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

简单通俗点来说:
举个例子:打开一个文件,将文件保存在硬盘上,要经过非常复杂的处理才能显示,这看似简单的操作其实在底层是非常复杂的

打开文件首先要扫面硬盘,找到文件的位置,然后从文件中读取一部分的数据,将数据放进I/O缓冲区,放进内存,这些数据都是0、1序列,而且是对照ASCII表和Unicode表翻译成字符串,然后在显示器显示出来,这个过程超复杂,那怎么搞呢?

操作系统想了个很好的办法,他就预先将这些复杂的操作写在一个函数内,编译成组件(一般都是动态链接库),跟着操作系统一起发布,并配上文档说明,程序员们只需简单的调用这些函数即可完成复杂的工作,这些封装好的函数,就叫做API(Application Programming Interface),即应用程序编程接口

更通俗易懂的说法就是:别人封装好的代码或编译好的程序,提供给你使用就叫做API,而你使用了别人的代码(或程序)中的某个函数、类、对象,就叫做使用的某个API
各种编程语言自带的标准库也是API。这些API由编程语言的开发者们编写,安全、高效、健壮,为我们实现了常见的功能,让我们不用再重复造轮子。

computed和watch的区别及各个原理(不易理解,可查官网文档)

两者区别

1.watch的监听只能是单个的监听,每次监听只能监听一个变量的修改,不能同时监听多个变量的修改,计算属性computed可以依赖多个数据的变化(并且只跟他所依赖的项进行关联)
2.当需要在数据变化时执行异步或开销较大的操作时,只能采用watch

详细解释:

计算属性component
computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理;

计算属性写法是一个函数,但是在界面中调用的话需要写成属性的方式进行调用计算属性会根据现有的数据生成一个新的数据,并且两者会产生关联,建立永久性缓存并且当无关数据发生改变的时候,计算属性内部不会重新计算,而是直接从缓存里面取值使用即可。

computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化,举例:购物车里面的商品列表和总金额之间的关系,只要商品列表里面的商品数量发生变化,或减少或增多或删除商品,总金额都应该发生变化。这里的这个总金额使用computed属性来进行计算是最好的选择

1、支持缓存,只有依赖数据发生改变,才会重新进行计算
2、不支持异步,当computed内有异步操作时无效,无法监听数据的变化
3、computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
4、如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
5、如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。

 <p>{{luFei_Name}}</p>
        vm = new Vue({
            el:"#app",
            data: {
                // 路飞的全名:蒙奇·D·路飞
                firstName: '蒙奇',
                secName: 'D',
                thirdName: '路飞'
            },
            computed: {
                luFei_Name: function () {
                return this.firstName + this.secName + this.thirdName
                }
            }
        })
        // 将“路飞”改为“海军王”
        vm.thirdName = '海军王'  // 蒙奇·D·海军王

watch

watch主要用于监控vue实例的变化,它监控的变量当然必须在data里面声明才可以,它可以监控一个变量,也可以是一个对象,但是我们不能类似这样监控,这样会报错,如下:

watch:{
	goodsList.price(newVal,oldVal){
	    //监控商品列表中是商品价格
	}
}

但是可以将对象写成字符串的形式:
在这里插入图片描述
1、不支持缓存,数据变,直接会触发相应的操作;
2、watch支持异步;
3、监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
4、当一个属性发生变化时,需要执行对应的操作;一对多;
5、监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数:   
immediate:组件加载立即触发回调函数执行,   
deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。

vm = new Vue({
    el:"#app",
    // (多个)船员名称数据 --> 依赖于 --> (1个)一一一名称数据 一个数据变化 --->  多个数据全部变化
    data: {
        haiZeiTuan_Name: '一一一',	
        suoLong: '一一一索隆', 
        naMei: '一一一娜美',
        xiangJiShi: '一一一香吉士'
    },
    watch: {
        haiZeiTuan_Name: function (newName) {	//函数的名字需是上面data内的数据,只能监控一个对象或一个变量
        this.suoLong = newName + '索隆'
        this.naMei = newName + '娜美'
        this.xiangJiShi = newName + '香吉士'
        console.log(this.suoLong)
        console.log(this.naMei)
        console.log(this.xiangJiShi)
        }
    }
})
vm.haiZeiTuan_Name = '二二二'       //全局更改名字

method与component的区别:

new Vue({
  el: '#app',
  // 设置两个button,点击分别调用getMethodsDate,getComputedDate方法
  template: 
'<div id="app">
    <button @click="getMethodsDate">methods</button>
    <button @click="getComputedDate">computed</button>
</div>',
  methods: {
    getMethodsDate: function () {
      alert(new Date())
    },
    // 返回computed选项中设置的计算属性——computedDate
    getComputedDate: function () {
      alert(this.computedDate)
    }
  },
  computed: {
    computedDate: function () {
      return new Date()
    }
  }

注意
1、两次点击computed返回的时间是相同的!!
两次点击computed返回的时间是相同的!!
两次点击computed返回的时间是相同的!!
2、两次点击methods返回的时间是不同的

原因:
new Date()不是依赖型数据(不是放在data等对象下的实例数据),所以computed只提供了缓存的值,而没有重新计算
只有符合:1.存在依赖型数据 2.依赖型数据发生改变这两个条件,computed才会重新计算。

Watch源码的工作流程

1.初始化组件上配置的watcher属性
2.对watcher属性可能的写法进行规整,得出key和handle
3.通过new Watcher 来创建一个基于key和handle的观察者
4.Watcher 的key为响应式的vm 上的变量,在watcher.get的时候,watcher订阅了对应key的变化。完成响应依赖。
5.当key的值发生了变化,触发watcher的更新方法,并执行回调函数handle

computed源码的流程

1.初始化的时候会获取computed里的定义。
2.通过遍历第一步的结果,按照computed新的变量名生成Watcher实例。
3.computed的watcher默认是lazy模式的,所以new Watcher 的时候不会调用watcher实例的get方法
4.vue 为computed 里的每个key 代理了一个新的get方法createComputedGetter(),当render页面的时候,新的get调用computed watcher实例的默认get方法。
5.computed执行自定义get方法的时候,会判断是否依赖又变动,没有的话,直接取值,否则去执行获取依赖的变量。
6.获取依赖变量的时候,将computed的watcher实例订阅到依赖的变量的Dep里。
7.走完这一步后,再调用计算列的watcher.depend将组件的watcher实例也订阅到计算列依赖的所有变量的dep中。
8.这样,当变量变化后,会通知computed的watcher将dirty设置为true, 以及组件的watcher更新dom。

注意事项

1.watcher 初始化是不执行的,如果想初始化就执行的话可以配置immediate属性
2.一般情况不要直接修改computed的值,会报错,一般通过为computed属性自定义set方法,通过改变依赖变量来改变computed的值
3.computed的属性如果不加入在dom中渲染是不会被加入到响应系统的。所以如果只是数据的变动的监控,不映射到dom上,请使用watcher或者其他方法。
4.watcher和computed 属性定义的函数不能使用箭头函数,否则内部this会指向组件的父环境,比如window,导致调用失败。

简单总结一下:

watch只能监听一个对象或变量(对象或变量必须是上面data内的数据,对象的话可以写成字符串形式“object.xxx”:对象内部的xxx),比如上面watch的案例,他的内部可以写多个数据与这个监听的数据进行关联,当该数据发生改变的时候,所有的内部数据也都会随着改变,可以做一些开销大的操作,可以进行异步操作
computed是计算属性,需写成函数的形式(可自定义函数名),该函数内部的变量依赖于data内的数据,但内部定义的变量可以缓存,当外面数据没有更改的时候,他是不会触发的,当所依赖的数据进行更改后,他才会重新计算,更新数据,他的内部可以监听多个依赖的数据,他不会进行异步操作

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值