Browse Source

support keep-alive

dev
Evan You 9 years ago
parent
commit
a5a9dc9b69
  1. 2
      flow/vnode.js
  2. 8
      src/compiler/codegen.js
  3. 4
      src/core/config.js
  4. 2
      src/core/instance/lifecycle.js
  5. 20
      src/core/vdom/create-component.js
  6. 2
      src/platforms/web/compiler/modules/transition.js
  7. 6
      src/platforms/web/runtime/components/index.js
  8. 22
      src/platforms/web/runtime/components/keep-alive.js

2
flow/vnode.js

@ -13,6 +13,7 @@ declare interface MountedComponentVNode {
componentOptions: VNodeComponentOptions;
child: Component;
parent: VNode;
data: VNodeData;
}
// interface for vnodes in update modules
@ -52,6 +53,7 @@ declare interface VNodeData {
staticRenderFns: Array<Function>
};
directives?: Array<VNodeDirective>;
keepAlive?: boolean;
}
declare type VNodeDirective = {

8
src/compiler/codegen.js

@ -72,6 +72,8 @@ function genElement (el: ASTElement): string {
code = `_m(${staticRenderFns.length - 1})`
}
}
// check keep-alive
code = checkKeepAlive(el, code)
// platform modules
for (let i = 0; i < platformModules.length; i++) {
const transform = platformModules[i].transformElement
@ -268,6 +270,12 @@ function genComponent (el: ASTElement): string {
})`
}
function checkKeepAlive (el: ASTElement, code: string): string {
return el.keepAlive
? `_h(_e("vKeepAlive"),function(){return [${code}]})`
: code
}
function genProps (props: Array<{ name: string, value: string }>): string {
let res = ''
for (let i = 0; i < props.length; i++) {

4
src/core/config.js

@ -77,7 +77,9 @@ const config: Config = {
'beforeUpdate',
'updated',
'beforeDestroy',
'destroyed'
'destroyed',
'activated',
'deactivated'
],
/**

2
src/core/instance/lifecycle.js

@ -54,10 +54,10 @@ export function lifecycleMixin (Vue: Class<Component>) {
vm._update(vm._render(), hydrating)
}, noop)
hydrating = false
vm._isMounted = true
// root instance, call mounted on self
// mounted is called for child components in its inserted hook
if (vm.$root === vm) {
vm._isMounted = true
callHook(vm, 'mounted')
}
return vm

20
src/core/vdom/create-component.js

@ -97,8 +97,10 @@ export function createComponentInstanceForVnode (
}
function init (vnode: VNodeWithData, hydrating: boolean) {
const child = vnode.child = createComponentInstanceForVnode(vnode)
child.$mount(hydrating ? vnode.elm : undefined, hydrating)
if (!vnode.child) {
const child = vnode.child = createComponentInstanceForVnode(vnode)
child.$mount(hydrating ? vnode.elm : undefined, hydrating)
}
}
function prepatch (
@ -116,11 +118,21 @@ function prepatch (
}
function insert (vnode: MountedComponentVNode) {
callHook(vnode.child, 'mounted')
if (!vnode.child._isMounted) {
vnode.child._isMounted = true
callHook(vnode.child, 'mounted')
}
if (vnode.data.keepAlive) {
callHook(vnode.child, 'activated')
}
}
function destroy (vnode: MountedComponentVNode) {
vnode.child.$destroy()
if (!vnode.data.keepAlive) {
vnode.child.$destroy()
} else {
callHook(vnode.child, 'deactivated')
}
}
function resolveAsyncComponent (

2
src/platforms/web/compiler/modules/transition.js

@ -26,7 +26,7 @@ function genData (el: ASTElement): string {
function transformElement (el: ASTElement, code: string): string {
return el.transitionMode
? `_h(_e('transition-control',{props:{mode:${
? `_h(_e('vTransitionControl',{props:{mode:${
el.transitionMode
}}}),function(){return [${code}]})`
: code

6
src/platforms/web/runtime/components/index.js

@ -1,5 +1,7 @@
import transitionControl from './transition-control'
import vKeepAlive from './keep-alive'
import vTransitionControl from './transition-control'
export default {
transitionControl
vKeepAlive,
vTransitionControl
}

22
src/platforms/web/runtime/components/keep-alive.js

@ -0,0 +1,22 @@
export default {
created () {
this.cache = Object.create(null)
},
render () {
const childNode = this.$slots.default[0]
const cid = childNode.componentOptions.Ctor.cid
if (this.cache[cid]) {
const child = childNode.child = this.cache[cid].child
childNode.elm = this.$el = child.$el
} else {
this.cache[cid] = childNode
}
childNode.data.keepAlive = true
return childNode
},
beforeDestroy () {
for (const key in this.cache) {
this.cache[key].child.$destroy()
}
}
}
Loading…
Cancel
Save