diff --git a/src/compiler/codegen/directives.js b/src/compiler/codegen/directives.js index 952d17830..4f019193f 100644 --- a/src/compiler/codegen/directives.js +++ b/src/compiler/codegen/directives.js @@ -17,7 +17,7 @@ export function genDirectives (el) { } else { // runtime directive hasRuntime = true - res += `{name:"${dir.name}"${ + res += `{def:__d__("${dir.name}")${ dir.value ? `,value:(${dir.value})` : '' }${ dir.modifiers ? `,modifiers:${JSON.stringify(dir.modifiers)}` : '' diff --git a/src/runtime/directives/cloak.js b/src/runtime/directives/cloak.js new file mode 100644 index 000000000..b1c6ea436 --- /dev/null +++ b/src/runtime/directives/cloak.js @@ -0,0 +1 @@ +export default {} diff --git a/src/runtime/directives/index.js b/src/runtime/directives/index.js new file mode 100644 index 000000000..aab07f2a4 --- /dev/null +++ b/src/runtime/directives/index.js @@ -0,0 +1,4 @@ +import cloak from './cloak' +import show from './show' + +export { cloak, show } diff --git a/src/runtime/directives/show.js b/src/runtime/directives/show.js new file mode 100644 index 000000000..b1c6ea436 --- /dev/null +++ b/src/runtime/directives/show.js @@ -0,0 +1 @@ +export default {} diff --git a/src/runtime/global-api.js b/src/runtime/global-api.js index ed3832931..a0927f9d8 100644 --- a/src/runtime/global-api.js +++ b/src/runtime/global-api.js @@ -1,4 +1,5 @@ import config from './config' +import * as directives from './directives/index' import * as util from './util/index' import h from './vdom/h' import { @@ -23,7 +24,7 @@ export function initGlobalAPI (Vue) { Vue.nextTick = nextTick Vue.options = { - directives: Object.create(null), + directives, filters: Object.create(null), components: Object.create(null), transitions: Object.create(null) diff --git a/src/runtime/instance/render.js b/src/runtime/instance/render.js index 90970a2c1..48e54ac3f 100644 --- a/src/runtime/instance/render.js +++ b/src/runtime/instance/render.js @@ -1,5 +1,5 @@ import Watcher from '../observer/watcher' -import { query } from '../util/index' +import { query, resolveAsset } from '../util/index' import { h, patch } from '../vdom/index' import { callHook } from './lifecycle' @@ -11,7 +11,11 @@ export function initRender (vm) { } export function renderMixin (Vue) { + // shorthands used in render functions Vue.prototype.__h__ = h + Vue.prototype.__d__ = function (id) { + return resolveAsset(this.$options, 'directives', id, true) + } Vue.prototype._update = function (vtree) { callHook(this, 'beforeUpdate') diff --git a/src/runtime/instance/state.js b/src/runtime/instance/state.js index 7fd498b40..8ead82527 100644 --- a/src/runtime/instance/state.js +++ b/src/runtime/instance/state.js @@ -100,8 +100,8 @@ function initWatch (vm) { let handler = watch[key] let options if (typeof handler === 'object') { - handler = handler.handler options = handler + handler = handler.handler } vm.$watch(key, handler, options) } diff --git a/src/runtime/util/options.js b/src/runtime/util/options.js index 2ab48c6d8..990d59e12 100644 --- a/src/runtime/util/options.js +++ b/src/runtime/util/options.js @@ -282,6 +282,19 @@ function guardProps (options) { } } +function guardDirectives (options) { + var dirs = options.directives + if (dirs) { + var keys = Object.keys(dirs) + var i = keys.length + while (i--) { + if (typeof dirs[keys[i]] === 'function') { + dirs[keys[i]] = { update: dirs[keys[i]] } + } + } + } +} + /** * Merge two option objects into a new one. * Core utility used in both instantiation and inheritance. @@ -295,6 +308,7 @@ function guardProps (options) { export function mergeOptions (parent, child, vm) { guardComponents(child) guardProps(child) + guardDirectives(child) var options = {} var key if (child.mixins) { diff --git a/src/runtime/vdom/index.js b/src/runtime/vdom/index.js index 8a79b037f..3cc788f17 100644 --- a/src/runtime/vdom/index.js +++ b/src/runtime/vdom/index.js @@ -11,13 +11,15 @@ import style from './modules/style' import props from './modules/props' import attrs from './modules/attrs' import events from './modules/events' +import directives from './modules/directives' const patch = createPatchFunction([ classes, props, attrs, style, - events + events, + directives ]) export { patch, h } diff --git a/src/runtime/vdom/modules/directives.js b/src/runtime/vdom/modules/directives.js index e69de29bb..83245fe2c 100644 --- a/src/runtime/vdom/modules/directives.js +++ b/src/runtime/vdom/modules/directives.js @@ -0,0 +1,28 @@ +export default { + create: function (oldVnode, vnode) { + applyDirectives(oldVnode, vnode, 'bind') + }, + update: function (oldVnode, vnode) { + applyDirectives(oldVnode, vnode, 'update', true) + } +} + +function applyDirectives (oldVnode, vnode, hook, update) { + const dirs = vnode.data.directives + if (dirs) { + for (let i = 0; i < dirs.length; i++) { + let dir = dirs[i] + let fn = dir.def[hook] + if (fn) { + // only call update if value has changed + if (update) { + let oldValue = oldVnode.data.directives[i].value + if (oldValue === dir.value) { + continue + } + } + fn(vnode.elm, dir.value, dir.modifiers) + } + } + } +}