hg-sid
Version:
a front-end simple framework with mvc
92 lines (86 loc) • 2.82 kB
text/typescript
import observe from '../observer/observer'
import Watcher from '../observer/watcher'
import Computed from '../observer/computed'
import { proxy } from '../util/util'
import DD from '.'
/**
* 代理配置项
* @param dd
*/
export default function initState(dd: DD) {
let opt = dd.$options
// 观察并代理 data 属性中数据
if (opt.data) initData(dd)
// 观察并代理 props 属性中数据
if (opt.props) initProp(dd)
// 处理 watch 属性内容
if (opt.watch) initWatch(dd)
// 处理 computed 属性内容
if (opt.computed) initComputed(dd)
// 代理 methods 属性中方法
if (opt.methods) initMethod(dd)
}
function initData(dd: DD) {
// let a = b = {} 的写法使得 a、b 指向同一个地址
let data = (dd._data = dd.$options.data ? dd.$options.data.call(dd) : {})
// 将 data 对象变成可监听结构
observe(data)
for (let key in dd._data) {
// 把 dd.data() 挂载在 dd,使得原来通过 dd.data().key 访问的数据,可以通过 dd.key 访问
proxy(dd, '_data', key)
}
}
function initProp(dd: DD) {
let props: any = (dd._props = {})
// 根据 props 中的 key 去 propsData 中取值
let propsData = dd.$options.propsData || {}
for (let key in dd.$options.props) {
let value = propsData[key]
// console.log(dd.$options.props[key].type)
if (!value) value = dd.$options.props[key].default
props[key] = value
}
observe(props)
for (let key in dd._props) {
// 把 dd.props 挂载在 dd,使得原来通过 dd.props.key 访问的数据,可以通过 dd.key 访问
proxy(dd, '_props', key)
// 监听父元素的属性,当父实例的属性变化时,更新子实例的该属性
// 这也是 prop 属性名需要和父实例 data 中属性名同名的原因
new Watcher(dd.$parent, key, (newValue: any) => {
dd[key] = newValue
})
}
}
function initWatch(dd: DD) {
for (let key in dd.$options.watch) {
let watch = new Watcher(
dd,
() => {
return key.split('.').reduce((obj, name) => obj[name], dd)
},
(newValue: any, oldValue: any) => {
dd.$options.watch[key].forEach((fnc: Function) =>
fnc(newValue, oldValue)
)
}
)
dd._watchers.push(watch)
}
}
function initComputed(dd: DD) {
let computed: any = (dd._computed = {})
for (let key in dd.$options.computed) {
computed[key] = new Computed(dd, key, dd.$options.computed[key]).value
}
observe(computed)
for (let key in dd._computed) {
// 把 dd.computed 挂载在 dd,使得原来通过 dd.computed.key 访问的数据,可以通过 dd.key 访问
proxy(dd, '_computed', key)
}
}
function initMethod(dd: DD) {
for (let key in dd.$options.methods) {
dd[key] = dd.$options.methods[key].bind(dd)
dd.$on(key, dd[key])
}
}