[TOC]
* * * * *
## 1 源代碼文件
~~~
src\component\index.js
~~~
## 2 接口組織
### 2-1 avalon.component(name,definition)
### 2-2 源代碼
~~~
avalon.component = function (name, definition) {
if (typeof name === 'string') {
//這里是定義組件的分支
avalon.components[name] = definition
for (var i = 0, obj; obj = componentQueue[i]; i++) {
if (name === obj.type) {
componentQueue.splice(i, 1)
i--
}
}
//這里沒有返回值
} else {
var node = name //node為頁面上節點對應的虛擬DOM
var vm = definition
var wid = node.props.wid
var options = node.props['ms-widget']
var tagName = node.type.indexOf('-') > 0 ? node.type : options.$type
//如果組件模板已經定
var placeholder = {
type: '#comment',
directive: 'widget',
props: {'ms-widget': wid},
nodeValue: 'ms-widget placeholder'
}
var docker = resolvedComponents[wid]
if (docker.render) {
//重新渲染自己
return reRender(docker)
} else if (!avalon.components[tagName]) {
componentQueue.push({
type: tagName
})
return placeholder
} else {
//頁面上的節點是用于傳參的
//通過插件的template字符串生成的節點,是來授參執行的
var type = node.type
if (!rcomponentTag.test(type)) {
avalon.warn(type + '不合適做組件的標簽')
}
if (type === 'xmp' || type === 'template' || node.children.length === 0) {
node.children = avalon.lexer(docker.template)
}
definition = avalon.components[tagName]
if (!avalon.modern && !definition.fixTag) {
avalon.document.createElement(tagName)
definition.fixTag = 1
}
var vtree = avalon.lexer(definition.template.trim())
if (vtree.length > 1) {
avalon.error('組件必須用一個元素包起來')
}
var widgetNode = vtree[0]
if (widgetNode.type !== tagName) {
avalon.warn('模板容器標簽最好為' + tagName)
}
for (var i in docker.props) {
if (!skip[i]) {
widgetNode.props[i] = docker.props[i]
}
}
if (!node.isVoidTag) {
//如果不是半閉合標簽,那么里面可能存在插槽元素,抽取出來與主模板合并
insertSlots(vtree, node)
}
delete options.$type
delete options.$define
var diff = options
delete options.$diff
var define = options.$define || avalon.directives.widget.define
var $id = options.$id || avalon.makeHashCode(tagName.replace(/-/g, '_'))
var vmodel = define(vm, definition.defaults, options)
vmodel.$id = $id
avalon.vmodels[$id] = vmodel
//生成組件的render
var render = avalon.render(vtree)
vmodel.$render = render
vmodel.$fire('onInit', vmodel)
avalon.mix(docker, {
render: render,
vmodel: vmodel,
diff: diff,
placeholder: placeholder
})
return reRender(docker)
}
}
}
~~~
## 3 其他操作
## 4 總結
- 概述
- 框架目錄
- 組件目錄(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接口
- 框架心得
- 心:總體思路