github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/public/libs/vue-1.0.24/src/instance/internal/events.js (about) 1 import { isSimplePath } from '../../parsers/expression' 2 import { 3 inDoc, 4 isArray, 5 warn 6 } from '../../util/index' 7 8 const eventRE = /^v-on:|^@/ 9 10 export default function (Vue) { 11 /** 12 * Setup the instance's option events & watchers. 13 * If the value is a string, we pull it from the 14 * instance's methods by name. 15 */ 16 17 Vue.prototype._initEvents = function () { 18 var options = this.$options 19 if (options._asComponent) { 20 registerComponentEvents(this, options.el) 21 } 22 registerCallbacks(this, '$on', options.events) 23 registerCallbacks(this, '$watch', options.watch) 24 } 25 26 /** 27 * Register v-on events on a child component 28 * 29 * @param {Vue} vm 30 * @param {Element} el 31 */ 32 33 function registerComponentEvents (vm, el) { 34 var attrs = el.attributes 35 var name, value, handler 36 for (var i = 0, l = attrs.length; i < l; i++) { 37 name = attrs[i].name 38 if (eventRE.test(name)) { 39 name = name.replace(eventRE, '') 40 // force the expression into a statement so that 41 // it always dynamically resolves the method to call (#2670) 42 // kinda ugly hack, but does the job. 43 value = attrs[i].value 44 if (isSimplePath(value)) { 45 value += '.apply(this, $arguments)' 46 } 47 handler = (vm._scope || vm._context).$eval(value, true) 48 handler._fromParent = true 49 vm.$on(name.replace(eventRE), handler) 50 } 51 } 52 } 53 54 /** 55 * Register callbacks for option events and watchers. 56 * 57 * @param {Vue} vm 58 * @param {String} action 59 * @param {Object} hash 60 */ 61 62 function registerCallbacks (vm, action, hash) { 63 if (!hash) return 64 var handlers, key, i, j 65 for (key in hash) { 66 handlers = hash[key] 67 if (isArray(handlers)) { 68 for (i = 0, j = handlers.length; i < j; i++) { 69 register(vm, action, key, handlers[i]) 70 } 71 } else { 72 register(vm, action, key, handlers) 73 } 74 } 75 } 76 77 /** 78 * Helper to register an event/watch callback. 79 * 80 * @param {Vue} vm 81 * @param {String} action 82 * @param {String} key 83 * @param {Function|String|Object} handler 84 * @param {Object} [options] 85 */ 86 87 function register (vm, action, key, handler, options) { 88 var type = typeof handler 89 if (type === 'function') { 90 vm[action](key, handler, options) 91 } else if (type === 'string') { 92 var methods = vm.$options.methods 93 var method = methods && methods[handler] 94 if (method) { 95 vm[action](key, method, options) 96 } else { 97 process.env.NODE_ENV !== 'production' && warn( 98 'Unknown method: "' + handler + '" when ' + 99 'registering callback for ' + action + 100 ': "' + key + '".', 101 vm 102 ) 103 } 104 } else if (handler && type === 'object') { 105 register(vm, action, key, handler.handler, handler) 106 } 107 } 108 109 /** 110 * Setup recursive attached/detached calls 111 */ 112 113 Vue.prototype._initDOMHooks = function () { 114 this.$on('hook:attached', onAttached) 115 this.$on('hook:detached', onDetached) 116 } 117 118 /** 119 * Callback to recursively call attached hook on children 120 */ 121 122 function onAttached () { 123 if (!this._isAttached) { 124 this._isAttached = true 125 this.$children.forEach(callAttach) 126 } 127 } 128 129 /** 130 * Iterator to call attached hook 131 * 132 * @param {Vue} child 133 */ 134 135 function callAttach (child) { 136 if (!child._isAttached && inDoc(child.$el)) { 137 child._callHook('attached') 138 } 139 } 140 141 /** 142 * Callback to recursively call detached hook on children 143 */ 144 145 function onDetached () { 146 if (this._isAttached) { 147 this._isAttached = false 148 this.$children.forEach(callDetach) 149 } 150 } 151 152 /** 153 * Iterator to call detached hook 154 * 155 * @param {Vue} child 156 */ 157 158 function callDetach (child) { 159 if (child._isAttached && !inDoc(child.$el)) { 160 child._callHook('detached') 161 } 162 } 163 164 /** 165 * Trigger all handlers for a hook 166 * 167 * @param {String} hook 168 */ 169 170 Vue.prototype._callHook = function (hook) { 171 this.$emit('pre-hook:' + hook) 172 var handlers = this.$options[hook] 173 if (handlers) { 174 for (var i = 0, j = handlers.length; i < j; i++) { 175 handlers[i].call(this) 176 } 177 } 178 this.$emit('hook:' + hook) 179 } 180 }