Vue源码中好玩的函数有哪些

Vue源码中好玩的函数有哪些

本篇内容主要讲解“Vue源码中好玩的函数有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue源码中好玩的函数有哪些”吧!

1. 数据类型判断

Object.prototype.toString.call() 返回的数据格式为 [object Object] 类型,然后用 slice 截取第8位到倒一位,得到结果为 Object

Vue源码中好玩的函数有哪些

var_toString=Object.prototype.toString;functiontoRawType(value){return_toString.call(value).slice(8,-1)}

运行结果测试

toRawType({})//ObjecttoRawType([])//ArraytoRawType(true)//BooleantoRawType(undefined)//UndefinedtoRawType(null)//NulltoRawType(function(){})//Function

2. 利用闭包构造map缓存数据

vue 中判断我们写的组件名是不是 html 内置标签的时候,如果用数组类遍历那么将要循环很多次获取结果,如果把数组转为对象,把标签名设置为对象的 key,那么不用依次遍历查找,只需要查找一次就能获取结果,提高了查找效率。

functionmakeMap(str,expectsLowerCase){//构建闭包集合mapvarmap=Object.create(null);varlist=str.split(',');for(vari=0;i<list.length;i++){map[list[i]]=true;}returnexpectsLowerCase?function(val){returnmap[val.toLowerCase()];}:function(val){returnmap[val];}}

// 利用闭包,每次判断是否是内置标签只需调用isHTMLTag

varisHTMLTag=makeMap('html,body,base,head,link,meta,style,title')console.log('res',isHTMLTag('body'))//true

3. 二维数组扁平化

vue中_createElement格式化传入的children的时候用到了simpleNormalizeChildren函数,原来是为了拍平数组,使二维数组扁平化,类似lodash中的flatten方法。

//先看lodash中的flatten_.flatten([1,[2,[3,[4]],5]])//得到结果为[1,2,[3,[4]],5]//vue中functionsimpleNormalizeChildren(children){for(vari=0;i<children.length;i++){if(Array.isArray(children[i])){returnArray.prototype.concat.apply([],children)}}returnchildren}//es6中等价于functionsimpleNormalizeChildren(children){return[].concat(...children)}

4. 方法拦截

vue中利用Object.defineProperty收集依赖,从而触发更新视图,但是数组却无法监测到数据的变化,但是为什么数组在使用push pop等方法的时候可以触发页面更新呢,那是因为 vue 内部拦截了这些方法。

//重写push等方法,然后再把原型指回原方法varARRAY_METHOD=['push','pop','shift','unshift','reverse','sort','splice'];vararray_methods=Object.create(Array.prototype);ARRAY_METHOD.forEach(method=>{array_methods[method]=function(){//拦截方法console.log('调用的是拦截的'+method+'方法,进行依赖收集');returnArray.prototype[method].apply(this,arguments);}});

运行结果测试

vararr=[1,2,3]arr.__proto__=array_methods//改变arr的原型arr.unshift(6)//打印结果:调用的是拦截的unshift方法,进行依赖收集

5. 继承的实现

vue 中调用Vue.extend实例化组件,Vue.extend 就是 VueComponent构造函数,而 VueComponent 利用Object.create继承 Vue,所以在平常开发中 Vue 和 Vue.extend区别不是很大。这边主要学习用 es5 原生方法实现继承的,当然了,es6中 class 类直接用 extends 继承。

//继承方法functioninheritPrototype(Son,Father){varprototype=Object.create(Father.prototype)prototype.constructor=Son//把Father.prototype赋值给Son.prototypeSon.prototype=prototype}functionFather(name){this.name=namethis.arr=[1,2,3]}Father.prototype.getName=function(){console.log(this.name)}functionSon(name,age){Father.call(this,name)this.age=age}inheritPrototype(Son,Father)Son.prototype.getAge=function(){console.log(this.age)}

运行结果测试

varson1=newSon("AAA",23)son1.getName()//AAAson1.getAge()//23son1.arr.push(4)console.log(son1.arr)//1,2,3,4varson2=newSon("BBB",24)son2.getName()//BBBson2.getAge()//24console.log(son2.arr)//1,2,3

6. 执行一次

once 方法相对比较简单,直接利用闭包实现就好了

functiononce(fn){varcalled=false;returnfunction(){if(!called){called=true;fn.apply(this,arguments);}}}

7. 浅拷贝

简单的深拷贝我们可以用 JSON.stringify() 来实现,不过vue 源码中的looseEqual 浅拷贝写的也很有意思,先类型判断再递归调用,总体也不难,学一下思路。

functionlooseEqual(a,b){if(a===b){returntrue}varisObjectA=isObject(a);varisObjectB=isObject(b);if(isObjectA&&isObjectB){try{varisArrayA=Array.isArray(a);varisArrayB=Array.isArray(b);if(isArrayA&&isArrayB){returna.length===b.length&&a.every(function(e,i){returnlooseEqual(e,b[i])})}elseif(!isArrayA&&!isArrayB){varkeysA=Object.keys(a);varkeysB=Object.keys(b);returnkeysA.length===keysB.length&&keysA.every(function(key){returnlooseEqual(a[key],b[key])})}else{/*istanbulignorenext*/returnfalse}}catch(e){/*istanbulignorenext*/returnfalse}}elseif(!isObjectA&&!isObjectB){returnString(a)===String(b)}else{returnfalse}}functionisObject(obj){returnobj!==null&&typeofobj==='object'}

到此,相信大家对“Vue源码中好玩的函数有哪些”有了更深的了解,不妨来实际操作一番吧!这里是恰卡编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

发布于 2022-01-21 23:16:53
收藏
分享
海报
0 条评论
41
上一篇:vue.js怎么下载安装 下一篇:vue与bootstrap有什么不同
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码