or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-tools.mdcomposition-api.mdindex.mdreactive-utilities.mdversion-detection.md

composition-api.mddocs/

0

# Composition API

1

2

Universal access to Composition API functions that work across Vue 2 (with @vue/composition-api) and Vue 3. Vue Demi automatically provides the appropriate implementation based on the detected Vue version.

3

4

## Capabilities

5

6

### Safe Installation

7

8

Ensures the Composition API plugin is properly installed. This is a no-op in Vue 3 but safely installs @vue/composition-api in Vue 2 environments.

9

10

```typescript { .api }

11

/**

12

* Safe installation of Composition API plugin

13

* No-op in Vue 3, installs @vue/composition-api in Vue 2

14

* @param vue - Optional Vue constructor (Vue 2 only), ignored in Vue 3

15

*/

16

declare function install(vue?: typeof Vue): void; // Vue 2: (vue?: typeof Vue), Vue 3: () => void

17

```

18

19

**Usage Examples:**

20

21

```typescript

22

import { install } from "vue-demi";

23

24

// Ensure Composition API is available

25

install();

26

27

// Or with specific Vue instance

28

import Vue from 'vue';

29

install(Vue);

30

31

// Safe to call multiple times

32

install();

33

install(); // No-op if already installed

34

```

35

36

### Universal Composition API

37

38

All Composition API functions are re-exported from vue-demi, providing a universal interface that works across Vue versions.

39

40

```typescript { .api }

41

// Core reactivity

42

export function ref<T>(value: T): Ref<T>;

43

export function reactive<T extends object>(target: T): UnwrapNestedRefs<T>;

44

export function computed<T>(getter: () => T): ComputedRef<T>;

45

export function readonly<T>(target: T): DeepReadonly<T>;

46

47

// Watchers

48

export function watch<T>(

49

source: WatchSource<T>,

50

callback: WatchCallback<T>,

51

options?: WatchOptions

52

): WatchStopHandle;

53

54

export function watchEffect(

55

effect: WatchEffect,

56

options?: WatchOptionsBase

57

): WatchStopHandle;

58

59

// Lifecycle hooks

60

export function onMounted(hook: () => any): void;

61

export function onUpdated(hook: () => any): void;

62

export function onUnmounted(hook: () => any): void;

63

export function onBeforeMount(hook: () => any): void;

64

export function onBeforeUpdate(hook: () => any): void;

65

export function onBeforeUnmount(hook: () => any): void;

66

67

// Dependency injection

68

export function provide<T>(key: InjectionKey<T> | string, value: T): void;

69

export function inject<T>(key: InjectionKey<T> | string): T | undefined;

70

export function inject<T>(key: InjectionKey<T> | string, defaultValue: T): T;

71

72

// Component utilities

73

export function getCurrentInstance(): ComponentInternalInstance | null;

74

export function nextTick(fn?: () => void): Promise<void>;

75

export function hasInjectionContext(): boolean;

76

```

77

78

**Usage Examples:**

79

80

```typescript

81

import {

82

ref,

83

reactive,

84

computed,

85

watch,

86

onMounted,

87

install

88

} from "vue-demi";

89

90

// Ensure Composition API is installed

91

install();

92

93

export default {

94

setup() {

95

// Reactive state

96

const count = ref(0);

97

const user = reactive({

98

name: 'John',

99

email: 'john@example.com'

100

});

101

102

// Computed values

103

const doubleCount = computed(() => count.value * 2);

104

105

// Watchers

106

watch(count, (newVal, oldVal) => {

107

console.log(`Count changed from ${oldVal} to ${newVal}`);

108

});

109

110

// Lifecycle

111

onMounted(() => {

112

console.log('Component mounted');

113

});

114

115

return {

116

count,

117

user,

118

doubleCount

119

};

120

}

121

};

122

```

123

124

### Vue 3 Component Mocks (Vue 2 only)

125

126

In Vue 2 environments, Vue 3 specific components are provided as mock implementations that throw helpful errors to prevent runtime issues.

127

128

```typescript { .api }

129

/**

130

* Mock components for Vue 3 features not available in Vue 2

131

* These throw descriptive errors when used in Vue 2

132

*/

133

export declare const Fragment: Component;

134

export declare const Transition: Component;

135

export declare const TransitionGroup: Component;

136

export declare const Teleport: Component;

137

export declare const Suspense: Component;

138

export declare const KeepAlive: Component;

139

```

140

141

**Usage Examples:**

142

143

```typescript

144

import { Fragment, isVue2 } from "vue-demi";

145

146

// Safe conditional usage

147

const MyComponent = {

148

setup() {

149

if (isVue2) {

150

// Vue 2 implementation without Fragment

151

return () => h('div', [

152

h('p', 'First paragraph'),

153

h('p', 'Second paragraph')

154

]);

155

} else {

156

// Vue 3 implementation with Fragment

157

return () => h(Fragment, [

158

h('p', 'First paragraph'),

159

h('p', 'Second paragraph')

160

]);

161

}

162

}

163

};

164

165

// This would throw an error in Vue 2:

166

// [vue-demi] Fragment is not supported in Vue 2. It's provided to avoid compiler errors.

167

```

168

169

### Injection Context Check

170

171

Utility to check if injection context is available, useful for safely using provide/inject.

172

173

```typescript { .api }

174

/**

175

* Check if injection context exists

176

* Falls back to getCurrentInstance() check

177

* @returns boolean indicating if injection context is available

178

*/

179

export function hasInjectionContext(): boolean;

180

```

181

182

**Usage Examples:**

183

184

```typescript

185

import { hasInjectionContext, inject, provide } from "vue-demi";

186

187

// Safe injection usage

188

function useTheme() {

189

if (hasInjectionContext()) {

190

return inject('theme', 'light');

191

}

192

return 'light'; // fallback

193

}

194

195

// Conditional provide/inject

196

export default {

197

setup() {

198

if (hasInjectionContext()) {

199

provide('theme', 'dark');

200

}

201

202

const theme = useTheme();

203

return { theme };

204

}

205

};

206

```

207

208

### Vue Warning Utility (Vue 2.7 only)

209

210

Vue 2.7 provides access to Vue's internal warning utility for development debugging.

211

212

```typescript { .api }

213

/**

214

* Vue warning function (Vue 2.7 only)

215

* Emits development warnings with optional component context

216

* @param msg - Warning message to display

217

* @param vm - Optional component instance for context

218

*/

219

export declare function warn(msg: string, vm?: Component | null): void;

220

```

221

222

**Usage Examples:**

223

224

```typescript

225

import { warn, isVue2, version } from "vue-demi";

226

227

// Development warnings (Vue 2.7 only)

228

export default {

229

setup() {

230

if (process.env.NODE_ENV !== 'production' && isVue2 && version?.startsWith('2.7')) {

231

// Emit warning with component context

232

warn('This is a development warning', getCurrentInstance());

233

234

// Simple warning

235

warn('Configuration issue detected');

236

}

237

238

return {};

239

}

240

};

241

242

// Conditional warning utility

243

function devWarn(message: string, component?: any) {

244

if (process.env.NODE_ENV !== 'production' && typeof warn === 'function') {

245

warn(message, component);

246

} else {

247

console.warn(message);

248

}

249

}

250

```

251

252

### Vue 2.7 App Creation Polyfill

253

254

For Vue 2.7, vue-demi provides a polyfill for Vue 3's `createApp` API.

255

256

```typescript { .api }

257

/**

258

* Create Vue 3 style app instance (Vue 2.7 only)

259

* Polyfill that wraps Vue 2 constructor with Vue 3 app interface

260

*/

261

export function createApp(rootComponent: any, rootProps?: any): App;

262

263

interface App<T = any> {

264

config: VueConstructor['config'];

265

use: VueConstructor['use'];

266

mixin: VueConstructor['mixin'];

267

component: VueConstructor['component'];

268

directive(name: string): Directive | undefined;

269

directive(name: string, directive: Directive): this;

270

provide<T>(key: InjectionKey<T> | string, value: T): this;

271

mount: Vue['$mount'];

272

unmount: Vue['$destroy'];

273

}

274

```

275

276

**Usage Examples (Vue 2.7 only):**

277

278

```typescript

279

import { createApp, isVue2 } from "vue-demi";

280

281

const MyComponent = {

282

template: '<div>{{ message }}</div>',

283

data() {

284

return { message: 'Hello Vue!' };

285

}

286

};

287

288

// Vue 2.7 with createApp polyfill

289

if (isVue2) {

290

const app = createApp(MyComponent);

291

app.provide('theme', 'dark');

292

app.mount('#app');

293

}

294

```