单例模式(SingletonPattern),又称单例模式,确保一个类只有一个实例,并提供一个全局访问点来访问它。也就是说,使用同一个类创建的每个新对象都是完全相同的。单例模式是设计模式中比较容易理解和使用的一种模式。同时,由于其应用场景广泛,也是面试题中的常客。哪些场景需要单例模式?有些游戏,比如:植物大战僵尸,我们肯定希望每次玩的时候都从之前的存档继续下去。如果我们第二天从第一关开始玩,那我就把电脑扔出窗外。有了存档,每次你玩的时候,你都会在同一个存档上继续,它使用单例。网站登录框、购物车等状态管理单例模式的实现。一般来说,我们在创建一个类(本质上是一个构造函数)后,会通过new关键字调用构造函数生成一个实例对象。像这样:classMan{callWife(){console.log('我给你老婆小丽打了电话');}}constman1=newMan();constman2=newMan();console.log(man1===man2);//上面false,我们先新建了一个man1,再新建了man2,显然man1和man2是独立的对象,各自占用一块内存空间。单例模式的作用是:无论我们创建对象多少次,只返回我们第一次创建的唯一实例。为此,构造函数需要具备判断是否已经创建实例的能力。我们把这个逻辑写成一个静态方法:}staticgetInstance(){if(!Man.instance){人。实例=新人();}返回Man.instance;}}constman1=Man.getInstance();constman2=Man.getInstance();console.log(man1===man2);//true除了this方法之外,getInstance方法的逻辑也可以用闭包来实现:Man.getInstance=(function(){letinstance=null;returnfunction(){if(!instance){instance=newMan();}returninstance;}})();现在在getInstance方法的判断下,无论调用多少次,Man都只会返回给我们同一个实例,而man1和man2现在都指向了这个唯一的实例。Vuex中的单例模式Vuex使用单个状态树,它包含一个对象的所有应用程序级状态。在这一点上,它作为“单一真相来源(SSOT)”存在。这也意味着每个应用程序将只包含一个商店实例。单个状态树允许我们直接定位任何特定的状态片段,并在调试期间轻松获取整个当前应用程序状态的快照。——Vuex官方文档在Vue中,组件间通信最常用的是props(仅用于父子组件间的通信),更复杂的(比如兄弟组件间的通信)可以通过父组件间接处理。但是当组件很多,关系很复杂的时候,上面提到的通信方式就变得难以维护了。这时候,最好的办法就是将共享数据抽取出来放在全局,让组件按照一定的规则访问数据,从而保证状态的变化以可预测的方式发生。于是就有了Vuex,唯一用来存储共享数据的数据源,就是Store。关于Vuex的详细介绍,可以参考Vuex的官方文档。Vuex如何保证Store的唯一性?我们先来看看如何在项目中引入Vuex//安装vuex插件Vue.use(Vuex)//将store注入到Vue实例中newVue({el:'#app',store})安装通过调用Vue.use()方法的Vuex插件。Vuex插件是一个对象,它在内部实现了一个install方法,该方法将在安装插件时调用,以将Store注入到Vue实例中。在install方法中,实现的逻辑和getInstance方法很相似:letVue//Vue的作用和上面的instance一样...exportfunctioninstall(_Vue){//判断传入的Vue实例对象是否已经安装(是否有唯一状态)if(Vue&&_Vue===Vue){if(process.env.NODE_ENV!=='production'){console.error('[vuex]已经安装。use(Vuex)shouldbecalledonceonce.')}return}//如果没有,为这个Vue实例安装一个唯一的VuexVue=_Vue//将Vuex初始化逻辑写入Vue的钩子函数applyMixin(Vue)}上面是Vuex源码中单例模式的实现方法,套路可以说和getInstance一模一样。这样可以保证一个Vue实例(也就是一个Vue应用)只会安装一次Vuex插件,所以每个Vue实例只会有一个全局Store。
