Vue源码中好玩的函数有哪些
Vue源码中好玩的函数有哪些
本篇内容主要讲解“Vue源码中好玩的函数有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue源码中好玩的函数有哪些”吧!
1. 数据类型判断
Object.prototype.toString.call()
返回的数据格式为 [object Object] 类型,然后用 slice
截取第8位到倒一位,得到结果为 Object
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源码中好玩的函数有哪些”有了更深的了解,不妨来实际操作一番吧!这里是恰卡编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
推荐阅读
-
vue表格组件教程学习(vue proxytable只能在开发环境跨域吗)
vueproxytable只能在开发环境跨域吗?跨域问题来源于JavaScript的同源策略,即只有协议主机名端口号(如...
-
Vue组件的自定义事件和全局事件总线怎么使用
-
vue中消息订阅与发布如何使用
vue中消息订阅与发布如何使用这篇文章主要介绍“vue中消息订阅与...
-
Vue显示图片的方式有哪些
-
vue引入静态jquery报错如何解决
vue引入静态jquery报错如何解决这篇文章主要介绍“vue引入...
-
vue-cropper怎么实现裁剪图片
-
怎么用Vue+NodeJS实现大文件上传
-
Vue如何实现简易跑马灯效果
-
Vue怎么指定不编译的文件夹和favicon.ico
Vue怎么指定不编译的文件夹和favicon.ico这篇文章主要介...
-
Vue中的插槽怎么使用