Vue源码分析之reduce()的思考

1,242 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情

如果Vue中data的数据嵌套层数较多的情况下,是如何实现双向数据绑定的呢?例如:

<template>  
  <div class="app">    
     <p>{{ items.item.a }}</p>    
     <p>{{ items.item.b.c }}</p>  
  </div>
</template>
<script>
export default {  
  name: "App",  
  data() {    
    return {      
       items: {        
         item: {          
           a: 1,          
           b: {            
             c: 2,          
           },        
         },      
       },    
    };  
  },  
  methods: {},
};
</script>

那Vue中是怎么解析items.item.a和items.item.b.c这样数据的呢?

complie解析过程中,用到了reduce归并数组的写法。下面我们先来简单看一下reduce的用法。

reduce():数组的归并方法

语法:

array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

接受两个参数:

  • 一个是在每一项上调用的函数
    这个调用函数中接受四个参数:累加值、当前值、当前项的索引和数组对象。这个函数返回的任何值都会作为累加值自动传给下一项。
  • 一个是作为归并基础的初始值(可选)如果设置了初始值,那么初始值就相当于初始的累加值

具体的用法,我们先看两个简单的例子(计算数组的和、数组去重):

1、计算数组的和

var arrts = [1, 2, 3, 4, 5, 6]

let arrts1 = arrts.reduce((pre, cur, index, array) => {
   return pre + cur
})
console.log(arrts1) // 21
console.log(arrts)  // [1, 2, 3, 4, 5, 6]

let arrts2 = arrts.reduce((pre, cur, index, array) => {
   return pre + cur
}, 100)
console.log(arrts2) // 121
// 如果传入了初始值,那么以初始值为基础,那么初始值就等于初始pre,加入到运算中。

reduce开始执行的时候是以100(初始值)为基础,第一次cur是attrs[0]的这个值 1,这个时候100 就是pre,然后进入迭代阶段。

2、数组去重

var arrts = [1, 2, 3, 4, 5, 6,7,2,4,5,1]
let arrts3 = arrts.reduce((pre, cur, index, array) => {
   !pre.includes(cur)&&pre.push(cur);
    return pre;
},[])
arrts3 // 1,2,3,4,5,6,7

数组去重这个例子中我们可以看到把传入的初始值,作为归并基础,这个思想很重要,也就是说,reduce开始执行的时候是以[ ](初始值)为基础,第一次cur是attrs[0]的这个值,这个时候[ ]就是pre,然后进入迭代阶段。

思路明确了,那我们来看一下上面Vue中解析深层的对象的方法是怎么封装的。

// expres是'items.item.a'这样的字符串
// vm是vue实例
getVal(expres,vm){
  return expres.split('.').reduce((data,currentVal)=>{
     return data[currentVal]
  },vm.$data);
}

具体分析如下:

  1. vm.data作为基础值,reduce第一次执行,得到的是vm.data.items这个对象;
  2. 第二次执行,得到的是vm.$data.items.item这个对象 ;
  3. 第三次执行,得到的是vm.$data.items.item.a这个值,所以就把按这个嵌套很深的值拿到了,并赋值给node节点的textcontent。 

关于reduce更详细的解释和示例说明请这篇文章:mp.weixin.qq.com/s/kxo6tOmaJ…

reduce还有很多其他的应用,后面如有遇到,会进行更新。

这是我之前发表在其他平台上的原创文章。

先天下之忧而忧,后天下之乐而乐!

我们下篇文章再见!