交流群:462197261站长百科站长论坛热门标签收藏本站北冥有鱼 互联网前沿资源第一站 助力全行业互联网+
点击这里给我发消息
  • 当前位置:
  • vue 2.5.1 源码学习 之Vue.extend 和 data的合并策略

    1. 子类父类

     2.Vue.extend()      //创建vue的子类

      组件的语法器 Vue.extend(options)

      Profile().$mount('#app') // 挂在app上,并替换app

      新建 initExend

      ==》 Vue.extend

     3. strat.data

      ==> if(!vm){子组件中data的值是一个方法function ==> mergeDataorFn()} // 数据的合并

      ==> else {} //通过实例绑定的data 实际是一个函数 mergeDataorFn

      ==》 mergeDataorFn if(!vm) mergeDataFn ==> mergeData()

                else ==》mergedInstanceDataFn ==>mergeData()

        mergeData(to,from) //终极合并

      jquery.extend // 深copy和浅copy

    // 大体思路 (二)
    // 1. 子类父类 
    /* 
       2.Vue.extend()  //创建vue的子类
       组件的语法器 Vue.extend(options)
       Profile().$mount('#app') // 挂在app上,并替换app
       新建 initExend  
         ==》 Vue.extend
    */
    /* 3. strat.data  
      ==> if(!vm){子组件中data的值是一个方法function ==> mergeDataorFn()} // 数据的合并
      ==> else {} //通过实例绑定的data 实际是一个函数 mergeDataorFn 
      ==》 mergeDataorFn if(!vm) mergeDataFn ==> mergeData()  
         else ==》mergedInstanceDataFn ==>mergeData()
      mergeData(to,from) //终极合并
      jquery.extend // 深copy和浅copy
    */
    (function(global,factory){
      // 兼容 cmd 
      typeof exports === 'object' && module !== 'undefined' ? module.exports = factory():  
      // Amd
      typeof define === 'function' && define.amd ? define(factory) : global.Vue = factory();
    })(this,function(){
      var uip = 0;
      function warn(string){
        console.error('Vue Wran:' + string)
      }
      function resolveConstructorOptions(Con){
        var options = Con.options;
        // 判断是否为vm的实例 或者是子类
         return options
      }
      var hasOwnPropeerty = Object.prototype.hasOwnProperty
      function hasOwn(obj , key){
        return hasOwnPropeerty.call(obj,key)
      }
      function makeMap(str, expectsLoweraseC){
        if(expectsLoweraseC){
          str = str.toLowerCase()
        }
        var map = Object.create(null)
        var list = str.split(',')
        for(var i = 0 ; i < list.length; i++){
          map[list[i]] = true
        }
        return function(key){
          return map[key]
        }
      }
      var isbuiltInTag = makeMap('slot,component',true)
      var isHTMLTag = makeMap(
        'html,body,base,head,link,meta,style,title,' +
        'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +
        'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' +
        'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +
        's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +
        'embed,object,param,source,canvas,script,noscript,del,ins,' +
        'caption,col,colgroup,table,thead,tbody,td,th,tr,' +
        'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +
        'output,progress,select,textarea,' +
        'details,dialog,menu,menuitem,summary,' +
        'content,element,shadow,template,blockquote,iframe,tfoot'
      );
      var isSVG = makeMap(
        'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' +
        'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +
        'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',
        true
      );
      var isReservedTag = function(key){
        return isHTMLTag(key) || isSVG(key) 
      }
      function validataComponentName(key){
        //检测component 的自定义名称是否合格 
        // 只能是字母开头或下划线,必须是字母开头
        if(!(/^[a-zA-Z][\w-]*$/g.test(key))){
          warn('组件的名称必须是字母或中横线,必须由字母开头')
        }
        // 1. 不能为内置对象,2.不能是html ,和avg的内部标签
        if( isbuiltInTag(key) || isReservedTag(key)){
          warn('不能为html标签或者avg的内部标签')
        } 
      }
      function checkComonpents(child){
        for(var key in child.component){
          validataComponentName(key)
        }
      }
      // 配置对象
      var config = {
        // 自定义的策略
        optionMergeStrategies:{}
      }
      var strats = config.optionMergeStrategies
      strats.el = function(parent,child , key , vm){
         if(!vm){
           warn('选项'+key+'只能在vue实例用使用')
         }
         return defaultStrat(parent,child , key , vm)
      }
      function mergeData(to,form){
        // 终极合并
        if(!form){
          return to
        }
      }
      function mergeDataorFn(parentVal,childVal,vm){
        // 合并 parentVal childVal 都是函数
        if(!vm){
          if(!childVal){
            return parentVal
          }
          if(!parentVal){
            return childVal
          }
          return function mergeDataFn(parentVal,childVal,vm){//只是一个函数  什么样的情况下调用 加入响应式系统 
            // 合并子组件对应的data 和  父组件对应的data
            return mergeData( 
              typeof parentVal === 'function' ? parentVal.call(this,this) : parentVal,  // -----忘记写
              typeof childVal === 'function' ? childVal.call(this,this): childVal)   // -----忘记写
          }
        }else{ // vue实例
          return function mergeInstanceDataFn(parentVal,childVal,vm){//只是一个函数  什么样的情况下调用 加入响应式系统 
            var InstanceData = typeof childVal === 'function' ? childVal.call(vm,vm): childVal;  // -----忘记写
            var defaultData = typeof parentVal === 'function' ? parent.call(vm,vm): parentVal;  // -----忘记写
            if(InstanceData){
              return mergeData(parentVal,childVal)
            }else{        // -----忘记写
              defaultData
            }
          }
        }
      }
      strats.data = function(parent,child , key , vm){
        if(!vm){
         // console.log(typeof child === 'function')
          if(child && !(typeof child === 'function')){
            warn('data必须返回是一个function')
          }
          return mergeDataorFn(parent,child)
        }
        return mergeDataorFn(parent,child,vm)
      }
      function defaultStrat(parent,child , key , vm){
        return child === undefined ? parent :child ;
      }
      function mergeOptions(parent,child,vm){
        var options = {}
        // 检测是component 是否是合法的 
        checkComonpents(child)
        // console.log(parent, child)
        for(key in parent){
          magerField(key)
        }
        for(key in child){
          if(!hasOwn(parent ,key)){ // parent 中循环过地方不进行循环
            magerField(key) // ----忘记写
          }
        }
        // 默认合并策略
        function magerField(key){ 
          // 自定义策略 默认策略 
          // console.log(key)
          var result = strats[key] || defaultStrat    // ---忘记写
          options[key] = result(parent[key],child[key] , key , vm)
        }
        // console.log(options)
        return options
      }
      function initMinxin(options){
        Vue.prototype._init = function(options){
          var vm = this 
          // 记录生成的vue实例对象 
          vm._uip = uip++ //  //-------忘记写
           vm.$options =mergeOptions(resolveConstructorOptions(vm.constructor),options,vm)
        }
      }
      function Vue(options){
        // 安全机制
        if(!(this instanceof Vue)){   //-------忘记写
          warn('Vue是一个构造函数,必须是由new关键字调用') 
        }
        this._init(options)
      }
      initMinxin() // 初始化选项1: 规范 2: 合并策略。
      Vue.options = {
        components: {},
        directives:{},
        _bash: Vue
      }
      function initExend(Vue){
        Vue.extend = function(extendOptions){
          extendOptions = extendOptions || {}  // -----忘记写
          var Super = this 
          var Child = function VueComponent() {
            this._init(options)
          }
          Child.prototype = Object.create(Super.prototype)
          Child.prototype.constructor = Child  // 改变constructor 的指向
          Child.options = mergeOptions(Super.options,extendOptions)
          // 子类继承父类的静态方法。
          Child.extend = Vue.extend
          return Child
        }
      }
      initExend(Vue)
      return Vue
    })
    <body>
      <div id="app">
        <huml></huml>
      </div>
      <script src="vue.js"></script>
      <!-- <script src="vue2.5.1.js"></script> -->
      <script type="text/javascript">
        var componentA = {
          el: "#app"
        }
        var vm = new Vue({
          el:"#app",
          data: {
            message: "hello Vue",
            key: "wodow"
          },
          components:{
            huml: componentA
          }
        })
        // console.log(Vue)
        var Parent = Vue.extend({
          data: function() {}
        })
        var Child = Parent.extend({});
        console.log(vm.$options)
      </script>
    </body>

    总结

    以上所述是小编给大家介绍的vue 2.5.1 源码学习 之Vue.extend 和 data的合并策略,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对北冥有鱼网站的支持!
    如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

    您可能感兴趣的文章:

    • vue.extend实现alert模态框弹窗组件
    • 关于vue.extend和vue.component的区别浅析
    • 用Vue.extend构建消息提示组件的方法实例
    • Vue.extend构造器的详解
    • spring boot+vue 的前后端分离与合并方案实例详解
    • Vue.js中用webpack合并打包多个组件并实现按需加载
    • vue.js实现表格合并示例代码
    • require.js 加载 vue组件 r.js 合并压缩的实例

    广而告之:
    热门推荐:
    ASP.NET MVC5 实现分页查询的示例代码

    对于大量数据的查询和展示使用分页是一种不错的选择,这篇文章简要介绍下自己实现分页查询的思路。 分页需要三个变量:数据总量、每页显示的数据条数、当前页码。 //数据总量 int dataCount; //每页显示的数据条数 int pageDataCount; int pageNumber; 根据数据总量和每页显示···

    javascript delete 使用示例代码

    javascript delete example 复制代码 代码如下: var flower={}; flower.name="oop"; delete flower.name; //true alert(flower.name); //undefined   创建一个名为flower的对象   flower具有成员name,值"oop";   delete 操作 删除这个成员   删除成功,已不存在f···

    帝国CMS7.5版支持限制单个栏目单个会员发布信息数

    帝国CMS7.5版支持设置单个栏目里单个会员只能发布多少条信息,可依自己网站需求设置。比如:可设置该栏目下一个会员只能发布一条信息。其它说明:开启本功能必须将投稿权限设置为会员以上级别。

    JavaScript栈和队列相关操作与实现方法详解

    本文实例讲述了JavaScript栈和队列相关操作与实现方法。分享给大家供大家参考,具体如下: 一、栈的介绍 栈就是和列表类似的一种数据结构,数据只能在栈顶添加或者删除。栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,成为栈顶。栈具有后进先出的特点,所以任何不在···

    去哪儿收到私有化要约:每ADS 30.39美元 股价飙升

      去哪儿收到私有化要约   凤凰科技讯 北京时间6月24日消息,去哪儿网(Nasdaq:QUNR)昨日宣布,公司董事会已收到来自远洋管理有限公司(Ocean Management Limited,以下简称“买方”)的初步、非约束性私有化要约,后者计划通过现金方式,以每股美国存托股份(···

    深入理解JavaScript创建对象的多种方式以及优缺点

    写在前面 这篇文章讲解创建对象的各种方式,以及优缺点。 但是注意: 这篇文章更像是笔记,因为《JavaScript高级程序设计》写得真是太好了! 1. 工厂模式 function createPerson(name) { var o = new Object(); o.name = name; o.getName = function () { console.l···

    PHP实现驼峰样式字符串(首字母大写)转换成下划线样式字符串的方法示例

    本文实例讲述了PHP实现驼峰样式字符串(首字母大写)转换成下划线样式字符串的方法。分享给大家供大家参考,具体如下: 1、如何在php中把驼峰样式的字符串转换成下划线样式的字符串。例:输入是FooBar的话,输出则是foo_bar 以下是用正则的方式去完成,既然用到正则,方法肯定就···

    织梦去掉友情链接中“织梦链投放”“织梦链”的方法

    最近我们的官网在换空间,突然发现友情链接多了一个织梦自带的友情链接,起初我还以为同事加的呢,后来去模块里边看了没有,去模板里边看了也只是一个调用友情链接的标签。后来想难道是织梦程序加进去的吗,果然是这样 我就总结一下 希望对遇到同样问题的朋友有所帮助。 织···

    dedecms修改后台自定义表单列表为横向列表显示

    dede织梦系统自定义表单提交内容后,在后台显示的方式非常粗糙,今天我们将其改为横排列表显示。 1、找到后台自定义表单的模板,你的后台目录(默认dede)/templets/diy_list.htm HTML <table width="98%" border="0" cellpadding="1"···

    php将html转成wml的WAP标记语言实例

    本文实例讲述了php将html转成wml的WAP标记语言的方法。分享给大家供大家参考。具体实现方法如下: <?php //--------------------------------------- // Html 标记WAP语言 //---------------------------------------- function html2wml($content) { //保留图片 ···