Browse Source

feat(compiler): mark hoisted trees with patchFlag

Evan You 6 years ago
parent
commit
175f8aae8d

+ 2 - 2
packages/compiler-core/__tests__/__snapshots__/scopeId.spec.ts.snap

@@ -5,8 +5,8 @@ exports[`scopeId compiler support should push scopeId for hoisted nodes 1`] = `
 const _withId = _withScopeId(\\"test\\")
 
 _pushScopeId(\\"test\\")
-const _hoisted_1 = _createVNode(\\"div\\", null, \\"hello\\")
-const _hoisted_2 = _createVNode(\\"div\\", null, \\"world\\")
+const _hoisted_1 = _createVNode(\\"div\\", null, \\"hello\\", -1)
+const _hoisted_2 = _createVNode(\\"div\\", null, \\"world\\", -1)
 _popScopeId()
 
 export const render = _withId(function render(_ctx, _cache) {

+ 2 - 2
packages/compiler-core/__tests__/scopeId.spec.ts

@@ -81,8 +81,8 @@ describe('scopeId compiler support', () => {
     expect(code).toMatch(
       [
         `_pushScopeId("test")`,
-        `const _hoisted_1 = _createVNode("div", null, "hello")`,
-        `const _hoisted_2 = _createVNode("div", null, "world")`,
+        `const _hoisted_1 = _createVNode("div", null, "hello", -1)`,
+        `const _hoisted_2 = _createVNode("div", null, "world", -1)`,
         `_popScopeId()`
       ].join('\n')
     )

+ 10 - 10
packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap

@@ -4,7 +4,7 @@ exports[`compiler: hoistStatic transform hoist element with static key 1`] = `
 "const _Vue = Vue
 const { createVNode: _createVNode } = _Vue
 
-const _hoisted_1 = _createVNode(\\"div\\", { key: \\"foo\\" })
+const _hoisted_1 = _createVNode(\\"div\\", { key: \\"foo\\" }, null, -1)
 
 return function render(_ctx, _cache) {
   with (this) {
@@ -24,7 +24,7 @@ const { createVNode: _createVNode } = _Vue
 const _hoisted_1 = _createVNode(\\"p\\", null, [
   _createVNode(\\"span\\"),
   _createVNode(\\"span\\")
-])
+], -1)
 
 return function render(_ctx, _cache) {
   with (this) {
@@ -43,7 +43,7 @@ const { createVNode: _createVNode, createCommentVNode: _createCommentVNode } = _
 
 const _hoisted_1 = _createVNode(\\"div\\", null, [
   _createCommentVNode(\\"comment\\")
-])
+], -1)
 
 return function render(_ctx, _cache) {
   with (this) {
@@ -60,8 +60,8 @@ exports[`compiler: hoistStatic transform hoist siblings with common non-hoistabl
 "const _Vue = Vue
 const { createVNode: _createVNode } = _Vue
 
-const _hoisted_1 = _createVNode(\\"span\\")
-const _hoisted_2 = _createVNode(\\"div\\")
+const _hoisted_1 = _createVNode(\\"span\\", null, null, -1)
+const _hoisted_2 = _createVNode(\\"div\\", null, null, -1)
 
 return function render(_ctx, _cache) {
   with (this) {
@@ -79,7 +79,7 @@ exports[`compiler: hoistStatic transform hoist simple element 1`] = `
 "const _Vue = Vue
 const { createVNode: _createVNode } = _Vue
 
-const _hoisted_1 = _createVNode(\\"span\\", { class: \\"inline\\" }, \\"hello\\")
+const _hoisted_1 = _createVNode(\\"span\\", { class: \\"inline\\" }, \\"hello\\", -1)
 
 return function render(_ctx, _cache) {
   with (this) {
@@ -172,7 +172,7 @@ exports[`compiler: hoistStatic transform prefixIdentifiers hoist nested static t
 "const _Vue = Vue
 const { createVNode: _createVNode } = _Vue
 
-const _hoisted_1 = _createVNode(\\"span\\", null, \\"foo \\" + _toDisplayString(1) + \\" \\" + _toDisplayString(true))
+const _hoisted_1 = _createVNode(\\"span\\", null, \\"foo \\" + _toDisplayString(1) + \\" \\" + _toDisplayString(true), -1)
 
 return function render(_ctx, _cache) {
   with (this) {
@@ -189,7 +189,7 @@ exports[`compiler: hoistStatic transform prefixIdentifiers hoist nested static t
 "const _Vue = Vue
 const { createVNode: _createVNode } = _Vue
 
-const _hoisted_1 = _createVNode(\\"span\\", { foo: 0 }, _toDisplayString(1))
+const _hoisted_1 = _createVNode(\\"span\\", { foo: 0 }, _toDisplayString(1), -1)
 
 return function render(_ctx, _cache) {
   with (this) {
@@ -346,7 +346,7 @@ exports[`compiler: hoistStatic transform should hoist v-for children if static 1
 const { createVNode: _createVNode } = _Vue
 
 const _hoisted_1 = { id: \\"foo\\" }
-const _hoisted_2 = _createVNode(\\"span\\")
+const _hoisted_2 = _createVNode(\\"span\\", null, null, -1)
 
 return function render(_ctx, _cache) {
   with (this) {
@@ -371,7 +371,7 @@ const _hoisted_1 = {
   key: 0,
   id: \\"foo\\"
 }
-const _hoisted_2 = _createVNode(\\"span\\")
+const _hoisted_2 = _createVNode(\\"span\\", null, null, -1)
 
 return function render(_ctx, _cache) {
   with (this) {

+ 1 - 0
packages/compiler-core/src/transforms/hoistStatic.ts

@@ -52,6 +52,7 @@ function walk(
     ) {
       if (!doNotHoistNode && isStaticNode(child, resultCache)) {
         // whole tree is static
+        ;(child.codegenNode as VNodeCall).patchFlag = PatchFlags.HOISTED + ``
         const hoisted = context.transformHoist
           ? context.transformHoist(child, context)
           : child.codegenNode!

+ 6 - 2
packages/runtime-core/src/renderer.ts

@@ -411,8 +411,12 @@ export function createRenderer<
     optimized: boolean
   ) {
     let el: HostElement
-    const { type, props, shapeFlag, transition, scopeId } = vnode
-    if (vnode.el != null && hostCloneNode !== undefined) {
+    const { type, props, shapeFlag, transition, scopeId, patchFlag } = vnode
+    if (
+      vnode.el !== null &&
+      hostCloneNode !== undefined &&
+      patchFlag === PatchFlags.HOISTED
+    ) {
       // If a vnode has non-null el, it means it's being reused.
       // Only static vnodes can be reused, so its mounted DOM nodes should be
       // exactly the same, and we can simply do a clone here.

+ 4 - 1
packages/shared/src/patchFlags.ts

@@ -61,11 +61,14 @@ export const enum PatchFlags {
   // Components with this flag are always force updated.
   DYNAMIC_SLOTS = 1 << 9,
 
+  // A special flag that indicates a hoisted, static vnode.
+  HOISTED = -1,
+
   // A special flag that indicates that the diffing algorithm should bail out
   // of optimized mode. This is only on block fragments created by renderSlot()
   // when encountering non-compiler generated slots (i.e. manually written
   // render functions, which should always be fully diffed)
-  BAIL = -1
+  BAIL = -2
 }
 
 // runtime object for public consumption