插件规范和设计模式

134 阅读2分钟

造轮子

// 民间规范 
amd:
a. 依赖前置(对于依赖的模块,提前执行,requireJS从2.0开始也改成了延迟执行) define(['./a','./b'],function(a,b){}
b. AMDAPI默认是一个当多个用, CMDAPI严格分区,推崇职责单一。
c. AMD里,require分全局require和局部requireCMD里没有全局require
cmd:依赖就近 
define(function(require,exports,module){
    var a = require('./a');
    a.doSomthing();
});
​
// 模块支持检测
if(typeof define === 'function' && define.amd) { // 如果有define 并且 define.amd 说明是amd环境
    define('jquery', [], function() { return jQuery;})
}
// 判断是不是node环境
if(typeof module === 'object' && module && typeof module.exports === 'object') {
    module.exports = jQuery;
}
​
// typeof exports === 'object' && typeof module !== 'undefined'  // node - commonjs的环境
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = global || self, global.vue = factory());
​
amd - define
es6 - import
node - commonjs
  • 工厂模式:让调用者不关心对象的构建,轻松拿到自己想要的东西

    应用场景:当你需要大量的产出对象的时候

    jquery为什么要用 工厂模式:操作大量的dom;

    (function(){
    ​
    })(window) // 传入window是为了减少作用域链查找
    // 使用变量 - 作用域链查找
  • 建造者模式 - 精细化的组合一个类

    应用场景:构建一个复杂庞大的类的时候

    分析功能,构建模块,独立开发模块 mode1 mode2

    function Vue(options) {
        if(!(this instanceof Vue)){
            varn('Vue is ...')
        }
        this._init();   
    }   
        
    
  • 享元模式 - 提取不同点享元

    目的:减少代码块和对象的数量

  • 函数式编程(前端特有?) -underscore lodash:用一个个方法来实现我们的功能

    Vue3 改成了函数式:为什么

    1. 便于组合,有利于扩展。组合大于继承
    2. 有利用控制代码体积 tree-shaking(把你没有用的方法删掉)
  • 前端尖端技术:serverless,同构,中台化,node工程体系搭建

  • 良好的编程思维,熟悉设计模式,熟悉各种js的技巧,熟悉js的原理,熟悉前端角度的设计模式
  • 组件库,脚手架,工具库,工程化系统
  • 在组件内部判断参数类型,提高代码健壮性和bug定位速度

    function add(a, b) {
        if(typeof a === 'number') {
            return a + b;
        } else {
            throw new Error('a is not a number')
        }
    }
    
  • 在容易出问题的地方

    try{
        // 易错代码
    } catch(e) {
        throw new Error(e)
    }
    
  • // 通过defineProperty放进去,保证了$router不能被更改

    // 通过defineProperty放进去,保证了$router不能被更改Object.defineProperty(vue.prototype, '$router', { get:function() { return _router; } })
    

vue3.0: 变化(快,小,省)

    1. api层次选择更快的api
    2. 算法层面 - 尽量减少操作步骤
  • 小:减少资源文件体积

    1. 通过工具,webpack压缩代码图片tree-shaking
    2. 减少重复
  1. api层面:响应式原理从 Object.defineProperty -> proxy
  2. Vue2.0 diff 新老DOM(从全部比对,改成只对比绑定指令的DOM)(block-tree)
  3. 函数式编程
    1. 缓存,是所有优化方案里最常用,最有效的,可以节省http请求,可以从内存里最快读取数据

缓存架构需要唯一性 - 单例模式

存缓存的地方不能直接被操作 - 闭包

promise 异步

缓存的副作用:更新的问题

if(!window.mycache) {
    window.mycache = (function(){
        var cache = {};
        return {
            get: function(api) {
                return new Promise(()=>{
                    if(cache[api]) {
                        resolve(cache[api])
                    } else {
                        this.set(api).then(res => {
                            cache[api] = res;
                            resolve(res);
                        })
                    }
                })
            },
            set: function(api) {
                return axios.get(api)
            }
        }
    })();
}
​
​
​
if(!window.mycache) {
    window.mycache = (function(){
        var cache = {};
        var cacheArr = [];
        return {
            get: function(api) {
                return new Promise(()=>{
                    if(cache[api]) {
                        resolve(cache[api])
                    } else {
                        this.set(api).then(res => {
                            this.set(api).then(res => {
                                if(cacheArr.length > 10) {
                                    var _api = cacheArr.shift();
                                    this.remove(_api)
                                }
                            })
                            cache[api] = res;
                            cacheArr.push(api);
                            resolve(res);
                        })
                    }
                })
            },
            set: function(api) {
                return axios.get(api)
            }
        }
    })();
}
​
​
​
mycache.get(api).then();

Vue插件的开发

  • Vue.use()

    1. 直接传方法, 就直接执行。 如果方法下有install方法,就会执行install。
Vue.use(); 如果有install就执行install, 如果没用install,就执行方法本身
​
a.install = function() {
    Vue.mixin({
        // 生命周期的混合
        created: function() {
            console.log()
        }
    })
}
​
  • Vue.mixin({})

    通过mixin混合进来的方法或数据, 所有组件都可以使用这个方法

    Vue.mixin({
    	created: function() {
    		console.log(1)
    	},
    	method: {
    		a: function(){}
    	},
    	data: {
    	
    	}
    })
    
  • 问题:因为vuex的内容太多,引起了打包结果过大

  • 解决方案:按照组件加载vuex

    function a() {
    
    }
    a.install = function() {
    	Vue.mixin({
    		beforeCreate: function() {
    			if(this.$options.isVuex) {
    				var name = this.$options.name
                    import('../store/module/' + name).then((res) => {
                        this.$store.registerModule(this.$options.name, res.default)
                    })
    			}
    		}
    	})
    }
    

    前端的单元测试是个什么东东!!!

  • Vue.extend({}) 让我们在任何地方都可以拿到一个组件的实例

    import pop from './components/pop.vue' // 拿到的是pop的选项配置
    
    var popcs = Vue.extend(pop); /
    // 给vue.extend方法一个对象,会返回给你根据这个对象所生成的vue构造函数
    var popob = new popcs().$mount();
    

\