驱动点
一、传统H5(高频更新)项目中变量监控、跨浏览器监控是很有必要的
二、保存的数据需要在仓库中处理之后再返回
三、变量实时保存到localStorage或sessionStorage
仓库核心代码如下
//仓库类,设置数据、变量监控、localStorage监控,自定义钩子函数
var myStore = {
_options: {
error: null,//错误回调
watch: {},//监听变量的变化(数组、数字、字符串)
},
//定义仓库核心
_store: function(options){
var data = {
_options: {
error: null,//错误回调
watch: {},//监听的对象
methods: {},//方法
initData: {},//初始化的值
static: {},//静态数据区
watchStatic: {},//监听静态变量(不要与静态区键值相同,否则出现数据丢失问题)
},
_d: {},//保存运行的数据
_wd: {},//监控数据的值
_sd: {},//静态数据区(跨页面访问)
//设置值
_set: function(key, value){
var self = data;
if(typeof self._sd[key] !== 'undefined'){//静态数据区
self._sd[key] = value;
localStorage.setItem(key, JSON.stringify(value));
}else{
self._d[key] = value;
}
},
//设置多个值
_sets: function(obj){
var self = data;
if(typeof obj === "object" && obj !== null){
for(var i in obj) {
self._set(i, obj[i]);
}
}else{
console.error('yexStore的sets使用方法不正确,需要一个对象做为参数');
}
return self;
},
//获取值
_get: function(key){
var self = data;
if(typeof self._sd[key] !== 'undefined'){//静态数据区
var returnData = localStorage.getItem(key);
try {
returnData = JSON.parse(returnData);
} catch (error) {}
return returnData;
}else if(typeof self._wd[key] !== 'undefined'){
return self._wd[key];
}else{
return self._d[key];
}
},
//合并对象,并监听对象
_mergeOptions: function(options){
var self = this;
//设置初始化数据
if(typeof options.initData === 'object' && options.initData !== null ){
Object.assign(self._d, options.initData);
delete options.initData;
}
//静态数据区
if(typeof options.static === 'object' && options.static !== null){
Object.assign(self._sd, options.static);
//读取静态数据区在sessionStore的值
var item = null;//子项
for(var i in self._sd){
item = self._sd[i];
if(typeof item === 'undefined' || item === null){
item = localStorage.getItem(i);
try {
self._sd[i] = JSON.parse(item);
} catch (e) {}
}else{
localStorage.setItem(i, item);
}
}
delete options.static;
}
//处理方法合并
if(typeof options.methods === 'object' && options.methods !== null){
var item = null;//临时数据
for(var i in options.methods){
var item = options.methods[i];
if(typeof item === 'function'){
self[i] = item;
}
}
delete options.methods;
}
//合并其他选项
Object.assign(self._options, options);
//处理监听区数据
var watch = self._options.watch;
if(typeof watch === 'object' && watch !== null){
for(var i in watch){
self._watchData(i, watch[i]);
}
}
//启动静态监控(监听storage事件)
var watchStatic = self._options.watchStatic;
for(var i in watchStatic){
localStorage.removeItem(i);//移除了key才能再次触发消息
}
window.addEventListener('storage', function(e){
var key = e.key;
var watchStatic = self._options.watchStatic;
if(watchStatic && typeof watchStatic[key] === 'function'){
var value = e.newValue;
if(value !== null){
try{value = JSON.parse(value);}catch(e){};
watchStatic[key](value);
}
localStorage.removeItem(key);//移除了key才能再次触发消息
}
});
},
_watchData: function(attribute, setFunc){
if(typeof attribute !== 'string' || attribute.replace(/\s*/g,'') === ''){
return;
}
var self = this;
var obj = self._d;
try{
self._wd[attribute] = self._d[attribute];//初始化
Object.defineProperty(obj, attribute, {
set: function(newValue) {
self._wd[attribute] = newValue;
setFunc(newValue);//设置值监听
}
});
}catch(e){
console.log('监听的值重复');
}
return self;
},
_initData: function(){
},
init: function(options){
var self = this;
self._mergeOptions(options);
self._initData();
return self;
},
};//所有的数据
this.dataObj = data.init(Object.assign({}, options));
//需要对扩展方法进行外层暴露
if(typeof options.methods === 'object' && options.methods !== null){
var item = null;//临时数据
for(var i in options.methods){
var item = options.methods[i];
if(typeof item === 'function'){
this[i] = this.dataObj[i];
}
}
}
this.set = this.dataObj._set;
this.sets = this.dataObj._sets;
this.get = this.dataObj._get;
},
_storeObj: null,//实例化的仓库对象
//设置仓库的数据
set: function(key, value){
var self = yexStore;
self._storeObj.set(key, value);
return self;
},
sets: function(obj){
var self = this;
self._storeObj.sets(obj);
return self;
},
//获取仓库的数据
get: function(key){
var self = this;
return self._storeObj.get(key);
},
//运行方法
runFunc: function (name, options) {
var self = yexStore;
var func = self._storeObj[name];
if(typeof func !== 'undefined'){
func(options);
}else{
var eFunc = self._options.error;
if(typeof eFunc === "function"){
eFunc('“' + name + '”方法不存在!!!');
}
}
},
//初始化数据
_initOptions: function(options){
var self = this;
//暴露库里面的方法(作为调用句柄)
if(typeof options.methods === 'object' && options.methods !== null){
var item = null;//临时数据
for(var i in options.methods){
var item = options.methods[i];
if(typeof item === 'function'){
self[i] = self._storeObj[i];
}
}
}
},
//初始化仓库
init: function(options){
var self = this;
self._storeObj = new self._store(Object.assign({},options));
self._initOptions(options);//初始化配置项,需要动态对函数的名字进行定义,一定需要放在最后
return self;
}
};
使用方式
//初始化仓库
var store = myStore.init({
initData: {
sysRunStartTime: 0,//系统开始运行时间
classId: 0,//使用的班级id
lessonId: 1,//使用的课程id
pageIndex: null//页面记录
},
watch: {
//页面索引(0首页、1点评页、2作业布置页、3授课、4点名页)
pageIndex: function (index) {
var self = store;
console.log('监听到页面变化', pageIndex);
}
},
watchStatic: {
pageChange: function(value){
console.log('监听到localStroage变化', value);
}
},
static: {
token: null,
host: config.host,//配置请求的地址
//静态区监控对象-不是为了存储数据而是为了监控数据(指明存储类型为静态)
pageChange: null
},
methods: {
//添加页面变化监控
addPageListen: function (callback) {
var self = this;
var name = 'pageListenList';
if (typeof self[name] !== 'object' || !Array.isArray(self[name])) {
self[name] = [];
}
self[name].push(callback);
return self;
}
}
});
触发点
//触发localStrage监控(特定版本有效-比如: chrome 69)
store.set('pageChange', 1);
//触发变量监听(通用)
store.set('pageIndex', 1);