or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animation-effects.mdbrowser-apis.mddevice-sensors.mddom-elements.mdevents.mdindex.mdmouse-pointer.mdnetwork.mdshared-utilities.mdstate-management.mdtemplate-composition.mdutilities.md

template-composition.mddocs/

0

# Template Composition

1

2

Advanced template composition utilities for creating reusable templates, template-based promises, and template reference helpers. These utilities enable sophisticated template patterns and component composition strategies.

3

4

## Capabilities

5

6

### Template Reusability

7

8

#### createReusableTemplate

9

10

Create reusable template components that can be defined once and reused multiple times.

11

12

```typescript { .api }

13

/**

14

* Create a pair of components for defining and reusing templates

15

* @param options - Template configuration options

16

* @returns Template component pair with define and reuse components

17

*/

18

function createReusableTemplate<

19

Bindings extends Record<string, any> = {},

20

Props extends Record<string, any> = {},

21

MapSlotNameToSlotProps extends Record<string, any> = {}

22

>(

23

options?: CreateReusableTemplateOptions<Props>

24

): ReusableTemplatePair<Bindings, MapSlotNameToSlotProps>;

25

26

interface CreateReusableTemplateOptions<Props extends Record<string, any>> {

27

inheritAttrs?: boolean;

28

props?: ComponentObjectPropsOptions<Props>;

29

}

30

31

type ReusableTemplatePair<

32

Bindings extends Record<string, any>,

33

MapSlotNameToSlotProps extends Record<string, any>

34

> = [

35

DefineTemplateComponent<Bindings, MapSlotNameToSlotProps>,

36

ReuseTemplateComponent<Bindings, MapSlotNameToSlotProps>

37

] & {

38

define: DefineTemplateComponent<Bindings, MapSlotNameToSlotProps>;

39

reuse: ReuseTemplateComponent<Bindings, MapSlotNameToSlotProps>;

40

};

41

```

42

43

**Usage Examples:**

44

45

```typescript

46

import { createReusableTemplate } from "@vueuse/core";

47

48

// Create template pair

49

const [DefineTemplate, ReuseTemplate] = createReusableTemplate<{ name: string }>();

50

51

// In your component template:

52

// <DefineTemplate v-slot="{ name }">

53

// <h1>Hello {{ name }}!</h1>

54

// </DefineTemplate>

55

//

56

// <ReuseTemplate name="World" />

57

// <ReuseTemplate name="Vue" />

58

```

59

60

#### createTemplatePromise

61

62

Create Promise-based templates for modal dialogs, confirmations, and async interactions.

63

64

```typescript { .api }

65

/**

66

* Create Promise-based template components for modal interactions

67

* @param options - Template promise configuration options

68

* @returns Template promise component and utilities

69

*/

70

function createTemplatePromise<Return = any, Args extends any[] = []>(

71

options?: TemplatePromiseOptions

72

): TemplatePromiseReturn<Return, Args>;

73

74

interface TemplatePromiseReturn<Return, Args extends any[]> {

75

TemplatePromise: DefineComponent<TemplatePromiseProps<Return, Args>>;

76

start: (...args: Args) => Promise<Return>;

77

close: () => void;

78

}

79

80

interface TemplatePromiseProps<Return, Args extends any[]> {

81

promise: Promise<Return> | undefined;

82

resolve: (v: Return | Promise<Return>) => void;

83

reject: (v: any) => void;

84

args: Args;

85

isResolving: boolean;

86

options: TemplatePromiseOptions;

87

}

88

89

interface TemplatePromiseOptions {

90

singleton?: boolean;

91

transition?: TransitionGroupProps;

92

}

93

```

94

95

**Usage Examples:**

96

97

```typescript

98

import { createTemplatePromise } from "@vueuse/core";

99

100

// Create confirmation dialog

101

const { TemplatePromise, start } = createTemplatePromise<boolean>();

102

103

// Use in template:

104

// <TemplatePromise v-slot="{ resolve, reject, args }">

105

// <div class="modal">

106

// <p>Are you sure?</p>

107

// <button @click="resolve(true)">Yes</button>

108

// <button @click="resolve(false)">No</button>

109

// </div>

110

// </TemplatePromise>

111

112

// Trigger programmatically

113

const confirmed = await start();

114

```

115

116

### Template References

117

118

#### templateRef

119

120

Template reference helper with type safety and automatic cleanup.

121

122

```typescript { .api }

123

/**

124

* Type-safe template reference helper

125

* @param key - Template ref key or element selector

126

* @param initialValue - Initial ref value

127

* @returns Template ref with enhanced capabilities

128

*/

129

function templateRef<T extends Element | ComponentPublicInstance = Element>(

130

key?: string | number | symbol,

131

initialValue?: T | null

132

): Readonly<Ref<T | null>>;

133

```

134

135

**Usage Examples:**

136

137

```typescript

138

import { templateRef } from "@vueuse/core";

139

140

// In setup

141

const buttonRef = templateRef<HTMLButtonElement>('button');

142

143

// In template: <button ref="button">Click me</button>

144

145

// Access element

146

console.log(buttonRef.value?.textContent);

147

```

148

149

#### useTemplateRefsList

150

151

Manage multiple template references with reactive list support.

152

153

```typescript { .api }

154

/**

155

* Reactive template references list for v-for scenarios

156

* @returns Template refs list with reactive updates

157

*/

158

function useTemplateRefsList<T = Element>(): [

159

Ref<T[]>,

160

(el: T | ComponentPublicInstance | Element | null) => void

161

];

162

```

163

164

**Usage Examples:**

165

166

```typescript

167

import { useTemplateRefsList } from "@vueuse/core";

168

169

// In setup

170

const [itemRefs, setItemRef] = useTemplateRefsList<HTMLDivElement>();

171

172

// In template:

173

// <div v-for="item in items" :key="item.id" :ref="setItemRef">

174

// {{ item.name }}

175

// </div>

176

177

// Access elements

178

itemRefs.value.forEach(el => console.log(el.textContent));

179

```

180

181

### Function Utilities

182

183

#### createUnrefFn

184

185

Create functions that automatically unref their arguments.

186

187

```typescript { .api }

188

/**

189

* Create a function that automatically unrefs its arguments

190

* @param fn - Function to enhance with auto-unref

191

* @returns Function that accepts refs and automatically unrefs them

192

*/

193

function createUnrefFn<T extends AnyFn>(fn: T): UnrefFnReturn<T>;

194

195

type UnrefFnReturn<T extends AnyFn> = (

196

...args: ToRefs<Parameters<T>>

197

) => ReturnType<T>;

198

```

199

200

**Usage Examples:**

201

202

```typescript

203

import { createUnrefFn, ref } from "@vueuse/core";

204

205

// Create unref function

206

const add = createUnrefFn((a: number, b: number) => a + b);

207

208

// Use with refs

209

const x = ref(1);

210

const y = ref(2);

211

const result = add(x, y); // Automatically unrefs x and y

212

```

213

214

#### unrefElement

215

216

Unref element from template refs, component instances, or plain elements.

217

218

```typescript { .api }

219

/**

220

* Unref element from various ref types

221

* @param elRef - Element reference (ref, component, or element)

222

* @returns Unrefed HTML element or null

223

*/

224

function unrefElement<T extends MaybeElement>(

225

elRef: MaybeElementRef<T>

226

): UnwrapNestedRefs<T>;

227

228

type MaybeElement = HTMLElement | SVGElement | VueInstance | undefined | null;

229

type MaybeElementRef<T extends MaybeElement = MaybeElement> = MaybeRef<T>;

230

```

231

232

**Usage Examples:**

233

234

```typescript

235

import { unrefElement, ref } from "@vueuse/core";

236

237

const elementRef = ref<HTMLDivElement>();

238

const componentRef = ref<ComponentPublicInstance>();

239

240

// Unref to get actual DOM element

241

const element = unrefElement(elementRef);

242

const componentElement = unrefElement(componentRef); // Gets component.$el

243

```

244

245

### Reactive Composition

246

247

#### computedInject

248

249

Computed with dependency injection support.

250

251

```typescript { .api }

252

/**

253

* Computed with dependency injection from parent components

254

* @param key - Injection key

255

* @param fn - Computation function receiving injected value

256

* @param defaultValue - Default value if injection fails

257

* @returns Computed ref with injected dependency

258

*/

259

function computedInject<T, K>(

260

key: InjectionKey<T> | string,

261

fn: (source: T, oldValue: K | undefined) => K,

262

defaultValue?: T

263

): ComputedRef<K>;

264

```

265

266

**Usage Examples:**

267

268

```typescript

269

import { computedInject, provide, ref } from "@vueuse/core";

270

271

// Parent provides theme

272

const theme = ref('dark');

273

provide('theme', theme);

274

275

// Child computes based on injected theme

276

const computedStyles = computedInject('theme', (theme) => ({

277

background: theme === 'dark' ? '#000' : '#fff',

278

color: theme === 'dark' ? '#fff' : '#000'

279

}));

280

```

281

282

### Event Management

283

284

#### createEventHook

285

286

Create custom event hooks for component communication.

287

288

```typescript { .api }

289

/**

290

* Create custom event hook for component events

291

* @returns Event hook with trigger and on methods

292

*/

293

function createEventHook<T = any>(): EventHook<T>;

294

295

interface EventHook<T = any> {

296

on: (fn: (param: T) => void) => void;

297

off: (fn: (param: T) => void) => void;

298

trigger: (param: T) => Promise<unknown[]>;

299

}

300

```

301

302

**Usage Examples:**

303

304

```typescript

305

import { createEventHook } from "@vueuse/core";

306

307

// Create custom event

308

const onDataLoaded = createEventHook<{ data: any[] }>();

309

310

// Listen to event

311

onDataLoaded.on(({ data }) => {

312

console.log('Data loaded:', data);

313

});

314

315

// Trigger event

316

onDataLoaded.trigger({ data: [1, 2, 3] });

317

```

318

319

## Shared Types

320

321

```typescript { .api }

322

// Component types

323

type VueInstance = ComponentPublicInstance;

324

type MaybeElement = HTMLElement | SVGElement | VueInstance | undefined | null;

325

type MaybeElementRef<T extends MaybeElement = MaybeElement> = MaybeRef<T>;

326

327

// Template component types

328

type DefineTemplateComponent<

329

Bindings extends Record<string, any>,

330

MapSlotNameToSlotProps extends Record<string, any>

331

> = DefineComponent & {

332

new(): {

333

$slots: {

334

default: (_: Bindings & {

335

$slots: GenerateSlotsFromSlotMap<MapSlotNameToSlotProps>

336

}) => any

337

}

338

}

339

};

340

341

type ReuseTemplateComponent<

342

Bindings extends Record<string, any>,

343

MapSlotNameToSlotProps extends Record<string, any>

344

> = DefineComponent<Bindings> & {

345

new(): {

346

$slots: GenerateSlotsFromSlotMap<MapSlotNameToSlotProps>

347

}

348

};

349

350

// Function utility types

351

type AnyFn = (...args: any[]) => any;

352

type ToRefs<T extends readonly unknown[]> = {

353

[K in keyof T]: MaybeRef<T[K]>

354

};

355

356

type UnrefFnReturn<T extends AnyFn> = (

357

...args: ToRefs<Parameters<T>>

358

) => ReturnType<T>;

359

360

// Event hook types

361

interface EventHookOn<T = any> {

362

(fn: (param: T) => void): void;

363

}

364

365

interface EventHookOff<T = any> {

366

(fn: (param: T) => void): void;

367

}

368

369

interface EventHookTrigger<T = any> {

370

(param: T): Promise<unknown[]>;

371

}

372

```