From ef9628ce7fdbf5415dbcb19fecad0b9de987afdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90=20Kevin=20Deng?= Date: Thu, 9 Nov 2023 17:54:31 +0800 Subject: [PATCH] feat(runtime-vapor): template --- .../runtime-vapor/__tests__/basic.spec.ts | 3 --- .../runtime-vapor/__tests__/template.spec.ts | 17 ++++++++++++++++ packages/runtime-vapor/src/index.ts | 2 +- packages/runtime-vapor/src/template.ts | 20 +++++++++++++++++++ 4 files changed, 38 insertions(+), 4 deletions(-) delete mode 100644 packages/runtime-vapor/__tests__/basic.spec.ts create mode 100644 packages/runtime-vapor/__tests__/template.spec.ts create mode 100644 packages/runtime-vapor/src/template.ts diff --git a/packages/runtime-vapor/__tests__/basic.spec.ts b/packages/runtime-vapor/__tests__/basic.spec.ts deleted file mode 100644 index 730cbb180..000000000 --- a/packages/runtime-vapor/__tests__/basic.spec.ts +++ /dev/null @@ -1,3 +0,0 @@ -test('basic', () => { - // -}) diff --git a/packages/runtime-vapor/__tests__/template.spec.ts b/packages/runtime-vapor/__tests__/template.spec.ts new file mode 100644 index 000000000..da471b432 --- /dev/null +++ b/packages/runtime-vapor/__tests__/template.spec.ts @@ -0,0 +1,17 @@ +/** + * @vitest-environment jsdom + */ + +import { template } from '../src' + +describe('api: template', () => { + test('create element', () => { + const t = template('
') + const div = t() + expect(div).toBeInstanceOf(HTMLDivElement) + + const div2 = t() + expect(div2).toBeInstanceOf(HTMLDivElement) + expect(div2).not.toBe(div) + }) +}) diff --git a/packages/runtime-vapor/src/index.ts b/packages/runtime-vapor/src/index.ts index 21ec276fc..305a75ddb 100644 --- a/packages/runtime-vapor/src/index.ts +++ b/packages/runtime-vapor/src/index.ts @@ -1 +1 @@ -export const foo = 'bar' +export { template } from './template' diff --git a/packages/runtime-vapor/src/template.ts b/packages/runtime-vapor/src/template.ts new file mode 100644 index 000000000..4f66b1572 --- /dev/null +++ b/packages/runtime-vapor/src/template.ts @@ -0,0 +1,20 @@ +export const template = (str: string): (() => Node) => { + let cached = false + let node: Node + return () => { + if (!cached) { + cached = true + const t = document.createElement('template') + t.innerHTML = str + // first render: insert the node directly. + // this removes it from the template fragment to avoid keeping two copies + // of the inserted tree in memory, even if the template is used only once. + return (node = t.content.firstChild!) + } else { + // repeated renders: clone from cache. This is more performant and + // efficient when dealing with big lists where the template is repeated + // many times. + return node.cloneNode(true) + } + } +}