ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] * * * * * ## 1 源代码文件 ### 1-1 VM创建入口 ~~~ src\vmodel\parts\share.js ~~~ ### 1-2 VM创建实现 ~~~ src\vmodel\modern.js ~~~ ## 2 流程分析 ### 2-1 VM创建接口define >[success] 接口实现文件 src\vmodel\parts\share.js ~~~ function define(definition) { var $id = definition.$id if (!$id && avalon.config.debug) { avalon.warn('vm.$id must be specified') } var vm = $$midway.masterFactory(definition, {}, { pathname: '', id: $id, master: true }) if (avalon.vmodels[$id]) { throw Error('error:[', $id, '] had defined!') } return avalon.vmodels[$id] = vm } ~~~ > definition:vm对象结构参数 ~~~ var vm = avalon.define({ $id: 'test', a: 11, b: { c: 22 } }) ~~~ > definition为 ~~~ { $id: 'test', a: 11, b: { c: 22 } } ~~~ * * * * * > define() 中 > 首先获取$id为参数definition的$id,上面的test. > if()判断$id是否获取成功, > 然后调用$$midway.masterFactory()创建vm > 这里的masterFactory()是vm创建的实现核心 > 然后检测avalon.vmodels是否包含$id索引 > 然后将创建的vm以$id为索引保存到avalon.vmodels全局数组中 ~~~ avalon.define = define ~~~ > 导出define到全局接口avalon.define() ### 2-2 VM创建实现masterFactory >[success] 创建实现文件 src\vmodel\parts\share.js ~~~ function masterFactory(definition, heirloom, options) { var $skipArray = {} if (definition.$skipArray) { $skipArray = avalon.oneObject(definition.$skipArray) delete definition.$skipArray } var keys = {} options = options || {} heirloom = heirloom || {} var accessors = {} var hashcode = makeHashCode("$") var pathname = options.pathname || "" options.id = options.id || hashcode options.hashcode = hashcode var key, sid, spath for (key in definition) { if ($$skipArray[key]) continue var val = keys[key] = definition[key] if (!isSkip(key, val, $skipArray)) { sid = options.id + "." + key spath = pathname ? pathname + "." + key : key accessors[key] = makeAccessor(sid, spath, heirloom) } } accessors.$model = modelAccessor var $vmodel = new Observer() Object.defineProperties($vmodel, accessors) for (key in keys) { $vmodel[key] = keys[key] if (key in $skipArray) { delete keys[key] } else { keys[key] = true } } makeObserver($vmodel, heirloom, keys, accessors, options) return $vmodel } ~~~ > definition:avalon.define()传递参数 > heirloom:avalon.mediatorFactory(vm1,vm2)的合并vm > options: * * * * * >[info] definition.$skiparray处理 * * * * * > 首先获取definition.$skipArray并保存 > 这里的$skipArray信息不需要进行监听, > 调用avalon.oneObject()创建一个简单对象, > 见框架工具的 另:全局函数 * * * * * >[info] 变量声明 * * * * * > 然后声明一系列创建过程中使用到变量 > keys 需要监听的键信息 > options 额外参数 > heirloom 继承的vm > accessors > hashcode 默认hanscode > pathname > options.id > options.hashcode > key definition的键key > sid 节点内部键? $.key > spath 节点内部路径? pathname.key.key * * * * * >[info] 遍历definition键创建访问器 * * * * * > 接着遍历definition的键 如果是key存在$$skipArray中跳到下个key处理 保存非$$skipArray的key与值到val和keys[key] 这里的$$skipArray在下面介绍 调用isSkip()检查key,val与$skipArray的关系 如果不是$skipArray的key。 则创建sid,spath, 然后以sid,spath,heirloom调用makeAccessor()创建访问器 isSkip()下面介绍 makeAccessor()是创建访问器的核心函数,下面分析 * * * * * >[info] 创建$vmodel,并挂载访问器 * * * * * > 将访问的$model设置为默认访问modelAccessor > 创建$vmodel为空对象 > 调用Object.defineProperties()挂载访问, > 这里的definProperties()是mvvm框架的实现核心。 > 具体使用基础原理的 Object对象 * * * * * >[info] $vmodel监控属性生成 * * * * * > 将全部keys的key与值保存到$vmodel[key] > 然后删除keys中在$skipArray的key。 > 这里的$skipArray不需要监控。 > $skipArray与$$skipArray不同 * * * * * >[info] $vmodel高级属性生成 * * * * * > 调用makeObserver()创建高级属性 > 包括$model,$id,$hashcode,$element,$render等 > makeObserver()在内部调用hideProperty() > 这里的hideProperty()也就是调用Object.defineProperty() > 下面详细分析 * * * * * >[info] $vmodel返回 * * * * * > 返回$vmodel。 由avalon.define()可知,最后这个$vmodel 以$id为索引保存到全局avalon.vmodel数组中 ~~~ $$midway.masterFactory = masterFactory ~~~ > 导出masterFactory到$$midway 最后在上面的avalon.define()函数中调用 ## 3 其他代码 VM创建相关其他代码见 附:VM生成 ## 4 总结 ### 4-1意义 avalon.define()创建vm对象。 正如概述中对mvvm的解析。 这个vm是连接视图html与后端数据api的关键 也就是mvvm中的vm,m对应后端api,v对应视图html ### 4-2 思路 调用 Object.defineProperty() Object.defineProperties() 创建vm对象 相关原理见基础原理 Object对象 ### 4-3参考链接 [avalon2学习教程02vm](https://segmentfault.com/a/1190000004882922)