[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)
- 概述
- 框架目录
- 组件目录(components\)
- 生成目录(dist\)
- 测试目录(karma\)
- 示例目录(perf\)
- 主体目录(src)
- 其他文件
- 框架流程
- 前:章节说明
- 主:模板扫描(avalon.scan())
- 主:VM创建(avalon.define())
- 主:同步刷新(avalon.batch())
- 附:节点解析(avalon.lexer())
- 附:虚拟DOM(avalon.vdomAdaptor())
- 附:渲染函数(avalon.render())
- 附:VM生成(avalon.masterFactory())
- 附:节点diff(avalon.diff())
- 主:界面事件(test)
- 框架工具
- 另:全局函数
- 另:全局正则
- 另:事件接口
- 另:组件接口
- 另:DOMApi
- 框架驱动
- D : 指令实现
- D:兼容处理
- 使用范例
- 基础原理
- js模块
- js对象
- js函数
- js数组
- js字符串
- dom接口
- 框架心得
- 心:总体思路