当前位置: 首页 > Web前端 > HTML

Vue源码分析-归一化选项

时间:2023-03-28 14:22:27 HTML

文章首发于个人博客小灰灰的空间归一化选项新建Vue创建Vue实例进行初始化时,首先进行的操作就是合并选项。合并选项时,针对不同场景有不同的合并策略.$options=mergeOptions(resolveConstructorOptions(vm.constructor),options||{},vm)}可以看到在创建Vue实例的时候,调用mergeOptions合并选项。在合并options的过程中,首先要做的是normalizeoptions/***Normalizepropsinjectdirectivesrespectively*/normalizeProps(child,vm)normalizeInject(child,vm)normalizeDirectives(child)下面我们看看上面的具体三大功能的实现。标准化props根据Vue使用文档中的说明,定义props有两种格式,即使用数组和对象。先看看这两种格式的用法//listpropspropsintheformofarray:['name','age']//Listpropsintheformofobjects,listpropsintheformofobjects.可以指定每个prop的数据类型props:{name:string,age:age,address:object}由于props有两种定义格式,使用起来势必不方便,所以需要对props进行标准化并将它们统一成一种对象格式。现在看normalizeProps的实现functionnormalizeProps(options:Object,vm:?Component){constprops=options.propsif(!props)returnconstres={}leti,val,nameif(Array.isArray(props)){//以数组格式列出propsi=props.lengthwhile(i--){val=props[i]if(typeofval==='string'){//数组中的每一项必须是一个字符串,将每一项存储在一个对象中,将每一项的key作为对象,对应的值为{type:null}name=camelize(val)res[name]={type:null}}elseif(process.env.NODE_ENV!=='production'){warn('propsmustbestringswhenusingarraysyntax.')}}}elseif(isPlainObject(props)){//如果list使用对象格式props,isPlainObject判断一个值是否是一个普通对象for(constkeyinprops){val=props[key]//将对象的key转换为驼峰格式name=camelize(key)//使用三元表达式计算res[name]=isPlainObject(val)?val:{type:val}}}elseif(process.env.NODE_ENV!=='production'){warn(`opt的无效值ion"props":expectedanArrayoranObject,`+`butgot${toRawType(props)}.`,vm)}options.props=res}经过以上代码的分析,我们最终可以得出结论,props有不同的写法数组格式props:['name','age']归一化的结果最终转换为如下props:{name:{type:null},age:{type:null}}forobjectformatprops:{name:string,age:number,address:{type:object}}最终转化为如下props:{name:{type:string},age:{type:number},address:{type:object}}规范化injectinject在Vue中不能单独使用,需要配合provide使用。我们来看一下Vue对provide/inject的解释,让一个祖先组件向它所有的后代组件注入一个依赖,不管这个组件层级有多深,也不管它的上下游关系是什么时候建立起来的。Alwayseffective注入选项应该是:一个字符串数组,或者一个对象,其中对象的key是本地绑定名,value是:用于搜索可用注入内容的key(字符串或Symbol),或对象,对象的:from属性是要在可用注入内容中搜索的键(字符串或符号)。默认属性是降级时使用的值现在让我们看看normalizeInject的实现。注入选项的写法有两种,数组的方式和对象的方式。和props的规则一样,最终会转化为对象格式//数组格式if(Array.isArray(inject)){for(leti=0;i(fn:F):F{constcache=Object.create(null)//创建一个emptyobjectcachedatareturn(functioncachedFn(str:string){consthit=cache[str]returnhit||(cache[str]=fn(str))//如果有缓存,就使用缓存,如果有是没有缓存,执行函数得到结果}:any)}constcamelizeRE=/-(\w)/g//将a-b形式转换为驼峰式aB//这里调用cached函数缓存转换结果导出constcamelize=cached((str:string):string=>{returnstr.replace(camelizeRE,(_,c)=>c?c.toUpperCase():'')})总结以上三种方法,propsinjectdirectives被分别归一化,这三个选项最终会被转换成对象的格式。