mirror of
https://gitee.com/vuejs/vue.git
synced 2024-12-04 13:07:40 +08:00
working on new observer
This commit is contained in:
parent
c225f8c3b8
commit
b5bfc59a70
@ -26,10 +26,13 @@ Hi! I’m really excited that you are interested in contributing to Vue.js. Befo
|
||||
## Code Style
|
||||
|
||||
- [No semicolons unless necessary](http://inimino.org/~inimino/blog/javascript_semicolons).
|
||||
- Follow JSDoc.
|
||||
- 2 spaces indentation.
|
||||
- multiple var declarations.
|
||||
- align equal signs where possible.
|
||||
- Return early in one line if possible.
|
||||
- align equal signs where appropriate.
|
||||
- Return early.
|
||||
- 1 space after `function`
|
||||
- 1 space between arguments, but not between parens.
|
||||
- When in doubt, read the source code.
|
||||
- Break long ternary conditionals like this:
|
||||
|
||||
|
@ -26,9 +26,9 @@
|
||||
"src/instance/dom.js",
|
||||
"src/instance/events.js",
|
||||
"src/instance/lifecycle.js",
|
||||
"src/observer/array.js",
|
||||
"src/observer/object.js",
|
||||
"src/observer/observer.js",
|
||||
"src/observer/watch-array.js",
|
||||
"src/observer/watch-object.js",
|
||||
"src/parsers/directive.js",
|
||||
"src/parsers/expression.js",
|
||||
"src/parsers/path.js",
|
||||
|
@ -1 +0,0 @@
|
||||
module.exports = 123
|
137
src/emitter.js
137
src/emitter.js
@ -0,0 +1,137 @@
|
||||
/**
|
||||
* Simple event emitter based on component/emitter.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Object} ctx - the context to call listners with.
|
||||
*/
|
||||
|
||||
function Emitter (ctx) {
|
||||
this._ctx = ctx || this
|
||||
}
|
||||
|
||||
var p = Emitter.prototype
|
||||
|
||||
/**
|
||||
* Listen on the given `event` with `fn`.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
*/
|
||||
|
||||
p.on = function (event, fn) {
|
||||
this._cbs = this._cbs || {}
|
||||
;(this._cbs[event] = this._cbs[event] || [])
|
||||
.push(fn)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an `event` listener that will be invoked a single
|
||||
* time then automatically removed.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
*/
|
||||
|
||||
p.once = function (event, fn) {
|
||||
var self = this
|
||||
this._cbs = this._cbs || {}
|
||||
|
||||
function on () {
|
||||
self.off(event, on)
|
||||
fn.apply(this, arguments)
|
||||
}
|
||||
|
||||
on.fn = fn
|
||||
this.on(event, on)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given callback for `event` or all
|
||||
* registered callbacks.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
*/
|
||||
|
||||
p.off = function (event, fn) {
|
||||
this._cbs = this._cbs || {}
|
||||
|
||||
// all
|
||||
if (!arguments.length) {
|
||||
this._cbs = {}
|
||||
return this
|
||||
}
|
||||
|
||||
// specific event
|
||||
var callbacks = this._cbs[event]
|
||||
if (!callbacks) return this
|
||||
|
||||
// remove all handlers
|
||||
if (arguments.length === 1) {
|
||||
delete this._cbs[event]
|
||||
return this
|
||||
}
|
||||
|
||||
// remove specific handler
|
||||
var cb
|
||||
for (var i = 0; i < callbacks.length; i++) {
|
||||
cb = callbacks[i]
|
||||
if (cb === fn || cb.fn === fn) {
|
||||
callbacks.splice(i, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* The internal, faster emit with fixed amount of arguments
|
||||
* using Function.call.
|
||||
*
|
||||
* @param {Object} event
|
||||
* @return {Emitter}
|
||||
*/
|
||||
|
||||
p.emit = function (event, a, b, c) {
|
||||
this._cbs = this._cbs || {}
|
||||
var callbacks = this._cbs[event]
|
||||
|
||||
if (callbacks) {
|
||||
callbacks = callbacks.slice(0)
|
||||
for (var i = 0, len = callbacks.length; i < len; i++) {
|
||||
callbacks[i].call(this._ctx, a, b, c)
|
||||
}
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* The external emit using Function.apply, used
|
||||
* by Vue instance event methods.
|
||||
*
|
||||
* @param {Object} event
|
||||
* @return {Emitter}
|
||||
*/
|
||||
|
||||
p.applyEmit = function (event) {
|
||||
this._cbs = this._cbs || {}
|
||||
var callbacks = this._cbs[event], args
|
||||
|
||||
if (callbacks) {
|
||||
callbacks = callbacks.slice(0)
|
||||
args = callbacks.slice.call(arguments, 1)
|
||||
for (var i = 0, len = callbacks.length; i < len; i++) {
|
||||
callbacks[i].apply(this._ctx, args)
|
||||
}
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
module.exports = Emitter
|
@ -0,0 +1,75 @@
|
||||
var _ = require('../util')
|
||||
var Emitter = require('../emitter')
|
||||
|
||||
/**
|
||||
* Observer class that are attached to each observed
|
||||
* object. They are essentially event emitters, but can
|
||||
* connect to each other and relay the events up the nested
|
||||
* object chain.
|
||||
*
|
||||
* @constructor
|
||||
* @extends Emitter
|
||||
* @private
|
||||
*/
|
||||
|
||||
function Observer () {
|
||||
Emitter.call(this)
|
||||
this.connections = Object.create(null)
|
||||
}
|
||||
|
||||
var p = Observer.prototype = Object.create(Emitter.prototype)
|
||||
|
||||
/**
|
||||
* Observe an object of unkown type.
|
||||
*
|
||||
* @param {*} obj
|
||||
* @return {Boolean} - returns true if successfully observed.
|
||||
*/
|
||||
|
||||
p.observe = function (obj) {
|
||||
if (obj && obj.$observer) {
|
||||
// already observed
|
||||
return
|
||||
}
|
||||
if (_.isArray(obj)) {
|
||||
this.observeArray(obj)
|
||||
return true
|
||||
}
|
||||
if (_.isObject(obj)) {
|
||||
this.observeObject(obj)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to another Observer instance,
|
||||
* capture its get/set/mutate events and relay the events
|
||||
* while prepending a key segment to the path.
|
||||
*
|
||||
* @param {Observer} target
|
||||
* @param {String} key
|
||||
*/
|
||||
|
||||
p.connect = function (target, key) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from a connected target Observer.
|
||||
*
|
||||
* @param {Observer} target
|
||||
* @param {String} key
|
||||
*/
|
||||
|
||||
p.disconnect = function (target, key) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Mixin Array and Object observe methods
|
||||
*/
|
||||
|
||||
_.mixin(p, require('./array'))
|
||||
_.mixin(p, require('./object'))
|
||||
|
||||
module.exports = Observer
|
30
src/util.js
30
src/util.js
@ -1,4 +1,9 @@
|
||||
// common utils
|
||||
/**
|
||||
* Mix properties into target object.
|
||||
*
|
||||
* @param {Object} target
|
||||
* @param {Object} mixin
|
||||
*/
|
||||
|
||||
exports.mixin = function (target, mixin) {
|
||||
for (var key in mixin) {
|
||||
@ -6,4 +11,27 @@ exports.mixin = function (target, mixin) {
|
||||
target[key] = mixin[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Object type check. Only returns true
|
||||
* for plain JavaScript objects.
|
||||
*
|
||||
* @param {*} obj
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
exports.isObject = function (obj) {
|
||||
return Object.prototype.toString.call(obj) === '[object Object]'
|
||||
}
|
||||
|
||||
/**
|
||||
* Array type check.
|
||||
*
|
||||
* @param {*} obj
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
exports.isArray = function (obj) {
|
||||
return Array.isArray(obj)
|
||||
}
|
@ -2,13 +2,18 @@ var _ = require('./util')
|
||||
var Compiler = require('./compiler/compiler')
|
||||
|
||||
/**
|
||||
* The exposed Vue constructor.
|
||||
* The exposed Vue constructor.
|
||||
*
|
||||
* @constructor
|
||||
* @public
|
||||
*/
|
||||
|
||||
function Vue (options) {
|
||||
this._compiler = new Compiler(this, options)
|
||||
}
|
||||
|
||||
// mixin instance methods
|
||||
|
||||
var p = Vue.prototype
|
||||
_.mixin(p, require('./instance/lifecycle'))
|
||||
_.mixin(p, require('./instance/data'))
|
||||
@ -16,9 +21,11 @@ _.mixin(p, require('./instance/dom'))
|
||||
_.mixin(p, require('./instance/events'))
|
||||
|
||||
// mixin asset registers
|
||||
|
||||
_.mixin(Vue, require('./api/asset-register'))
|
||||
|
||||
// static methods
|
||||
|
||||
Vue.config = require('./api/config')
|
||||
Vue.use = require('./api/use')
|
||||
Vue.require = require('./api/require')
|
||||
|
Loading…
Reference in New Issue
Block a user