]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat: created/beforeCreate
authorEvan You <yyx990803@gmail.com>
Thu, 5 Sep 2019 14:07:43 +0000 (10:07 -0400)
committerEvan You <yyx990803@gmail.com>
Thu, 5 Sep 2019 14:20:40 +0000 (10:20 -0400)
packages/runtime-core/__tests__/apiOptions.spec.ts
packages/runtime-core/src/apiOptions.ts

index b0f4d14793231f10fa20aa89e25f6955d809d543..103a56a407d1044e56292d8500818ccb698bf418 100644 (file)
@@ -227,7 +227,145 @@ describe('api: options', () => {
     expect(renderToString(h(Root))).toBe(`<!---->1112<!---->`)
   })
 
-  test('lifecycle', () => {})
+  test('lifecycle', async () => {
+    const count = ref(0)
+    const root = nodeOps.createElement('div')
+    const calls: string[] = []
+
+    const Root = {
+      beforeCreate() {
+        calls.push('root beforeCreate')
+      },
+      created() {
+        calls.push('root created')
+      },
+      beforeMount() {
+        calls.push('root onBeforeMount')
+      },
+      mounted() {
+        calls.push('root onMounted')
+      },
+      beforeUpdate() {
+        calls.push('root onBeforeUpdate')
+      },
+      updated() {
+        calls.push('root onUpdated')
+      },
+      beforeUnmount() {
+        calls.push('root onBeforeUnmount')
+      },
+      unmounted() {
+        calls.push('root onUnmounted')
+      },
+      render() {
+        return h(Mid, { count: count.value })
+      }
+    }
+
+    const Mid = {
+      beforeCreate() {
+        calls.push('mid beforeCreate')
+      },
+      created() {
+        calls.push('mid created')
+      },
+      beforeMount() {
+        calls.push('mid onBeforeMount')
+      },
+      mounted() {
+        calls.push('mid onMounted')
+      },
+      beforeUpdate() {
+        calls.push('mid onBeforeUpdate')
+      },
+      updated() {
+        calls.push('mid onUpdated')
+      },
+      beforeUnmount() {
+        calls.push('mid onBeforeUnmount')
+      },
+      unmounted() {
+        calls.push('mid onUnmounted')
+      },
+      render() {
+        return h(Child, { count: this.$props.count })
+      }
+    }
+
+    const Child = {
+      beforeCreate() {
+        calls.push('child beforeCreate')
+      },
+      created() {
+        calls.push('child created')
+      },
+      beforeMount() {
+        calls.push('child onBeforeMount')
+      },
+      mounted() {
+        calls.push('child onMounted')
+      },
+      beforeUpdate() {
+        calls.push('child onBeforeUpdate')
+      },
+      updated() {
+        calls.push('child onUpdated')
+      },
+      beforeUnmount() {
+        calls.push('child onBeforeUnmount')
+      },
+      unmounted() {
+        calls.push('child onUnmounted')
+      },
+      render() {
+        return h('div', this.$props.count)
+      }
+    }
+
+    // mount
+    render(h(Root), root)
+    expect(calls).toEqual([
+      'root beforeCreate',
+      'root created',
+      'root onBeforeMount',
+      'mid beforeCreate',
+      'mid created',
+      'mid onBeforeMount',
+      'child beforeCreate',
+      'child created',
+      'child onBeforeMount',
+      'child onMounted',
+      'mid onMounted',
+      'root onMounted'
+    ])
+
+    calls.length = 0
+
+    // update
+    count.value++
+    await nextTick()
+    expect(calls).toEqual([
+      'root onBeforeUpdate',
+      'mid onBeforeUpdate',
+      'child onBeforeUpdate',
+      'child onUpdated',
+      'mid onUpdated',
+      'root onUpdated'
+    ])
+
+    calls.length = 0
+
+    // unmount
+    render(null, root)
+    expect(calls).toEqual([
+      'root onBeforeUnmount',
+      'mid onBeforeUnmount',
+      'child onBeforeUnmount',
+      'child onUnmounted',
+      'mid onUnmounted',
+      'root onUnmounted'
+    ])
+  })
 
   test('mixins', () => {
     const calls: string[] = []
@@ -237,8 +375,14 @@ describe('api: options', () => {
           a: 1
         }
       },
+      created() {
+        calls.push('mixinA created')
+        expect(this.a).toBe(1)
+        expect(this.b).toBe(2)
+        expect(this.c).toBe(3)
+      },
       mounted() {
-        calls.push('mixinA')
+        calls.push('mixinA mounted')
       }
     }
     const mixinB = {
@@ -247,8 +391,14 @@ describe('api: options', () => {
           b: 2
         }
       },
+      created() {
+        calls.push('mixinB created')
+        expect(this.a).toBe(1)
+        expect(this.b).toBe(2)
+        expect(this.c).toBe(3)
+      },
       mounted() {
-        calls.push('mixinB')
+        calls.push('mixinB mounted')
       }
     }
     const Comp = {
@@ -258,8 +408,14 @@ describe('api: options', () => {
           c: 3
         }
       },
+      created() {
+        calls.push('comp created')
+        expect(this.a).toBe(1)
+        expect(this.b).toBe(2)
+        expect(this.c).toBe(3)
+      },
       mounted() {
-        calls.push('comp')
+        calls.push('comp mounted')
       },
       render() {
         return `${this.a}${this.b}${this.c}`
@@ -267,7 +423,14 @@ describe('api: options', () => {
     }
 
     expect(renderToString(h(Comp))).toBe(`123`)
-    expect(calls).toEqual(['mixinA', 'mixinB', 'comp'])
+    expect(calls).toEqual([
+      'mixinA created',
+      'mixinB created',
+      'comp created',
+      'mixinA mounted',
+      'mixinB mounted',
+      'comp mounted'
+    ])
   })
 
   test('extends', () => {
index 6070b8c361530eebf8b1bcec16741a830dc4cd76..472462cf715077b20190ef8e12ffb6b11c11b49e 100644 (file)
@@ -70,8 +70,8 @@ export interface LegacyOptions {
   updated?(): void
   activated?(): void
   decativated?(): void
-  beforeDestroy?(): void
-  destroyed?(): void
+  beforeUnmount?(): void
+  unmounted?(): void
   renderTracked?(e: DebuggerEvent): void
   renderTriggered?(e: DebuggerEvent): void
   errorCaptured?(): boolean | void
@@ -100,25 +100,30 @@ export function applyOptions(
     components,
     directives,
     // lifecycle
-    // beforeCreate is handled separately
-    created,
     beforeMount,
     mounted,
     beforeUpdate,
     updated,
     // TODO activated
     // TODO decativated
-    beforeDestroy,
-    destroyed,
+    beforeUnmount,
+    unmounted,
     renderTracked,
     renderTriggered,
     errorCaptured
   } = options
 
+  const globalMixins = instance.appContext.mixins
+
+  // beforeCreate
+  if (!asMixin) {
+    callSyncHook('beforeCreate', options, ctx, globalMixins)
+  }
+
   // global mixins are applied first, and only if this is a non-mixin call
   // so that they are applied once per instance.
   if (!asMixin) {
-    applyMixins(instance, instance.appContext.mixins)
+    applyMixins(instance, globalMixins)
   }
   // extending a base component...
   if (extendsOptions) {
@@ -205,8 +210,8 @@ export function applyOptions(
   }
 
   // lifecycle options
-  if (created) {
-    created.call(ctx)
+  if (!asMixin) {
+    callSyncHook('created', options, ctx, globalMixins)
   }
   if (beforeMount) {
     onBeforeMount(beforeMount.bind(ctx))
@@ -229,11 +234,45 @@ export function applyOptions(
   if (renderTriggered) {
     onRenderTracked(renderTriggered.bind(ctx))
   }
-  if (beforeDestroy) {
-    onBeforeUnmount(beforeDestroy.bind(ctx))
+  if (beforeUnmount) {
+    onBeforeUnmount(beforeUnmount.bind(ctx))
   }
-  if (destroyed) {
-    onUnmounted(destroyed.bind(ctx))
+  if (unmounted) {
+    onUnmounted(unmounted.bind(ctx))
+  }
+}
+
+function callSyncHook(
+  name: 'beforeCreate' | 'created',
+  options: ComponentOptions,
+  ctx: any,
+  globalMixins: ComponentOptions[]
+) {
+  callHookFromMixins(name, globalMixins, ctx)
+  const baseHook = options.extends && options.extends[name]
+  if (baseHook) {
+    baseHook.call(ctx)
+  }
+  const mixins = options.mixins
+  if (mixins) {
+    callHookFromMixins(name, mixins, ctx)
+  }
+  const selfHook = options[name]
+  if (selfHook) {
+    selfHook.call(ctx)
+  }
+}
+
+function callHookFromMixins(
+  name: 'beforeCreate' | 'created',
+  mixins: ComponentOptions[],
+  ctx: any
+) {
+  for (let i = 0; i < mixins.length; i++) {
+    const fn = mixins[i][name]
+    if (fn) {
+      fn.call(ctx)
+    }
   }
 }