restructure

This commit is contained in:
Evan You 2014-07-14 10:43:48 -04:00
parent 49ad4ca7d1
commit 706c67d1d0
24 changed files with 199 additions and 26 deletions

View File

@ -1,6 +1,6 @@
console.log('\nObserver\n') console.log('\nObserver\n')
var Observer = require('../src/observer/observer') var Observer = require('../src/observe/observer')
var Emitter = require('../src/emitter') var Emitter = require('../src/emitter')
var OldObserver = require('../../vue/src/observer') var OldObserver = require('../../vue/src/observer')
var sideEffect = true var sideEffect = true

View File

@ -1,4 +1,4 @@
var Observer = require('../src/observer/observer') var Observer = require('../src/observe/observer')
var _ = require('../src/util') var _ = require('../src/util')
function Vue (options) { function Vue (options) {
@ -87,9 +87,7 @@ function Vue (options) {
// also proxy newly added keys. // also proxy newly added keys.
var self = this var self = this
ob.on('added', function (key) { ob.on('added', function (key) {
if (!self.hasOwnProperty(key)) { _.proxy(self, scope, key)
_.proxy(self, scope, key)
}
}) })
} }

View File

View File

@ -6,10 +6,26 @@ exports.$set = function () {
} }
exports.$add = function () {
}
exports.$delete = function () {
}
exports.$watch = function () { exports.$watch = function () {
} }
exports.$unwatch = function () { exports.$unwatch = function () {
}
exports.$toJSON = function () {
}
exports.$log = function () {
} }

View File

61
src/api/global.js Normal file
View File

@ -0,0 +1,61 @@
var _ = require('../util')
var config = require('../config')
/**
* Configuration
*/
exports.config = function () {
}
/**
* Class inehritance
*/
exports.extend = function () {
}
/**
* Plugin system
*/
exports.use = function () {
}
/**
* Expose some internal utilities
*/
exports.require = function () {
}
/**
* Define asset registries and registration
* methods on a constructor.
*/
config.assetTypes.forEach(function (type) {
var registry = '_' + type + 's'
exports[registry] = {}
/**
* Asset registration method.
*
* @param {String} id
* @param {*} definition
*/
exports[type] = function (id, definition) {
this[registry][id] = definition
}
})
/**
* This is pretty useful so we expose it as a global method.
*/
exports.nextTick = _.nextTick

View File

View File

View File

@ -1 +1,11 @@
module.exports = {} module.exports = {
assetTypes: [
'directive',
'filter',
'partial',
'effect',
'component'
]
}

90
src/internal/init.js Normal file
View File

@ -0,0 +1,90 @@
exports._init = function (options) {
var data = options.data
var parent = options.parent
var scope = this._scope = parent
? Object.create(parent._scope)
: {}
// copy instantiation data into scope
for (var key in data) {
if (key in scope) {
// key exists on the scope prototype chain
// cannot use direct set here, because in the parent
// scope everything is already getter/setter and we
// need to overwrite them with Object.defineProperty.
_.define(scope, key, data[key], true)
} else {
scope[key] = data[key]
}
}
// create observer
// pass in noProto:true to avoid mutating the __proto__
var ob = this._observer = Observer.create(scope, { noProto: true })
var dob = Observer.create(data)
var locked = false
// sync scope and original data.
ob
.on('set', guard(function (key, val) {
data[key] = val
}))
.on('added', guard(function (key, val) {
data.$add(key, val)
}))
.on('deleted', guard(function (key) {
data.$delete(key)
}))
// also need to sync data object changes to scope...
// this would cause cycle updates, so we need to lock
// stuff when one side updates the other
dob
.on('set', guard(function (key, val) {
scope[key] = val
}))
.on('added', guard(function (key, val) {
scope.$add(key, val)
}))
.on('deleted', guard(function (key) {
scope.$delete(key)
}))
function guard (fn) {
return function (key, val) {
if (locked || key.indexOf(Observer.pathDelimiter) > -1) {
return
}
locked = true
fn(key, val)
locked = false
}
}
// relay change events from parent scope.
// this ensures the current Vue instance is aware of
// stuff going on up in the scope chain.
if (parent) {
var po = parent._observer
;['set', 'mutate', 'added', 'deleted'].forEach(function (event) {
po.on(event, function (key, a, b) {
if (!scope.hasOwnProperty(key)) {
ob.emit(event, key, a, b)
}
})
})
}
// proxy everything on self
for (var key in scope) {
_.proxy(this, scope, key)
}
// also proxy newly added keys.
var self = this
ob.on('added', function (key) {
_.proxy(self, scope, key)
})
}

View File

@ -85,7 +85,7 @@ Observer.create = function (value, options) {
return value.$observer return value.$observer
} if (_.isArray(value)) { } if (_.isArray(value)) {
return new Observer(value, ARRAY, options) return new Observer(value, ARRAY, options)
} else if (_.isObject(value)) { } else if (_.isObject(value) && !value._scope) { // avoid Vue instance
return new Observer(value, OBJECT, options) return new Observer(value, OBJECT, options)
} }
} }

View File

@ -36,6 +36,7 @@ exports.deepMixin = function (to, from) {
*/ */
exports.proxy = function (to, from, key) { exports.proxy = function (to, from, key) {
if (to.hasOwnProperty(key)) return
Object.defineProperty(to, key, { Object.defineProperty(to, key, {
enumerable: true, enumerable: true,
configurable: true, configurable: true,

View File

@ -1,5 +1,4 @@
var _ = require('./util') var _ = require('./util')
var Compiler = require('./compiler/compiler')
/** /**
* The exposed Vue constructor. * The exposed Vue constructor.
@ -10,33 +9,31 @@ var Compiler = require('./compiler/compiler')
*/ */
function Vue (options) { function Vue (options) {
this._compiler = new Compiler(this, options) this._init(options)
} }
/**
* Mixin instance methods
*/
var p = Vue.prototype var p = Vue.prototype
_.mixin(p, require('./instance/lifecycle'))
_.mixin(p, require('./instance/data'))
_.mixin(p, require('./instance/dom'))
_.mixin(p, require('./instance/events'))
/** /**
* Mixin asset registers * Mixin internal instance methods
*/ */
_.mixin(Vue, require('./api/asset-register')) _.mixin(p, require('./internal/init'))
_.mixin(p, require('./internal/compile'))
/** /**
* Static methods * Mixin API instance methods
*/ */
Vue.config = require('./api/config') _.mixin(p, require('./api/data'))
Vue.use = require('./api/use') _.mixin(p, require('./api/dom'))
Vue.require = require('./api/require') _.mixin(p, require('./api/events'))
Vue.extend = require('./api/extend') _.mixin(p, require('./api/lifecycle'))
Vue.nextTick = require('./util').nextTick
/**
* Mixin global API
*/
_.mixin(Vue, require('./api/global'))
module.exports = Vue module.exports = Vue