本文主要是介绍Moon系列之Methods、Computed、双向绑定,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
上一篇文章中了解了整个Moon构造函数的逻辑处理,本篇文章主要是去详细分析Moon是如何处理Methods、computed以及它是如何实现双向绑定的,vue.js是通过ES5的defineProperty来实现的,看看二者有何不同。
具体分析
还是通过简单的实例来分析methods、computed等,具体实例如下:
<div id="app"><p>{{getMsg}}</p></div><script src="./moon.js"></script><script>new Moon({el: '#app',data: {msg: 'hello world'},// 计算属性computed: {getMsg: {get() {let msg = this.get('msg');或者this.$data.msg直接获取return `js ${msg}`}}},methods: {outMsg() {console.log(this.$data.msg);}}});
首先明确几点:
- 在Js中应用data中的数据必须是this.$data.变量的形式或者通过Moon的get方法
- computed的使用必须写成get、set形式
methods
首先分析Methods,看看Moon是如何处理的,相关代码如下:
var initMethods = function (instance, methods) {var initMethod = function (methodName, method) {// 从此处可以看到2点信息:// 1:methods中定义的方法都会被添加到$data(数据中心)// 2:使用apply改变原先methods中的thisinstance.$data[methodName] = function () {return method.apply(instance, arguments);};};// 遍历methodsfor (var method in methods) {initMethod(method, methods[method]);}};
Moon中methods的调用形式有两种:
- 直接调用,this.$data.方法
- 使用Moon中提供的方式callMethod的形式:Moon实例.callMethod(方法,参数)
computed
计算属性的处理就不会像methods那么简单了,计算属性涉及到双向绑定以及缓存,具体代码如下:
var initComputed = function (instance, computed) {var setComputedProperty = function (prop) {// 获取observer对象,观察者var observer = instance.$observer;// 调用observe方法,为每一个计算属性创建一个clear清除缓存的函数observer.observe(prop);// 使用Object.defineProperty将计算属性定义到$data中并监听变化Object.defineProperty(instance.$data, prop, {get: function () {var cache = null;// 查找缓存中是否存在指定名称的computed,存在就取缓存中的计算属性if (observer.cache[prop] === undefined) {// 将observer.target就是当前计算属性名称observer.target = prop;// 调用computed中指定的计算属性,并将结果者赋给cachecache = computed[prop].get.call(instance);observer.target = null;// 保存当前计算结果到oberver.cache对象中observer.cache[prop] = cache;} else {cache = observer.cache[prop];}return cache;},set: noop});var setter = null;// computed中的计算属性中set方法都在observer.setter中if ((setter = computed[prop].set) !== undefined) {observer.setters[prop] = setter;}};// 遍历computedfor (var propName in computed) {setComputedProperty(propName);}};
从上面中可以得到计算属性也是被添加到$data中,计算属性的缓存是通过Observer中的cache属性来处理
双向绑定
Vue是基于数据劫持 + 发布者-订阅者模式实现双向绑定的,你可以使用this.name = name这样的简单形式实现视图更新。
Moon中并没有提供这种形式,它采用的是提供专门的set和get方法主动去触发$data中的数据的响应式变更。
具体看看set、get方法的实现:
- set
Moon.prototype.set = function (key, val) {// 获取observer观察者对象var observer = this.$observer;// resolveKeyPath处理获取指定的属性名,更新$data中的值var base = resolveKeyPath(this, this.$data, key, val);var setter = null;// 检查是否是计算属性,是则调用计算属性的set方法if ((setter = observer.setters[base]) !== undefined) {setter.call(this, val);}// 通知,清除包含指定属性的所有计算属性的cache(缓存)observer.notify(base, val);// 异步队列更新DOM视图// 实际上是重新调用Moon实例的build方法并执行updated生命周期函数queueBuild(this);};
queueBuid
var queueBuild = function (instance) {if (instance.$queued === false && instance.$destroyed === false) {instance.$queued = true;setTimeout(function () {// 实例的build方法,更新DOMinstance.build();// updated生命周期函数callHook(instance, 'updated');instance.$queued = false;}, 0);}};
- get
Moon.prototype.get = function (key) {// 获取var observer = this.$observer;var target = null;// observer.target表示计算属性的名称(这里主要是用于计算属性初始化过程中的处理逻辑)if ((target = observer.target) !== null) {// 构建map,map中存储每一个属性所在的所有计算属性Mapif (observer.map[key] === undefined) {// key就是$data中的属性,target就是依赖key的计算属性observer.map[key] = [target];} else if (observer.map[key].indexOf(target) === -1) {observer.map[key].push(target);}}return this.$data[key];};
从上面的实现逻辑中可以知道Moon中双向绑定实际的处理如下:
- 主动调用set方法,实现$data或计算属性的值变化
- get方法获取 d a t a 中数据,而在该方法中核心点是建立计算属性中的 data中数据,而在该方法中核心点是建立计算属性中的 data中数据,而在该方法中核心点是建立计算属性中的data依赖
只要你在computed中调用 d a t a 中变量,就会在 g e t 中建立 data中变量,就会在get中建立 data中变量,就会在get中建立data与computed之间的Map联系,这就是Moon是如何收集computed的方式。
总结
- Moon中对于Methods以及Computed的处理,都添加到data数据中心
- Moon中计算属性采用了Object.defineProperty,普通data中的变量没有采用
- d a t a 中变量通过 M o o n 实例提供的 s e t 来实现数据响应的,使用 g e t 来获取 data中变量通过Moon实例提供的set来实现数据响应的,使用get来获取 data中变量通过Moon实例提供的set来实现数据响应的,使用get来获取data中的数据。
- 计算属性中通过get来建立$data中变量与其的联系,使用Observer观察者对象的map来保存
- 通过set更新 d a t a 中数据之后会重新渲染,再次渲染时拿到的就是更新后的 data中数据之后会重新渲染,再次渲染时拿到的就是更新后的 data中数据之后会重新渲染,再次渲染时拿到的就是更新后的data,即双向绑定
这篇关于Moon系列之Methods、Computed、双向绑定的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!