[TOC]
## 1 (web\compiler\) web编译目录
### 1-1 目录层次
~~~
compiler\directives
html.js ;html指令
text.js ;text指令
model.js ;model指令
index.js ;指令编译入口
~~~
### 1-2 html指令编译
>[info] import
~~~
;(导入)添加prop接口
import { addProp } from 'compiler/helpers'
~~~
>[info] module
~~~
;html解析编译
export default function html (el, dir) {
if (!dir.value) return
addProp(el, 'innerHTML', `__toString__(${dir.value})`)
}
~~~
>[info] export
~~~
;(导出)html解析接口
export default function html (el, dir) {}
~~~
### 1-3 text解析
>[info] import
~~~
import { addProp } from 'compiler/helpers'
~~~
>[info] module
~~~
;text指令解析编译
export default function text (el, dir) {
if (!dir.value) return
addProp(el, 'textContent', `__toString__(${dir.value})`)
}
~~~
>[info] export
~~~
;(导出)text指令解析编译
export default function text (el, dir) {}
~~~
### 1-4 model指令解析
>[info] import
~~~
;(导入)添加事件处理,添加prop,获取绑定属性
import { addHandler, addProp, getBindingAttr } from 'compiler/helpers'
~~~
>[info] module
~~~
;v-model 模型指令解析入口
export default function model (el, dir) {
;dir.value,dir.modifiers
const value = dir.value
const modifiers = dir.modifiers
;el类型select,checkbox,radio
if (el.tag === 'select') {
if (el.attrsMap.multiple != null) {
genMultiSelect(el, value)
} else {
genSelect(el, value)
}
} else {
;el类型checkbox,radio,input
switch (el.attrsMap.type) {
case 'checkbox':
genCheckboxModel(el, value)
break
case 'radio':
genRadioModel(el, value)
break
default:
return genDefaultModel(el, value, modifiers)
}
}
}
;创建Checkbox模型
function genCheckboxModel (el, value) {
const valueBinding = getBindingAttr(el, 'value')
addProp(el, 'checked',
`Array.isArray(${value})` +
`?(${value}).indexOf(${valueBinding})>-1` +
`:!!(${value})`
)
addHandler(el, 'change',
`var $$a=${value},` +
'$$el=$event.target,' +
'$$c=$$el.checked;' +
'if(Array.isArray($$a)){' +
`var $$v=${valueBinding},` +
'$$i=$$a.indexOf($$v);' +
'if($$c){$$i<0&&$$a.push($$v)}' +
'else{$$i>-1&&$$a.splice($$i,1)}' +
`}else{${value}=$$c}`
)
}
;创建Radio模型
function genRadioModel (el, value) {
const valueBinding = getBindingAttr(el, 'value')
addProp(el, 'checked', `(${value}==${valueBinding})`)
addHandler(el, 'change', `${value}=${valueBinding}`)
}
;创建默认模型input
function genDefaultModel (el, value, modifiers) {
const type = el.attrsMap.type
const { lazy, number, trim } = modifiers || {}
const event = lazy ? 'change' : 'input'
const needCompositionGuard = !lazy && type !== 'range'
const valueExpression = `$event.target.value${trim ? '.trim()' : ''}`
let code = number || type === 'number'
? `${value}=Number(${valueExpression})`
: `${value}=${valueExpression}`
if (needCompositionGuard) {
code = `if($event.target.composing)return;${code}`
}
addProp(el, 'value', `(${value})`)
addHandler(el, event, code)
if (needCompositionGuard) {
// need runtime directive code to help with composition events
return true
}
}
;select值代码
const getSelectedValueCode =
'Array.prototype.filter' +
'.call($event.target.options,function(o){return o.selected})' +
'.map(function(o){return "_value" in o ? o._value : o.value})'
;select子选项修改
function patchChildOptions (el, fn) {
for (let i = 0; i < el.children.length; i++) {
const c = el.children[i]
if (c.tag === 'option') {
addProp(c, 'selected', fn(getBindingAttr(c, 'value')))
}
}
}
;生成select
function genSelect (el, value) {
addHandler(el, 'change', `${value}=${getSelectedValueCode}[0]`)
patchChildOptions(el, valueBinding => `$(${value})===(${valueBinding})`)
}
;生成MultiSelect
function genMultiSelect (el, value) {
addHandler(el, 'change', `${value}=${getSelectedValueCode}`)
patchChildOptions(el, valueBinding => `$(${value}).indexOf(${valueBinding})>-1`)
}
~~~
>[info] export
~~~
;(导出)model解析编译
~~~
### 1-5 index.js web编译入口
>[info] import
~~~
;(导入)model指令解析,text指令解析,html指令解析
import model from './model'
import text from './text'
import html from './html'
~~~
>[info] export
~~~
;(导出)model,text,html指令解析
export default {
model,
text,
html
}
~~~
- 概述
- 框架结构
- 编译入口(\entries)
- web-compiler.js(web编译)
- web-runtime.js(web运行时)
- web-runtime-wih-compiler.js(web编译运行)
- web-server-renderer.js(web服务器渲染)
- 核心实现 (\core)
- index.js(核心入口)
- config.js(核心配置)
- core\util(核心工具)
- core\observer(双向绑定)
- core\vdom(虚拟DOM)
- core\global-api(核心api)
- core\instance(核心实例)
- 模板编译(\compiler)
- compiler\parser(模板解析)
- events.js(事件解析)
- helper.js(解析助手)
- directives\ref.js(ref指令)
- optimizer.js(解析优化)
- codegen.js(渲染生成)
- index.js(模板编译入口)
- web渲染(\platforms\web)
- compiler(web编译目录)
- runtime(web运行时目录)
- server(web服务器目录)
- util(web工具目录)
- 服务器渲染(\server)
- render-stream.js(流式渲染)
- render.js(服务器渲染函数)
- create-renderer.js(创建渲染接口)
- 框架流程
- Vue初始化
- Vue视图数据绑定
- Vue数据变化刷新
- Vue视图操作刷新
- 框架工具
- 基础工具(\shared)
- 模板编译助手
- 核心实例工具
- Web渲染工具
- 基础原理
- dom
- string
- array
- function
- object
- es6
- 模块(Module)
- 类(Class)
- 函数(箭头)
- 字符串(扩展)
- 代理接口(Proxy)
- 数据绑定基础
- 数据绑定实现
- mvvm简单实现
- mvvm简单使用
- vdom算法
- vdom实现
- vue源码分析资料