• 【js】vue 2.5.1 源码学习(二) 策略合并


     一、  整体思路
        1 首先是代码的大体构造,先判断引入代码的环境,即对应amd 和cmd的处理
        2 vue_init 需要借助 initMinxin    ==>>>       // 初始化选项1: 规范 2: 合并策略。
        3 mergeOptions 选项合并 一个或者多个对象合并,并且生成一个新的对象
             ==>  resloveConstructorOptions 返回vm的optios 判断是否是vue对象有可能是vue子类。不一定指向options。
                    parent 自定义的options的选项     child 用户自定义的options
             ==>   checkComonpents // 规范的检测 validataComponentsName(key)
                    检测component的名称是否规范(不能使用内置标签slot component 关于html的标签名称 svg的子类的名称)
                  (规范:组件的名称必须是字母或中横线,必须由字母开头)
                    isbuiltInTag 检测是都是内置标签 isReservedTag是否是html的标签
                    ===>   makeMap 检测key是否在makeMap里面
            ==> mergeField 默认策略 // 以默认为优先。用户定义为覆盖
                  defaultStrat(parent,chhild)  合并策略   child === undefined ? parent : child;
           ==>  var config = {    // 配置对象
                      // 内置对象自定义策略
                     optionMergeStrategies:{}
                   }
                 var strats = config.optionMergeStrategies;
        4 Vue.options = {} vue的全局api
      1 //  大体思路  
      2 // 1 首先是代码的大体构造,先判断引入代码的环境,即对应amd 和cmd的处理
      3 // 2 vue_init  需要借助  initMinxin  // 初始化选项1: 规范 2: 合并策略。
      4 // 3 mergeOptions  选项合并 一个或者多个对象合并,并且生成一个新的对象 
      5     // resloveConstructorOptions  返回vm的optios  判断是否是vue对象又k
      6     // 有可能是vue子类。不一定指向options。     
      7     //  parent 自定义的options的选项  
      8     //  child  用户自定义的options  
      9     /*  checkComonpents  // 规范的检测 validataComponentsName(key)
     10         检测component的名称是否规范(不能使用内置标签slot component 关于html的标签名称  svg的子类的名称)自称)
     11        (规范:组件的名称必须是字母或中横线,必须由字母开头) 
     12         isbuiltInTag 检测是都是内置标签  isReservedTag是否是html的标签
     13         makeMap  检测key是否在makeMap里面 
     14     */   
     15     /*  mergeField 默认策略 // 以默认为优先。用户定义为覆盖  
     16         defaultStrat(parent,chhild)  
     17         child === undefined ? parent : child;
     18     */
     19    /*
     20      var config = {
     21          optionMergeStrategies:{}
     22      }
     23      var strats = config.optionMergeStrategies;
     24    */
     25 // 4 Vue.options = {} vue的全局api   
     26 
     27 (function(global,factory){
     28     // 兼容 cmd  
     29     typeof exports === 'object'  && module !== 'undefined' ? module.exports = factory():   
     30     // Amd
     31     typeof define  === 'function' && define.amd ?  define(factory) : global.Vue = factory();
     32 })(this,function(){
     33     var uip = 0;
     34     function warn(string){
     35         console.error('Vue Wran:' + string)
     36     }
     37 
     38     function resolveConstructorOptions(Con){
     39         var options = Con.options;
     40         // 判断是否为vm的实例 或者是子类
     41           return options
     42     }
     43     var hasOwnPropeerty = Object.prototype.hasOwnProperty
     44     function hasOwn(obj , key){
     45         return hasOwnPropeerty.call(obj,key)
     46     }
     47     function makeMap(str, expectsLoweraseC){
     48         if(expectsLoweraseC){
     49             str = str.toLowerCase()
     50         }
     51         var map = Object.create(null)
     52         var list = str.split(',')
     53         for(var i = 0 ; i < list.length; i++){
     54             map[list[i]] = true
     55         }
     56         return function(key){
     57             return map[key]
     58         
     59         }
     60     }
     61     var  isbuiltInTag = makeMap('slot,component',true)
     62     var isHTMLTag = makeMap(
     63         'html,body,base,head,link,meta,style,title,' +
     64         'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +
     65         'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' +
     66         'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +
     67         's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +
     68         'embed,object,param,source,canvas,script,noscript,del,ins,' +
     69         'caption,col,colgroup,table,thead,tbody,td,th,tr,' +
     70         'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +
     71         'output,progress,select,textarea,' +
     72         'details,dialog,menu,menuitem,summary,' +
     73         'content,element,shadow,template,blockquote,iframe,tfoot'
     74     );
     75     var isSVG = makeMap(
     76         'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' +
     77         'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +
     78         'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',
     79         true
     80     );
     81     var isReservedTag = function(key){
     82         return isHTMLTag(key) || isSVG(key) 
     83     }
     84     function validataComponentName(key){
     85         //检测component 的自定义名称是否合格 
     86         // 只能是字母开头或下划线,必须是字母开头
     87         if(!(/^[a-zA-Z][w-]*$/g.test(key))){
     88            warn('组件的名称必须是字母或中横线,必须由字母开头')
     89         }
     90         // 1. 不能为内置对象,2.不能是html ,和avg的内部标签
     91         if( isbuiltInTag(key) || isReservedTag(key)){
     92             warn('不能为html标签或者avg的内部标签')
     93         } 
     94     }
     95     function checkComonpents(child){
     96         for(var key in child.component){
     97             validataComponentName(key)
     98         }
     99     }
    100    // 配置对象
    101     var config = {
    102         // 自定义的策略
    103         optionMergeStrategies:{}
    104     }
    105     var strats = config.optionMergeStrategies
    106     strats.el = function(parent,child , key , vm){
    107        
    108           if(!vm){
    109               warn('选项'+key+'只能在vue实例用使用')
    110           }
    111           return defaultStrat(parent,child , key , vm)
    112     }
    113     function defaultStrat(parent,child , key , vm){
    114         return child === undefined ? parent :child ;
    115     }
    116     function mergeOptions(parent,child,vm){
    117         var options = {}
    118         // 检测是component 是否是合法的  
    119      
    120         checkComonpents(child)
    121         
    122         // console.log(parent, child)
    123         for(key in parent){
    124             magerField(key)
    125         }
    126         for(key in child){
    127             if(!hasOwn(parent ,key)){  // parent 中循环过地方不进行循环
    128                 magerField(key)  // ----忘记写
    129             }
    130               
    131         }
    132         // 默认合并策略
    133         function magerField(key){  
    134             // 自定义策略  默认策略 
    135             // console.log(key)
    136             var result = strats[key] || defaultStrat        // ---忘记写
    137             options[key] = result(parent[key],child[key] , key , vm)
    138         }
    139         console.log(options)
    140         return options
    141     }
    142     function initMinxin(options){
    143         Vue.prototype._init = function(options){
    144             var vm = this 
    145             // 记录生成的vue实例对象 
    146             vm._uip =  uip++ //   //-------忘记写
    147           
    148              mergeOptions(resolveConstructorOptions(vm.constructor),options,vm)
    149         }
    150     }
    151     function Vue(options){
    152         // 安全机制
    153         if(!(this instanceof Vue)){     //-------忘记写
    154             warn('Vue是一个构造函数,必须是由new关键字调用')  
    155         }
    156         this._init(options)
    157     }
    158     initMinxin()  //  初始化选项1: 规范 2: 合并策略。
    159     Vue.options = {
    160         components: {},
    161         directives:{},
    162         _bash: Vue
    163     }
    164     return Vue
    165 })
     1 <body>
     2     <div id="app">
     3         <huml></huml>
     4     </div>
     5     <script src="vue.js"></script>
     6     <!-- <script src="vue2.5.1.js"></script> -->
     7     <script type="text/javascript">
     8         var componentA = {
     9             el: "#app"
    10         }
    11         var vm = new Vue({
    12             el:"#app",
    13             data: {
    14                 message: "hello Vue",
    15                 key: "wodow"
    16             },
    17             components:{
    18                 huml: componentA
    19             }
    20             
    21         })
    22         console.log(vm.$options)
    23     </script>
    24 </body>

    以上仅为个人学习上的笔记,如有问题,欢迎评论。

  • 相关阅读:
    (转)老话题,权限设计及实现!
    (转)深入理解最强桌面地图控件GMAP.NET 百度地图
    (转)一步一步Asp.Net MVC系列_权限管理设计起始篇
    (转)常见存储过程分页PK赛——简单测试分析常见存储过程分页速度
    (转)正则表达之零宽断言(零宽度正预测先行断言)
    holer实现外网访问本地网站
    ural(Timus) 1039. Anniversary Party
    uva 10308 Roads in the North
    其他OJ 树型DP 技能树(未通过)
    ural(Timus) 1067. Disk Tree
  • 原文地址:https://www.cnblogs.com/yeujuan/p/10959708.html
Copyright © 2020-2023  润新知