feature: vor und nachteile

This commit is contained in:
Hikyu
2026-05-31 13:54:31 +02:00
parent 552a947a1c
commit e3dad17446
23270 changed files with 3024794 additions and 200 deletions
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2021 Yaël GUILLOUX <yael.guilloux@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+92
View File
@@ -0,0 +1,92 @@
# 🤹 @vueuse/motion
[![npm](https://img.shields.io/npm/v/@vueuse/motion.svg)](https://www.npmjs.com/package/@vueuse/motion)
[![npm](https://img.shields.io/npm/v/vueuse-motion-nightly.svg)](https://www.npmjs.com/package/vueuse-motion-nightly)
[![npm](https://img.shields.io/npm/dm/@vueuse/motion.svg)](https://npm-stat.com/charts.html?package=@vueuse/motion)
[![Netlify Status](https://api.netlify.com/api/v1/badges/ab1db459-8420-4bc6-9fac-2bc247fa2385/deploy-status)](https://app.netlify.com/sites/vueuse-motion/deploys)
Vue Composables putting your components in motion
- 🏎 **Smooth animations** based on [Popmotion](https://popmotion.io/)
- 🎮 **Declarative** API inspired by [Framer Motion](https://www.framer.com/motion/)
- 🚀 **Plug** & **play** with **20+ presets**
- 🌐 **SSR Ready**
- 🚚 First-class support for **Nuxt 3**
- ✨ Written in **TypeScript**
- 🏋️‍♀️ Lightweight with **<20kb** bundle size
[🌍 Documentation](https://motion.vueuse.org)
[👀 Demos](https://vueuse-motion-demo.netlify.app)
## Quick Start
Let's get started by installing the package and adding the plugin.
From your terminal:
```bash
npm install @vueuse/motion
```
In your Vue app entry file:
```javascript
import { createApp } from 'vue'
import { MotionPlugin } from '@vueuse/motion'
import App from './App.vue'
const app = createApp(App)
app.use(MotionPlugin)
app.mount('#app')
```
You can now animate any of your component, HTML or SVG elements using `v-motion`.
```vue
<template>
<div
v-motion
:initial="{
opacity: 0,
y: 100,
}"
:enter="{
opacity: 1,
y: 0,
}"
/>
</template>
```
To see more about how to use directives, check out [Directive Usage](https://motion.vueuse.org/features/directive-usage).
To see more about what properties you can animate, check out [Motion Properties](https://motion.vueuse.org/features/motion-properties).
To see more about how to create your own animation styles, check out [Transition Properties](https://motion.vueuse.org/features/transition-properties).
To see more about what are variants and how you can use them, check out [Variants](https://motion.vueuse.org/features/variants).
To see more about how to control your declared variants, check out [Motion Instance](https://motion.vueuse.org/features/motion-instance).
## Nightly release channel
You can try out the latest changes before a stable release by installing the nightly release channel.
```bash
npm install @vueuse/motion@npm:vueuse-motion-nightly
```
## Credits
This package is heavily inspired by [Framer Motion](https://www.framer.com/motion/) by [@mattgperry](https://twitter.com/mattgperry).
If you are interested in using [WAAPI](https://developer.mozilla.org/fr/docs/Web/API/Web_Animations_API), check out [Motion.dev](https://motion.dev/)!
I would also like to thank [antfu](https://github.com/antfu), [patak-dev](https://github.com/patak-dev) and [kazupon](https://github.com/kazupon) for their kind help!
If you like this package, consider following me on [GitHub](https://github.com/Tahul) and on [Twitter](https://twitter.com/yaeeelglx).
👋
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
module.exports = function(...args) {
return import('./module.mjs').then(m => m.default.call(this, ...args))
}
const _meta = module.exports.meta = require('./module.json')
module.exports.getMeta = () => Promise.resolve(_meta)
+428
View File
@@ -0,0 +1,428 @@
import { NuxtModule } from '@nuxt/schema';
import { MaybeRef, VueInstance } from '@vueuse/core';
import { CSSProperties, Ref, UnwrapRef } from 'vue';
type ResolvedKeyframesTarget = [null, ...number[]] | number[] | [null, ...string[]] | string[];
type KeyframesTarget = ResolvedKeyframesTarget | [null, ...CustomValueType[]] | CustomValueType[];
type ResolvedSingleTarget = string | number;
type SingleTarget = ResolvedSingleTarget | CustomValueType;
type ValueTarget = SingleTarget | KeyframesTarget;
type EasingFunction = (v: number) => number;
type Easing = [number, number, number, number] | 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' | 'circIn' | 'circOut' | 'circInOut' | 'backIn' | 'backOut' | 'backInOut' | 'anticipate' | EasingFunction;
interface Orchestration {
/**
* Delay the animation by this duration (in seconds). Defaults to `0`.
*/
delay?: number;
/**
* Callback triggered on animation complete.
*/
onComplete?: () => void;
/**
* Should the value be set imediately
*/
immediate?: boolean;
}
interface Repeat {
/**
* The number of times to repeat the transition. Set to `Infinity` for perpetual repeating.
*
* Without setting `repeatType`, this will loop the animation.
*/
repeat?: number;
/**
* How to repeat the animation. This can be either:
*
* "loop": Repeats the animation from the start
*
* "reverse": Alternates between forward and backwards playback
*
* "mirror": Switchs `from` and `to` alternately
*/
repeatType?: 'loop' | 'reverse' | 'mirror';
/**
* When repeating an animation, `repeatDelay` will set the
* duration of the time to wait, in seconds, between each repetition.
*/
repeatDelay?: number;
}
/**
* An animation that animates between two or more values over a specific duration of time.
* This is the default animation for non-physical values like `color` and `opacity`.
*/
interface Tween extends Repeat {
/**
* Set `type` to `"tween"` to use a duration-based tween animation.
* If any non-orchestration `transition` values are set without a `type` property,
* this is used as the default animation.
*/
type?: 'tween';
/**
* The duration of the tween animation. Set to `0.3` by default, 0r `0.8` if animating a series of keyframes.
*/
duration?: number;
/**
* The easing function to use. Set as one of the below.
*
* - The name of an existing easing function.
* - An array of four numbers to define a cubic bezier curve.
* - An easing function, that accepts and returns a value `0-1`.
*
* If the animating value is set as an array of multiple values for a keyframes
* animation, `ease` can be set as an array of easing functions to set different easings between
* each of those values.
*/
ease?: Easing | Easing[];
/**
* The duration of time already elapsed in the animation. Set to `0` by
* default.
*/
elapsed?: number;
/**
* When animating keyframes, `times` can be used to determine where in the animation each keyframe is reached.
* Each value in `times` is a value between `0` and `1`, representing `duration`.
*
* There must be the same number of `times` as there are keyframes.
* Defaults to an array of evenly-spread durations.
*/
times?: number[];
/**
* When animating keyframes, `easings` can be used to define easing functions between each keyframe. This array should be one item fewer than the number of keyframes, as these easings apply to the transitions between the keyframes.
*/
easings?: Easing[];
/**
* The value to animate from.
* By default, this is the current state of the animating value.
*/
from?: number | string;
to?: number | string | ValueTarget;
velocity?: number;
delay?: number;
}
/**
* An animation that simulates spring physics for realistic motion.
* This is the default animation for physical values like `x`, `y`, `scale` and `rotate`.
*/
interface Spring extends Repeat {
/**
* Set `type` to `"spring"` to animate using spring physics for natural
* movement. Type is set to `"spring"` by default.
*/
type: 'spring';
/**
* Stiffness of the spring. Higher values will create more sudden movement.
* Set to `100` by default.
*/
stiffness?: number;
/**
* Strength of opposing force. If set to 0, spring will oscillate
* indefinitely. Set to `10` by default.
*/
damping?: number;
/**
* Mass of the moving object. Higher values will result in more lethargic
* movement. Set to `1` by default.
*/
mass?: number;
/**
* The duration of the animation, defined in seconds. Spring animations can be a maximum of 10 seconds.
*
* If `bounce` is set, this defaults to `0.8`.
*
* Note: `duration` and `bounce` will be overridden if `stiffness`, `damping` or `mass` are set.
*/
duration?: number;
/**
* `bounce` determines the "bounciness" of a spring animation.
*
* `0` is no bounce, and `1` is extremely bouncy.
*
* If `duration` is set, this defaults to `0.25`.
*
* Note: `bounce` and `duration` will be overridden if `stiffness`, `damping` or `mass` are set.
*/
bounce?: number;
/**
* End animation if absolute speed (in units per second) drops below this
* value and delta is smaller than `restDelta`. Set to `0.01` by default.
*/
restSpeed?: number;
/**
* End animation if distance is below this value and speed is below
* `restSpeed`. When animation ends, spring gets “snapped” to. Set to
* `0.01` by default.
*/
restDelta?: number;
/**
* The value to animate from.
* By default, this is the initial state of the animating value.
*/
from?: number | string;
to?: number | string | ValueTarget;
/**
* The initial velocity of the spring. By default this is the current velocity of the component.
*/
velocity?: number;
delay?: number;
}
/**
* An animation that decelerates a value based on its initial velocity,
* usually used to implement inertial scrolling.
*
* Optionally, `min` and `max` boundaries can be defined, and inertia
* will snap to these with a spring animation.
*
* This animation will automatically precalculate a target value,
* which can be modified with the `modifyTarget` property.
*
* This allows you to add snap-to-grid or similar functionality.
*
* Inertia is also the animation used for `dragTransition`, and can be configured via that prop.
*/
interface Inertia {
/**
* Set `type` to animate using the inertia animation. Set to `"tween"` by
* default. This can be used for natural deceleration, like momentum scrolling.
*/
type: 'inertia';
/**
* A function that receives the automatically-calculated target and returns a new one. Useful for snapping the target to a grid.
*/
modifyTarget?: (v: number) => number;
/**
* If `min` or `max` is set, this affects the stiffness of the bounce
* spring. Higher values will create more sudden movement. Set to `500` by
* default.
*/
bounceStiffness?: number;
/**
* If `min` or `max` is set, this affects the damping of the bounce spring.
* If set to `0`, spring will oscillate indefinitely. Set to `10` by
* default.
*/
bounceDamping?: number;
/**
* A higher power value equals a further target. Set to `0.8` by default.
*/
power?: number;
/**
* Adjusting the time constant will change the duration of the
* deceleration, thereby affecting its feel. Set to `700` by default.
*/
timeConstant?: number;
/**
* End the animation if the distance to the animation target is below this value, and the absolute speed is below `restSpeed`.
* When the animation ends, the value gets snapped to the animation target. Set to `0.01` by default.
* Generally the default values provide smooth animation endings, only in rare cases should you need to customize these.
*/
restDelta?: number;
/**
* Minimum constraint. If set, the value will "bump" against this value (or immediately spring to it if the animation starts as less than this value).
*/
min?: number;
/**
* Maximum constraint. If set, the value will "bump" against this value (or immediately snap to it, if the initial animation value exceeds this value).
*/
max?: number;
/**
* The value to animate from. By default, this is the current state of the animating value.
*/
from?: number | string;
/**
* The initial velocity of the animation.
* By default this is the current velocity of the component.
*/
velocity?: number;
delay?: number;
}
/**
* Keyframes tweens between multiple `values`.
*
* These tweens can be arranged using the `duration`, `easings`, and `times` properties.
*/
interface Keyframes {
/**
* Set `type` to `"keyframes"` to animate using the keyframes animation.
* Set to `"tween"` by default. This can be used to animate between a series of values.
*/
type: 'keyframes';
/**
* An array of values to animate between.
*/
values: KeyframesTarget;
/**
* An array of numbers between 0 and 1, where `1` represents the `total` duration.
*
* Each value represents at which point during the animation each item in the animation target should be hit, so the array should be the same length as `values`.
*
* Defaults to an array of evenly-spread durations.
*/
times?: number[];
/**
* An array of easing functions for each generated tween, or a single easing function applied to all tweens.
*
* This array should be one item less than `values`, as these easings apply to the transitions *between* the `values`.
*/
ease?: Easing | Easing[];
/**
* Popmotion's easing prop to define individual easings. `ease` will be mapped to this prop in keyframes animations.
*/
easings?: Easing | Easing[];
elapsed?: number;
/**
* The total duration of the animation. Set to `0.3` by default.
*/
duration?: number;
repeatDelay?: number;
from?: number | string;
to?: number | string | ValueTarget;
velocity?: number;
delay?: number;
}
type PermissiveTransitionDefinition = Record<string, any>;
type TransitionDefinition = Tween | Spring | Keyframes | Inertia | PermissiveTransitionDefinition;
type TransitionMap = Orchestration & Record<string, TransitionDefinition>;
/**
* Transition props
*/
type Transition = (Orchestration & Repeat & TransitionDefinition) | (Orchestration & Repeat & TransitionMap);
interface CustomValueType {
mix: (from: any, to: any) => (p: number) => number | string;
toValue: () => number | string;
}
/**
* SVG Supported properties
*/
interface SVGPathProperties {
pathLength?: number;
pathOffset?: number;
pathSpacing?: number;
}
/**
* Transform properties
*/
type TransformValue = string | number;
interface TransformProperties {
x?: TransformValue | TransformValue[];
y?: TransformValue | TransformValue[];
z?: TransformValue | TransformValue[];
translateX?: TransformValue | TransformValue[];
translateY?: TransformValue | TransformValue[];
translateZ?: TransformValue | TransformValue[];
rotate?: TransformValue | TransformValue[];
rotateX?: TransformValue | TransformValue[];
rotateY?: TransformValue | TransformValue[];
rotateZ?: TransformValue | TransformValue[];
scale?: TransformValue | TransformValue[];
scaleX?: TransformValue | TransformValue[];
scaleY?: TransformValue | TransformValue[];
scaleZ?: TransformValue | TransformValue[];
skew?: TransformValue | TransformValue[];
skewX?: TransformValue | TransformValue[];
skewY?: TransformValue | TransformValue[];
originX?: TransformValue | TransformValue[];
originY?: TransformValue | TransformValue[];
originZ?: TransformValue | TransformValue[];
perspective?: TransformValue | TransformValue[];
transformPerspective?: TransformValue | TransformValue[];
}
/**
* Relevant styling properties
*/
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type StyleProperties = Omit<CSSProperties, 'transition' | 'rotate' | 'scale' | 'perspective' | 'transform' | 'transformBox' | 'transformOrigin' | 'transformStyle'>;
/**
* Available properties for useMotion variants
*/
type MotionProperties = StyleProperties | TransformProperties | SVGPathProperties;
/**
* Variant
*/
type Variant = {
transition?: Transition;
} & MotionProperties;
/**
* Motion variants object
*/
type MotionVariants<T extends string> = {
initial?: Variant;
enter?: Variant;
leave?: Variant;
visible?: Variant;
visibleOnce?: Variant;
hovered?: Variant;
tapped?: Variant;
focused?: Variant;
} & {
[key in T]?: Variant;
};
type PermissiveTarget = VueInstance | MotionTarget;
type MotionTarget = HTMLElement | SVGElement | null | undefined;
interface MotionInstance<T extends string, V extends MotionVariants<T>> extends MotionControls<T, V> {
target: MaybeRef<PermissiveTarget>;
variants: MaybeRef<V>;
variant: Ref<keyof V>;
state: Ref<Variant | undefined>;
motionProperties: UnwrapRef<MotionProperties>;
}
interface MotionControls<T extends string, V extends MotionVariants<T>> {
/**
* Apply a variant declaration and execute the resolved transitions.
*
* @param variant
* @returns Promise<void[]>
*/
apply: (variant: Variant | keyof V) => Promise<void[]> | undefined;
/**
* Apply a variant declaration without transitions.
*
* @param variant
*/
set: (variant: Variant | keyof V) => void;
/**
* Stop all the ongoing transitions for the current element.
*/
stop: (keys?: string | string[]) => void;
/**
* Helper to be passed to <transition> leave event.
*
* @param done
*/
leave: (done: () => void) => void;
/**
* Computed reference reactive to the animation state of motion controls.
*/
isAnimating: any;
}
type MotionInstanceBindings<T extends string, V extends MotionVariants<T>> = Record<string, MotionInstance<T, V>>;
declare module 'vue' {
interface ComponentCustomProperties {
$motions?: MotionInstanceBindings<any, any>;
}
}
declare module '@vue/runtime-dom' {
interface HTMLAttributes {
variants?: MotionVariants<any>;
initial?: Variant;
enter?: Variant;
leave?: Variant;
visible?: Variant;
visibleOnce?: Variant;
hovered?: Variant;
tapped?: Variant;
focused?: Variant;
}
}
interface ModuleOptions$1<T extends string> {
directives?: Record<T, MotionVariants<T>>;
excludePresets?: boolean;
}
interface ModuleOptions extends ModuleOptions$1<string> {
}
declare const _default: NuxtModule<ModuleOptions, ModuleOptions, false>;
export { type ModuleOptions, _default as default };
+428
View File
@@ -0,0 +1,428 @@
import { NuxtModule } from '@nuxt/schema';
import { MaybeRef, VueInstance } from '@vueuse/core';
import { CSSProperties, Ref, UnwrapRef } from 'vue';
type ResolvedKeyframesTarget = [null, ...number[]] | number[] | [null, ...string[]] | string[];
type KeyframesTarget = ResolvedKeyframesTarget | [null, ...CustomValueType[]] | CustomValueType[];
type ResolvedSingleTarget = string | number;
type SingleTarget = ResolvedSingleTarget | CustomValueType;
type ValueTarget = SingleTarget | KeyframesTarget;
type EasingFunction = (v: number) => number;
type Easing = [number, number, number, number] | 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' | 'circIn' | 'circOut' | 'circInOut' | 'backIn' | 'backOut' | 'backInOut' | 'anticipate' | EasingFunction;
interface Orchestration {
/**
* Delay the animation by this duration (in seconds). Defaults to `0`.
*/
delay?: number;
/**
* Callback triggered on animation complete.
*/
onComplete?: () => void;
/**
* Should the value be set imediately
*/
immediate?: boolean;
}
interface Repeat {
/**
* The number of times to repeat the transition. Set to `Infinity` for perpetual repeating.
*
* Without setting `repeatType`, this will loop the animation.
*/
repeat?: number;
/**
* How to repeat the animation. This can be either:
*
* "loop": Repeats the animation from the start
*
* "reverse": Alternates between forward and backwards playback
*
* "mirror": Switchs `from` and `to` alternately
*/
repeatType?: 'loop' | 'reverse' | 'mirror';
/**
* When repeating an animation, `repeatDelay` will set the
* duration of the time to wait, in seconds, between each repetition.
*/
repeatDelay?: number;
}
/**
* An animation that animates between two or more values over a specific duration of time.
* This is the default animation for non-physical values like `color` and `opacity`.
*/
interface Tween extends Repeat {
/**
* Set `type` to `"tween"` to use a duration-based tween animation.
* If any non-orchestration `transition` values are set without a `type` property,
* this is used as the default animation.
*/
type?: 'tween';
/**
* The duration of the tween animation. Set to `0.3` by default, 0r `0.8` if animating a series of keyframes.
*/
duration?: number;
/**
* The easing function to use. Set as one of the below.
*
* - The name of an existing easing function.
* - An array of four numbers to define a cubic bezier curve.
* - An easing function, that accepts and returns a value `0-1`.
*
* If the animating value is set as an array of multiple values for a keyframes
* animation, `ease` can be set as an array of easing functions to set different easings between
* each of those values.
*/
ease?: Easing | Easing[];
/**
* The duration of time already elapsed in the animation. Set to `0` by
* default.
*/
elapsed?: number;
/**
* When animating keyframes, `times` can be used to determine where in the animation each keyframe is reached.
* Each value in `times` is a value between `0` and `1`, representing `duration`.
*
* There must be the same number of `times` as there are keyframes.
* Defaults to an array of evenly-spread durations.
*/
times?: number[];
/**
* When animating keyframes, `easings` can be used to define easing functions between each keyframe. This array should be one item fewer than the number of keyframes, as these easings apply to the transitions between the keyframes.
*/
easings?: Easing[];
/**
* The value to animate from.
* By default, this is the current state of the animating value.
*/
from?: number | string;
to?: number | string | ValueTarget;
velocity?: number;
delay?: number;
}
/**
* An animation that simulates spring physics for realistic motion.
* This is the default animation for physical values like `x`, `y`, `scale` and `rotate`.
*/
interface Spring extends Repeat {
/**
* Set `type` to `"spring"` to animate using spring physics for natural
* movement. Type is set to `"spring"` by default.
*/
type: 'spring';
/**
* Stiffness of the spring. Higher values will create more sudden movement.
* Set to `100` by default.
*/
stiffness?: number;
/**
* Strength of opposing force. If set to 0, spring will oscillate
* indefinitely. Set to `10` by default.
*/
damping?: number;
/**
* Mass of the moving object. Higher values will result in more lethargic
* movement. Set to `1` by default.
*/
mass?: number;
/**
* The duration of the animation, defined in seconds. Spring animations can be a maximum of 10 seconds.
*
* If `bounce` is set, this defaults to `0.8`.
*
* Note: `duration` and `bounce` will be overridden if `stiffness`, `damping` or `mass` are set.
*/
duration?: number;
/**
* `bounce` determines the "bounciness" of a spring animation.
*
* `0` is no bounce, and `1` is extremely bouncy.
*
* If `duration` is set, this defaults to `0.25`.
*
* Note: `bounce` and `duration` will be overridden if `stiffness`, `damping` or `mass` are set.
*/
bounce?: number;
/**
* End animation if absolute speed (in units per second) drops below this
* value and delta is smaller than `restDelta`. Set to `0.01` by default.
*/
restSpeed?: number;
/**
* End animation if distance is below this value and speed is below
* `restSpeed`. When animation ends, spring gets “snapped” to. Set to
* `0.01` by default.
*/
restDelta?: number;
/**
* The value to animate from.
* By default, this is the initial state of the animating value.
*/
from?: number | string;
to?: number | string | ValueTarget;
/**
* The initial velocity of the spring. By default this is the current velocity of the component.
*/
velocity?: number;
delay?: number;
}
/**
* An animation that decelerates a value based on its initial velocity,
* usually used to implement inertial scrolling.
*
* Optionally, `min` and `max` boundaries can be defined, and inertia
* will snap to these with a spring animation.
*
* This animation will automatically precalculate a target value,
* which can be modified with the `modifyTarget` property.
*
* This allows you to add snap-to-grid or similar functionality.
*
* Inertia is also the animation used for `dragTransition`, and can be configured via that prop.
*/
interface Inertia {
/**
* Set `type` to animate using the inertia animation. Set to `"tween"` by
* default. This can be used for natural deceleration, like momentum scrolling.
*/
type: 'inertia';
/**
* A function that receives the automatically-calculated target and returns a new one. Useful for snapping the target to a grid.
*/
modifyTarget?: (v: number) => number;
/**
* If `min` or `max` is set, this affects the stiffness of the bounce
* spring. Higher values will create more sudden movement. Set to `500` by
* default.
*/
bounceStiffness?: number;
/**
* If `min` or `max` is set, this affects the damping of the bounce spring.
* If set to `0`, spring will oscillate indefinitely. Set to `10` by
* default.
*/
bounceDamping?: number;
/**
* A higher power value equals a further target. Set to `0.8` by default.
*/
power?: number;
/**
* Adjusting the time constant will change the duration of the
* deceleration, thereby affecting its feel. Set to `700` by default.
*/
timeConstant?: number;
/**
* End the animation if the distance to the animation target is below this value, and the absolute speed is below `restSpeed`.
* When the animation ends, the value gets snapped to the animation target. Set to `0.01` by default.
* Generally the default values provide smooth animation endings, only in rare cases should you need to customize these.
*/
restDelta?: number;
/**
* Minimum constraint. If set, the value will "bump" against this value (or immediately spring to it if the animation starts as less than this value).
*/
min?: number;
/**
* Maximum constraint. If set, the value will "bump" against this value (or immediately snap to it, if the initial animation value exceeds this value).
*/
max?: number;
/**
* The value to animate from. By default, this is the current state of the animating value.
*/
from?: number | string;
/**
* The initial velocity of the animation.
* By default this is the current velocity of the component.
*/
velocity?: number;
delay?: number;
}
/**
* Keyframes tweens between multiple `values`.
*
* These tweens can be arranged using the `duration`, `easings`, and `times` properties.
*/
interface Keyframes {
/**
* Set `type` to `"keyframes"` to animate using the keyframes animation.
* Set to `"tween"` by default. This can be used to animate between a series of values.
*/
type: 'keyframes';
/**
* An array of values to animate between.
*/
values: KeyframesTarget;
/**
* An array of numbers between 0 and 1, where `1` represents the `total` duration.
*
* Each value represents at which point during the animation each item in the animation target should be hit, so the array should be the same length as `values`.
*
* Defaults to an array of evenly-spread durations.
*/
times?: number[];
/**
* An array of easing functions for each generated tween, or a single easing function applied to all tweens.
*
* This array should be one item less than `values`, as these easings apply to the transitions *between* the `values`.
*/
ease?: Easing | Easing[];
/**
* Popmotion's easing prop to define individual easings. `ease` will be mapped to this prop in keyframes animations.
*/
easings?: Easing | Easing[];
elapsed?: number;
/**
* The total duration of the animation. Set to `0.3` by default.
*/
duration?: number;
repeatDelay?: number;
from?: number | string;
to?: number | string | ValueTarget;
velocity?: number;
delay?: number;
}
type PermissiveTransitionDefinition = Record<string, any>;
type TransitionDefinition = Tween | Spring | Keyframes | Inertia | PermissiveTransitionDefinition;
type TransitionMap = Orchestration & Record<string, TransitionDefinition>;
/**
* Transition props
*/
type Transition = (Orchestration & Repeat & TransitionDefinition) | (Orchestration & Repeat & TransitionMap);
interface CustomValueType {
mix: (from: any, to: any) => (p: number) => number | string;
toValue: () => number | string;
}
/**
* SVG Supported properties
*/
interface SVGPathProperties {
pathLength?: number;
pathOffset?: number;
pathSpacing?: number;
}
/**
* Transform properties
*/
type TransformValue = string | number;
interface TransformProperties {
x?: TransformValue | TransformValue[];
y?: TransformValue | TransformValue[];
z?: TransformValue | TransformValue[];
translateX?: TransformValue | TransformValue[];
translateY?: TransformValue | TransformValue[];
translateZ?: TransformValue | TransformValue[];
rotate?: TransformValue | TransformValue[];
rotateX?: TransformValue | TransformValue[];
rotateY?: TransformValue | TransformValue[];
rotateZ?: TransformValue | TransformValue[];
scale?: TransformValue | TransformValue[];
scaleX?: TransformValue | TransformValue[];
scaleY?: TransformValue | TransformValue[];
scaleZ?: TransformValue | TransformValue[];
skew?: TransformValue | TransformValue[];
skewX?: TransformValue | TransformValue[];
skewY?: TransformValue | TransformValue[];
originX?: TransformValue | TransformValue[];
originY?: TransformValue | TransformValue[];
originZ?: TransformValue | TransformValue[];
perspective?: TransformValue | TransformValue[];
transformPerspective?: TransformValue | TransformValue[];
}
/**
* Relevant styling properties
*/
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type StyleProperties = Omit<CSSProperties, 'transition' | 'rotate' | 'scale' | 'perspective' | 'transform' | 'transformBox' | 'transformOrigin' | 'transformStyle'>;
/**
* Available properties for useMotion variants
*/
type MotionProperties = StyleProperties | TransformProperties | SVGPathProperties;
/**
* Variant
*/
type Variant = {
transition?: Transition;
} & MotionProperties;
/**
* Motion variants object
*/
type MotionVariants<T extends string> = {
initial?: Variant;
enter?: Variant;
leave?: Variant;
visible?: Variant;
visibleOnce?: Variant;
hovered?: Variant;
tapped?: Variant;
focused?: Variant;
} & {
[key in T]?: Variant;
};
type PermissiveTarget = VueInstance | MotionTarget;
type MotionTarget = HTMLElement | SVGElement | null | undefined;
interface MotionInstance<T extends string, V extends MotionVariants<T>> extends MotionControls<T, V> {
target: MaybeRef<PermissiveTarget>;
variants: MaybeRef<V>;
variant: Ref<keyof V>;
state: Ref<Variant | undefined>;
motionProperties: UnwrapRef<MotionProperties>;
}
interface MotionControls<T extends string, V extends MotionVariants<T>> {
/**
* Apply a variant declaration and execute the resolved transitions.
*
* @param variant
* @returns Promise<void[]>
*/
apply: (variant: Variant | keyof V) => Promise<void[]> | undefined;
/**
* Apply a variant declaration without transitions.
*
* @param variant
*/
set: (variant: Variant | keyof V) => void;
/**
* Stop all the ongoing transitions for the current element.
*/
stop: (keys?: string | string[]) => void;
/**
* Helper to be passed to <transition> leave event.
*
* @param done
*/
leave: (done: () => void) => void;
/**
* Computed reference reactive to the animation state of motion controls.
*/
isAnimating: any;
}
type MotionInstanceBindings<T extends string, V extends MotionVariants<T>> = Record<string, MotionInstance<T, V>>;
declare module 'vue' {
interface ComponentCustomProperties {
$motions?: MotionInstanceBindings<any, any>;
}
}
declare module '@vue/runtime-dom' {
interface HTMLAttributes {
variants?: MotionVariants<any>;
initial?: Variant;
enter?: Variant;
leave?: Variant;
visible?: Variant;
visibleOnce?: Variant;
hovered?: Variant;
tapped?: Variant;
focused?: Variant;
}
}
interface ModuleOptions$1<T extends string> {
directives?: Record<T, MotionVariants<T>>;
excludePresets?: boolean;
}
interface ModuleOptions extends ModuleOptions$1<string> {
}
declare const _default: NuxtModule<ModuleOptions, ModuleOptions, false>;
export { type ModuleOptions, _default as default };
+8
View File
@@ -0,0 +1,8 @@
{
"name": "@vueuse/motion",
"configKey": "motion",
"builder": {
"@nuxt/module-builder": "0.8.3",
"unbuild": "2.0.0"
}
}
+35
View File
@@ -0,0 +1,35 @@
import { defu } from 'defu';
import { defineNuxtModule, createResolver, addPlugin, addImportsDir, addComponent } from '@nuxt/kit';
const module = defineNuxtModule({
meta: {
name: "@vueuse/motion",
configKey: "motion"
},
defaults: {},
setup(options, nuxt) {
const { resolve } = createResolver(import.meta.url);
nuxt.options.runtimeConfig.public.motion = defu(nuxt.options.runtimeConfig.public.motion || {}, options);
addPlugin(resolve("./runtime/templates/motion"));
addImportsDir(resolve("./runtime/composables"));
addComponent({
name: "Motion",
export: "MotionComponent",
filePath: "@vueuse/motion"
});
addComponent({
name: "MotionGroup",
export: "MotionGroupComponent",
filePath: "@vueuse/motion"
});
if (!nuxt.options.build.transpile)
nuxt.options.build.transpile = [];
const transpileList = ["defu", "@vueuse/motion", "@vueuse/shared", "@vueuse/core"];
transpileList.forEach((pkgName) => {
if (!nuxt.options.build.transpile.includes(pkgName))
nuxt.options.build.transpile.push(pkgName);
});
}
});
export { module as default };
@@ -0,0 +1,12 @@
export { reactiveStyle } from '@vueuse/motion';
export { reactiveTransform } from '@vueuse/motion';
export { useElementStyle } from '@vueuse/motion';
export { useElementTransform } from '@vueuse/motion';
export { useMotion } from '@vueuse/motion';
export { useMotionControls } from '@vueuse/motion';
export { useMotionProperties } from '@vueuse/motion';
export { useMotions } from '@vueuse/motion';
export { useMotionTransitions } from '@vueuse/motion';
export { useMotionVariants } from '@vueuse/motion';
export { useSpring } from '@vueuse/motion';
export { useReducedMotion } from '@vueuse/motion';
@@ -0,0 +1,12 @@
export { reactiveStyle } from "@vueuse/motion";
export { reactiveTransform } from "@vueuse/motion";
export { useElementStyle } from "@vueuse/motion";
export { useElementTransform } from "@vueuse/motion";
export { useMotion } from "@vueuse/motion";
export { useMotionControls } from "@vueuse/motion";
export { useMotionProperties } from "@vueuse/motion";
export { useMotions } from "@vueuse/motion";
export { useMotionTransitions } from "@vueuse/motion";
export { useMotionVariants } from "@vueuse/motion";
export { useSpring } from "@vueuse/motion";
export { useReducedMotion } from "@vueuse/motion";
@@ -0,0 +1,4 @@
import type { Plugin } from 'nuxt/app'
declare const plugin: Plugin<Record<string, unknown>>
export default plugin
@@ -0,0 +1,8 @@
import { MotionPlugin } from "@vueuse/motion";
import { defineNuxtPlugin, useRuntimeConfig } from "#imports";
export default defineNuxtPlugin(
(nuxtApp) => {
const config = useRuntimeConfig();
nuxtApp.vueApp.use(MotionPlugin, config.public.motion);
}
);
+1
View File
@@ -0,0 +1 @@
export { type ModuleOptions, default } from './module.js'
+1
View File
@@ -0,0 +1 @@
export { type ModuleOptions, default } from './module'
@@ -0,0 +1,21 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
@@ -0,0 +1,15 @@
# Installation
> `npm install --save @types/web-bluetooth`
# Summary
This package contains type definitions for web-bluetooth (https://webbluetoothcg.github.io/web-bluetooth/).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/web-bluetooth.
### Additional Details
* Last updated: Tue, 07 Nov 2023 15:11:36 GMT
* Dependencies: none
# Credits
These definitions were written by [Uri Shaked](https://github.com/urish), [Xavier Lozinguez](https://github.com/xlozinguez), [Rob Moran](https://github.com/thegecko), and [David Bjerremose](https://github.com/DaBs).
@@ -0,0 +1,193 @@
type BluetoothServiceUUID = number | string;
type BluetoothCharacteristicUUID = number | string;
type BluetoothDescriptorUUID = number | string;
type BluetoothManufacturerData = Map<number, DataView>;
type BluetoothServiceData = Map<BluetoothServiceUUID, DataView>;
interface BluetoothDataFilter {
readonly dataPrefix?: BufferSource | undefined;
readonly mask?: BufferSource | undefined;
}
interface BluetoothManufacturerDataFilter extends BluetoothDataFilter {
companyIdentifier: number;
}
interface BluetoothServiceDataFilter extends BluetoothDataFilter {
service: BluetoothServiceUUID;
}
interface BluetoothLEScanFilter {
readonly name?: string | undefined;
readonly namePrefix?: string | undefined;
readonly services?: BluetoothServiceUUID[] | undefined;
readonly manufacturerData?: BluetoothManufacturerDataFilter[] | undefined;
readonly serviceData?: BluetoothServiceDataFilter[] | undefined;
}
interface BluetoothLEScanOptions {
readonly filters?: BluetoothLEScanFilter[] | undefined;
readonly keepRepeatedDevices?: boolean | undefined;
readonly acceptAllAdvertisements?: boolean | undefined;
}
interface BluetoothLEScan extends BluetoothLEScanOptions {
active: boolean;
stop: () => void;
}
type RequestDeviceOptions = {
filters: BluetoothLEScanFilter[];
optionalServices?: BluetoothServiceUUID[] | undefined;
optionalManufacturerData?: number[] | undefined;
} | {
acceptAllDevices: boolean;
optionalServices?: BluetoothServiceUUID[] | undefined;
optionalManufacturerData?: number[] | undefined;
};
interface BluetoothAdvertisingEvent extends Event {
readonly device: BluetoothDevice;
readonly uuids: BluetoothServiceUUID[];
readonly manufacturerData: BluetoothManufacturerData;
readonly serviceData: BluetoothServiceData;
readonly name?: string | undefined;
readonly appearance?: number | undefined;
readonly rssi?: number | undefined;
readonly txPower?: number | undefined;
}
interface BluetoothRemoteGATTDescriptor {
readonly characteristic: BluetoothRemoteGATTCharacteristic;
readonly uuid: string;
readonly value?: DataView | undefined;
readValue(): Promise<DataView>;
writeValue(value: BufferSource): Promise<void>;
}
interface BluetoothCharacteristicProperties {
readonly broadcast: boolean;
readonly read: boolean;
readonly writeWithoutResponse: boolean;
readonly write: boolean;
readonly notify: boolean;
readonly indicate: boolean;
readonly authenticatedSignedWrites: boolean;
readonly reliableWrite: boolean;
readonly writableAuxiliaries: boolean;
}
interface CharacteristicEventHandlers {
oncharacteristicvaluechanged: (this: this, ev: Event) => any;
}
interface BluetoothRemoteGATTCharacteristic extends EventTarget, CharacteristicEventHandlers {
readonly service: BluetoothRemoteGATTService;
readonly uuid: string;
readonly properties: BluetoothCharacteristicProperties;
readonly value?: DataView | undefined;
getDescriptor(descriptor: BluetoothDescriptorUUID): Promise<BluetoothRemoteGATTDescriptor>;
getDescriptors(descriptor?: BluetoothDescriptorUUID): Promise<BluetoothRemoteGATTDescriptor[]>;
readValue(): Promise<DataView>;
writeValue(value: BufferSource): Promise<void>;
writeValueWithResponse(value: BufferSource): Promise<void>;
writeValueWithoutResponse(value: BufferSource): Promise<void>;
startNotifications(): Promise<BluetoothRemoteGATTCharacteristic>;
stopNotifications(): Promise<BluetoothRemoteGATTCharacteristic>;
addEventListener(
type: "characteristicvaluechanged",
listener: (this: this, ev: Event) => any,
useCapture?: boolean,
): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
interface ServiceEventHandlers {
onserviceadded: (this: this, ev: Event) => any;
onservicechanged: (this: this, ev: Event) => any;
onserviceremoved: (this: this, ev: Event) => any;
}
interface BluetoothRemoteGATTService extends EventTarget, CharacteristicEventHandlers, ServiceEventHandlers {
readonly device: BluetoothDevice;
readonly uuid: string;
readonly isPrimary: boolean;
getCharacteristic(characteristic: BluetoothCharacteristicUUID): Promise<BluetoothRemoteGATTCharacteristic>;
getCharacteristics(characteristic?: BluetoothCharacteristicUUID): Promise<BluetoothRemoteGATTCharacteristic[]>;
getIncludedService(service: BluetoothServiceUUID): Promise<BluetoothRemoteGATTService>;
getIncludedServices(service?: BluetoothServiceUUID): Promise<BluetoothRemoteGATTService[]>;
addEventListener(type: "serviceadded", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "servicechanged", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "serviceremoved", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
interface BluetoothRemoteGATTServer {
readonly device: BluetoothDevice;
readonly connected: boolean;
connect(): Promise<BluetoothRemoteGATTServer>;
disconnect(): void;
getPrimaryService(service: BluetoothServiceUUID): Promise<BluetoothRemoteGATTService>;
getPrimaryServices(service?: BluetoothServiceUUID): Promise<BluetoothRemoteGATTService[]>;
}
interface BluetoothDeviceEventHandlers {
onadvertisementreceived: (this: this, ev: BluetoothAdvertisingEvent) => any;
ongattserverdisconnected: (this: this, ev: Event) => any;
}
interface WatchAdvertisementsOptions {
signal?: AbortSignal;
}
interface BluetoothDevice
extends EventTarget, BluetoothDeviceEventHandlers, CharacteristicEventHandlers, ServiceEventHandlers
{
readonly id: string;
readonly name?: string | undefined;
readonly gatt?: BluetoothRemoteGATTServer | undefined;
forget(): Promise<void>;
watchAdvertisements(options?: WatchAdvertisementsOptions): Promise<void>;
readonly watchingAdvertisements: boolean;
addEventListener(
type: "gattserverdisconnected",
listener: (this: this, ev: Event) => any,
useCapture?: boolean,
): void;
addEventListener(
type: "advertisementreceived",
listener: (this: this, ev: BluetoothAdvertisingEvent) => any,
useCapture?: boolean,
): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
interface Bluetooth
extends EventTarget, BluetoothDeviceEventHandlers, CharacteristicEventHandlers, ServiceEventHandlers
{
getDevices(): Promise<BluetoothDevice[]>;
getAvailability(): Promise<boolean>;
onavailabilitychanged: (this: this, ev: Event) => any;
readonly referringDevice?: BluetoothDevice | undefined;
requestDevice(options?: RequestDeviceOptions): Promise<BluetoothDevice>;
requestLEScan(options?: BluetoothLEScanOptions): Promise<BluetoothLEScan>;
addEventListener(type: "availabilitychanged", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(
type: "advertisementreceived",
listener: (this: this, ev: BluetoothAdvertisingEvent) => any,
useCapture?: boolean,
): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
declare namespace BluetoothUUID {
function getService(name: string | number): string;
function getCharacteristic(name: string | number): string;
function getDescriptor(name: string | number): string;
function canonicalUUID(alias: string | number): string;
}
interface Navigator {
bluetooth: Bluetooth;
}
@@ -0,0 +1,40 @@
{
"name": "@types/web-bluetooth",
"version": "0.0.20",
"description": "TypeScript definitions for web-bluetooth",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/web-bluetooth",
"license": "MIT",
"contributors": [
{
"name": "Uri Shaked",
"githubUsername": "urish",
"url": "https://github.com/urish"
},
{
"name": "Xavier Lozinguez",
"githubUsername": "xlozinguez",
"url": "https://github.com/xlozinguez"
},
{
"name": "Rob Moran",
"githubUsername": "thegecko",
"url": "https://github.com/thegecko"
},
{
"name": "David Bjerremose",
"githubUsername": "DaBs",
"url": "https://github.com/DaBs"
}
],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/web-bluetooth"
},
"scripts": {},
"dependencies": {},
"typesPublisherContentHash": "6a130e3db86a1d977ddff03e84f9f150c142902343c9fa383d3e8d4f19180d98",
"typeScriptVersion": "4.5"
}
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019-PRESENT Anthony Fu<https://github.com/antfu>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,124 @@
<p align="center">
<a href="https://github.com/vueuse/vueuse#gh-light-mode-only">
<img src="https://raw.githubusercontent.com/vueuse/vueuse/main/packages/public/logo-vertical.png#gh-light-mode-only" alt="VueUse - Collection of essential Vue Composition Utilities" width="300">
</a>
<a href="https://github.com/vueuse/vueuse#gh-dark-mode-only">
<img src="https://raw.githubusercontent.com/vueuse/vueuse/main/packages/public/logo-vertical-dark.png#gh-dark-mode-only" alt="VueUse - Collection of essential Vue Composition Utilities" width="300">
</a>
<br>
Collection of essential Vue Composition Utilities
</p>
<p align="center">
<a href="https://www.npmjs.com/package/@vueuse/core" target="__blank"><img src="https://img.shields.io/npm/v/@vueuse/core?color=a1b858&label=" alt="NPM version"></a>
<a href="https://www.npmjs.com/package/@vueuse/core" target="__blank"><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/@vueuse/core?color=50a36f&label="></a>
<a href="https://vueuse.org" target="__blank"><img src="https://img.shields.io/static/v1?label=&message=docs%20%26%20demos&color=1e8a7a" alt="Docs & Demos"></a>
<img alt="Function Count" src="https://vueuse.org/badge-function-count.svg">
<br>
<a href="https://github.com/vueuse/vueuse" target="__blank"><img alt="GitHub stars" src="https://img.shields.io/github/stars/vueuse/vueuse?style=social"></a>
</p>
<p align="center">
<a href="https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg">
<img src='https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg'>
</a>
</p>
## 🚀 Features
- 🎪 [**Interactive docs & demos**](https://vueuse.org)
- 🕶 **Seamless migration**: Works for **both** Vue 3 and 2
- ⚡ **Fully tree shakeable**: Only take what you want, [bundle size](https://vueuse.org/export-size)
- 🦾 **Type Strong**: Written in [TypeScript](https://www.typescriptlang.org/), with [TS Docs](https://github.com/microsoft/tsdoc)
- 🔋 **SSR Friendly**
- 🌎 **No bundler required**: Usable via CDN
- 🔩 **Flexible**: Configurable event filters and targets
- 🔌 **Optional [Add-ons](https://vueuse.org/add-ons)**: Router, Firebase, RxJS, etc.
## 🦄 Usage
```ts
import { useLocalStorage, useMouse, usePreferredDark } from '@vueuse/core'
export default {
setup() {
// tracks mouse position
const { x, y } = useMouse()
// if user prefers dark theme
const isDark = usePreferredDark()
// persist state in localStorage
const store = useLocalStorage(
'my-storage',
{
name: 'Apple',
color: 'red',
},
)
return { x, y, isDark, store }
},
}
```
Refer to [functions list](https://vueuse.org/functions) or [documentations](https://vueuse.org/) for more details.
## 📦 Install
> 🎩 From v4.0, it works for Vue 2 & 3 **within a single package** by the power of [vue-demi](https://github.com/vueuse/vue-demi)!
```bash
npm i @vueuse/core
```
[Add ons](https://vueuse.org/add-ons.html) | [Nuxt Module](https://vueuse.org/guide/index.html#nuxt)
> From v6.0, VueUse requires `vue` >= v3.2 or `@vue/composition-api` >= v1.1
###### Demos
- [Vite + Vue 3](https://github.com/vueuse/vueuse-vite-starter)
- [Nuxt 3 + Vue 3](https://github.com/antfu/vitesse-nuxt3)
- [Webpack + Vue 3](https://github.com/vueuse/vueuse-vue3-example)
- [Nuxt 2 + Vue 2](https://github.com/antfu/vitesse-nuxt-bridge)
- [Vue CLI + Vue 2](https://github.com/vueuse/vueuse-vue2-example)
### CDN
```vue
<script src="https://unpkg.com/@vueuse/shared"></script>
<script src="https://unpkg.com/@vueuse/core"></script>
```
It will be exposed to global as `window.VueUse`
## 🪴 Project Activity
![Alt](https://repobeats.axiom.co/api/embed/a406ba7461a6a087dbdb14d4395046c948d44c51.svg 'Repobeats analytics image')
## 🧱 Contribute
See the [**Contributing Guide**](https://vueuse.org/contributing)
## 🌸 Thanks
This project is heavily inspired by the following awesome projects.
- [streamich/react-use](https://github.com/streamich/react-use)
- [u3u/vue-hooks](https://github.com/u3u/vue-hooks)
- [logaretm/vue-use-web](https://github.com/logaretm/vue-use-web)
- [kripod/react-hooks](https://github.com/kripod/react-hooks)
And thanks to [all the contributors on GitHub](https://github.com/vueuse/vueuse/graphs/contributors)!
## 👨‍🚀 Contributors
### Financial Contributors on Open Collective
<a href="https://opencollective.com/vueuse"><img src="https://opencollective.com/vueuse/individuals.svg?width=890"></a>
## 📄 License
[MIT License](https://github.com/vueuse/vueuse/blob/main/LICENSE) © 2019-PRESENT [Anthony Fu](https://github.com/antfu)
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -0,0 +1 @@
module.exports = require('@vueuse/metadata')
@@ -0,0 +1 @@
export * from '@vueuse/metadata'
@@ -0,0 +1 @@
export * from '@vueuse/metadata'
@@ -0,0 +1 @@
export * from '@vueuse/metadata'
@@ -0,0 +1 @@
export * from '@vueuse/metadata'
@@ -0,0 +1 @@
../vue-demi/bin/vue-demi-fix.js
@@ -0,0 +1 @@
../vue-demi/bin/vue-demi-switch.js
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-present, Anthony Fu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,229 @@
<p align="center">
<img src="https://github.com/vueuse/vue-demi/blob/main/assets/banner.png?raw=true" width="600"/>
<br>
<a href='https://www.npmjs.com/package/vue-demi'><img src='https://img.shields.io/npm/v/vue-demi?color=42b883' alt='npm'></a>
</p>
<p align="center">
<b>Vue Demi</b> (<i>half</i> in French) is a developing utility<br> allows you to write <b>Universal Vue Libraries</b> for Vue 2 & 3<br>
<i>See more details in <a href='https://antfu.me/posts/make-libraries-working-with-vue-2-and-3'>this blog post</a></i>
</p>
<br>
<br>
## Strategies
- `<=2.6`: exports from `vue` + `@vue/composition-api` with plugin auto installing.
- `2.7`: exports from `vue` (Composition API is built-in in Vue 2.7).
- `>=3.0`: exports from `vue`, with polyfill of Vue 2's `set` and `del` API.
## Usage
Install this as your plugin's dependency:
```bash
npm i vue-demi
# or
yarn add vue-demi
# or
pnpm i vue-demi
```
Add `vue` and `@vue/composition-api` to your plugin's peer dependencies to specify what versions you support.
```jsonc
{
"dependencies": {
"vue-demi": "latest"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^2.0.0 || >=3.0.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
},
"devDependencies": {
"vue": "^3.0.0" // or "^2.6.0" base on your preferred working environment
},
}
```
Import everything related to Vue from it, it will redirect to `vue@2` + `@vue/composition-api` or `vue@3` based on users' environments.
```ts
import { ref, reactive, defineComponent } from 'vue-demi'
```
Publish your plugin and all is done!
> When using with [Vite](https://vitejs.dev), you will need to opt-out the pre-bundling to get `vue-demi` work properly by
> ```js
> // vite.config.js
> export default defineConfig({
> optimizeDeps: {
> exclude: ['vue-demi']
> }
> })
> ```
### Extra APIs
`Vue Demi` provides extra APIs to help distinguish users' environments and to do some version-specific logic.
### `isVue2` `isVue3`
```ts
import { isVue2, isVue3 } from 'vue-demi'
if (isVue2) {
// Vue 2 only
} else {
// Vue 3 only
}
```
### `Vue2`
To avoid bringing in all the tree-shakable modules, we provide a `Vue2` export to support access to Vue 2's global API. (See [#41](https://github.com/vueuse/vue-demi/issues/41).)
```ts
import { Vue2 } from 'vue-demi'
if (Vue2) {
Vue2.config.ignoredElements.push('x-foo')
}
```
### `install()`
Composition API in Vue 2 is provided as a plugin and needs to be installed on the Vue instance before using. Normally, `vue-demi` will try to install it automatically. For some usages where you might need to ensure the plugin gets installed correctly, the `install()` API is exposed to as a safe version of `Vue.use(CompositionAPI)`. `install()` in the Vue 3 environment will be an empty function (no-op).
```ts
import { install } from 'vue-demi'
install()
```
## CLI
### Manually Switch Versions
To explicitly switch the redirecting version, you can use these commands in your project's root.
```bash
npx vue-demi-switch 2
# or
npx vue-demi-switch 3
```
### Package Aliasing
If you would like to import `vue` under an alias, you can use the following command
```bash
npx vue-demi-switch 2 vue2
# or
npx vue-demi-switch 3 vue3
```
Then `vue-demi` will redirect APIs from the alias name you specified, for example:
```ts
import * as Vue from 'vue3'
var isVue2 = false
var isVue3 = true
var Vue2 = undefined
export * from 'vue3'
export {
Vue,
Vue2,
isVue2,
isVue3,
}
```
### Auto Fix
If the `postinstall` hook doesn't get triggered or you have updated the Vue version, try to run the following command to resolve the redirecting.
```bash
npx vue-demi-fix
```
### Isomorphic Testings
You can support testing for both versions by adding npm alias in your dev dependencies. For example:
```json
{
"scripts": {
"test:2": "vue-demi-switch 2 vue2 && jest",
"test:3": "vue-demi-switch 3 && jest",
},
"devDependencies": {
"vue": "^3.0.0",
"vue2": "npm:vue@2"
},
}
```
or
```json
{
"scripts": {
"test:2": "vue-demi-switch 2 && jest",
"test:3": "vue-demi-switch 3 vue3 && jest",
},
"devDependencies": {
"vue": "^2.6.0",
"vue3": "npm:vue@3"
},
}
```
## Examples
See [examples](./examples).
## Who is using this?
- [VueUse](https://github.com/vueuse/vueuse) - Collection of Composition API utils
- [@vue/apollo-composable](https://github.com/vuejs/vue-apollo/tree/v4/packages/vue-apollo-composable) - Apollo GraphQL functions for Vue Composition API
- [vuelidate](https://github.com/vuelidate/vuelidate) - Simple, lightweight model-based validation
- [vue-composition-test-utils](https://github.com/ariesjia/vue-composition-test-utils) - Simple vue composition api unit test utilities
- [vue-use-stripe](https://github.com/frandiox/vue-use-stripe) - Stripe Elements wrapper for Vue.js
- [@opd/g2plot-vue](https://github.com/open-data-plan/g2plot-vue) - G2plot for vue
- [vue-echarts](https://github.com/ecomfe/vue-echarts) - Vue.js component for Apache ECharts.
- [fluent-vue](https://github.com/Demivan/fluent-vue) - Vue.js integration for [Fluent.js](https://github.com/projectfluent/fluent.js) - JavaScript implementation of [Project Fluent](https://projectfluent.org)
- [vue-datatable-url-sync](https://github.com/socotecio/vue-datatable-url-sync) - Synchronize datatable options and filters with the url to keep user preference even after refresh or navigation
- [vue-insta-stories](https://github.com/UnevenSoftware/vue-insta-stories) - Instagram stories in your vue projects.
- [vue-tiny-validate](https://github.com/FrontLabsOfficial/vue-tiny-validate) - Tiny Vue Validate Composition
- [v-perfect-signature](https://github.com/wobsoriano/v-perfect-signature) - Pressure-sensitive signature drawing for Vue 2 and 3
- [vue-winbox](https://github.com/wobsoriano/vue-winbox) - A wrapper component for WinBox.js that adds the ability to mount Vue components.
- [vue-word-highlighter](https://github.com/kawamataryo/vue-word-highlighter) - The word highlighter library for Vue 2 and Vue 3
- [vue-chart-3](https://github.com/victorgarciaesgi/vue-chart-3) - Vue.js component for Chart.js
- [json-editor-vue](https://github.com/cloydlau/json-editor-vue) - JSON editor & viewer for Vue 2 and 3.
- [kidar-echarts](https://github.com/kidarjs/kidar-echarts) - A simpler echarts component for Vue 2 and 3.
- [vue3-sketch-ruler](https://github.com/kakajun/vue3-sketch-ruler) - The zoom operation used for page presentation for Vue 2 and 3( Replace render function with template )
- [vue-rough-notation](https://github.com/Leecason/vue-rough-notation) - RoughNotation wrapper component for Vue 2 and 3.
- [vue-request](https://github.com/AttoJS/vue-request) - Vue composition API for data fetching, supports SWR, polling, error retry, cache request, pagination, etc.
- [vue3-lazyload](https://github.com/murongg/vue3-lazyload) - A vue3.x image lazyload plugin.
- [vue-codemirror6](https://github.com/logue/vue-codemirror6) - CodeMirror6 component for Vue2 and 3.
- [@tanstack/vue-query](https://github.com/TanStack/query) - TanStack Query for Vue.
> open a PR to add your library ;)
## Underhood
See [the blog post](https://antfu.me/posts/make-libraries-working-with-vue-2-and-3/#-introducing-vue-demi).
## License
MIT License © 2020 [Anthony Fu](https://github.com/antfu)
@@ -0,0 +1,3 @@
#!/usr/bin/env node
'use strict'
require('../scripts/postinstall')
@@ -0,0 +1,3 @@
#!/usr/bin/env node
'use strict'
require('../scripts/switch-cli')
@@ -0,0 +1,29 @@
var Vue = require('vue')
Object.keys(Vue).forEach(function(key) {
exports[key] = Vue[key]
})
exports.set = function(target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
target[key] = val
return val
}
exports.del = function(target, key) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
delete target[key]
}
exports.Vue = Vue
exports.Vue2 = undefined
exports.isVue2 = false
exports.isVue3 = true
exports.install = function(){}
@@ -0,0 +1,22 @@
import * as Vue from 'vue'
declare const isVue2: boolean
declare const isVue3: boolean
declare const Vue2: any
declare const install: (vue?: any) => void
/**
* @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead.
* Refer to https://github.com/vueuse/vue-demi/issues/41
*/
declare const V: typeof Vue
export function set<T>(target: any, key: any, val: T): T
export function del(target: any, key: any): void
export * from 'vue'
export {
V as Vue,
Vue2,
isVue2,
isVue3,
install,
}
@@ -0,0 +1,126 @@
var _VueDemiGlobal = typeof globalThis !== 'undefined'
? globalThis
: typeof global !== 'undefined'
? global
: typeof self !== 'undefined'
? self
: this
var VueDemi = (function (VueDemi, Vue, VueCompositionAPI) {
if (VueDemi.install) {
return VueDemi
}
if (!Vue) {
console.error('[vue-demi] no Vue instance found, please be sure to import `vue` before `vue-demi`.')
return VueDemi
}
// Vue 2.7
if (Vue.version.slice(0, 4) === '2.7.') {
for (var key in Vue) {
VueDemi[key] = Vue[key]
}
VueDemi.isVue2 = true
VueDemi.isVue3 = false
VueDemi.install = function () {}
VueDemi.Vue = Vue
VueDemi.Vue2 = Vue
VueDemi.version = Vue.version
VueDemi.warn = Vue.util.warn
VueDemi.hasInjectionContext = function() {
return !!VueDemi.getCurrentInstance()
}
function createApp(rootComponent, rootProps) {
var vm
var provide = {}
var app = {
config: Vue.config,
use: Vue.use.bind(Vue),
mixin: Vue.mixin.bind(Vue),
component: Vue.component.bind(Vue),
provide: function (key, value) {
provide[key] = value
return this
},
directive: function (name, dir) {
if (dir) {
Vue.directive(name, dir)
return app
} else {
return Vue.directive(name)
}
},
mount: function (el, hydrating) {
if (!vm) {
vm = new Vue(Object.assign({ propsData: rootProps }, rootComponent, { provide: Object.assign(provide, rootComponent.provide) }))
vm.$mount(el, hydrating)
return vm
} else {
return vm
}
},
unmount: function () {
if (vm) {
vm.$destroy()
vm = undefined
}
},
}
return app
}
VueDemi.createApp = createApp
}
// Vue 2.6.x
else if (Vue.version.slice(0, 2) === '2.') {
if (VueCompositionAPI) {
for (var key in VueCompositionAPI) {
VueDemi[key] = VueCompositionAPI[key]
}
VueDemi.isVue2 = true
VueDemi.isVue3 = false
VueDemi.install = function () {}
VueDemi.Vue = Vue
VueDemi.Vue2 = Vue
VueDemi.version = Vue.version
VueDemi.hasInjectionContext = function() {
return !!VueDemi.getCurrentInstance()
}
} else {
console.error('[vue-demi] no VueCompositionAPI instance found, please be sure to import `@vue/composition-api` before `vue-demi`.')
}
}
// Vue 3
else if (Vue.version.slice(0, 2) === '3.') {
for (var key in Vue) {
VueDemi[key] = Vue[key]
}
VueDemi.isVue2 = false
VueDemi.isVue3 = true
VueDemi.install = function () {}
VueDemi.Vue = Vue
VueDemi.Vue2 = undefined
VueDemi.version = Vue.version
VueDemi.set = function (target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
target[key] = val
return val
}
VueDemi.del = function (target, key) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
delete target[key]
}
} else {
console.error('[vue-demi] Vue version ' + Vue.version + ' is unsupported.')
}
return VueDemi
})(
(_VueDemiGlobal.VueDemi = _VueDemiGlobal.VueDemi || (typeof VueDemi !== 'undefined' ? VueDemi : {})),
_VueDemiGlobal.Vue || (typeof Vue !== 'undefined' ? Vue : undefined),
_VueDemiGlobal.VueCompositionAPI || (typeof VueCompositionAPI !== 'undefined' ? VueCompositionAPI : undefined)
);
@@ -0,0 +1,34 @@
import * as Vue from 'vue'
var isVue2 = false
var isVue3 = true
var Vue2 = undefined
function install() {}
export function set(target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
target[key] = val
return val
}
export function del(target, key) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
delete target[key]
}
export * from 'vue'
export {
Vue,
Vue2,
isVue2,
isVue3,
install,
}
@@ -0,0 +1,60 @@
var VueModule = require('vue')
// get the real Vue https://github.com/vueuse/vue-demi/issues/192
var Vue = VueModule.default || VueModule
exports.Vue = Vue
exports.Vue2 = Vue
exports.isVue2 = true
exports.isVue3 = false
exports.install = function () {}
exports.warn = Vue.util.warn
// createApp polyfill
exports.createApp = function (rootComponent, rootProps) {
var vm
var provide = {}
var app = {
config: Vue.config,
use: Vue.use.bind(Vue),
mixin: Vue.mixin.bind(Vue),
component: Vue.component.bind(Vue),
provide: function (key, value) {
provide[key] = value
return this
},
directive: function (name, dir) {
if (dir) {
Vue.directive(name, dir)
return app
} else {
return Vue.directive(name)
}
},
mount: function (el, hydrating) {
if (!vm) {
vm = new Vue(Object.assign({ propsData: rootProps }, rootComponent, { provide: Object.assign(provide, rootComponent.provide) }))
vm.$mount(el, hydrating)
return vm
} else {
return vm
}
},
unmount: function () {
if (vm) {
vm.$destroy()
vm = undefined
}
},
}
return app
}
Object.keys(VueModule).forEach(function (key) {
exports[key] = VueModule[key]
})
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
exports.hasInjectionContext = function() {
return !!VueModule.getCurrentInstance()
}
@@ -0,0 +1,38 @@
import Vue from 'vue'
import type { PluginFunction, PluginObject, VueConstructor, Directive, InjectionKey, Component } from 'vue'
declare const isVue2: boolean
declare const isVue3: boolean
declare const Vue2: typeof Vue | undefined
declare const version: string
declare const install: (vue?: typeof Vue) => void
export declare function warn(msg: string, vm?: Component | null): void
/**
* @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead.
* Refer to https://github.com/vueuse/vue-demi/issues/41
*/
declare const V: typeof Vue
// accept no generic because Vue 3 doesn't accept any
// https://github.com/vuejs/vue-next/pull/2758/
export declare type Plugin = PluginObject<any> | PluginFunction<any>
export type { VNode } from 'vue'
export * from 'vue'
export { V as Vue, Vue2, isVue2, isVue3, version, install }
// #region createApp polyfill
export interface App<T = any> {
config: VueConstructor['config']
use: VueConstructor['use']
mixin: VueConstructor['mixin']
component: VueConstructor['component']
directive(name: string): Directive | undefined
directive(name: string, directive: Directive): this
provide<T>(key: InjectionKey<T> | string, value: T): this
mount: Vue['$mount']
unmount: Vue['$destroy']
}
export declare function createApp(rootComponent: any, rootProps?: any): App
// #endregion
export declare function hasInjectionContext(): boolean
@@ -0,0 +1,80 @@
import Vue from 'vue'
import { getCurrentInstance } from 'vue'
var isVue2 = true
var isVue3 = false
var Vue2 = Vue
var warn = Vue.util.warn
function install() {}
// createApp polyfill
export function createApp(rootComponent, rootProps) {
var vm
var provide = {}
var app = {
config: Vue.config,
use: Vue.use.bind(Vue),
mixin: Vue.mixin.bind(Vue),
component: Vue.component.bind(Vue),
provide: function (key, value) {
provide[key] = value
return this
},
directive: function (name, dir) {
if (dir) {
Vue.directive(name, dir)
return app
} else {
return Vue.directive(name)
}
},
mount: function (el, hydrating) {
if (!vm) {
vm = new Vue(Object.assign({ propsData: rootProps }, rootComponent, { provide: Object.assign(provide, rootComponent.provide) }))
vm.$mount(el, hydrating)
return vm
} else {
return vm
}
},
unmount: function () {
if (vm) {
vm.$destroy()
vm = undefined
}
},
}
return app
}
export {
Vue,
Vue2,
isVue2,
isVue3,
install,
warn
}
// Vue 3 components mock
function createMockComponent(name) {
return {
setup() {
throw new Error('[vue-demi] ' + name + ' is not supported in Vue 2. It\'s provided to avoid compiler errors.')
}
}
}
export var Fragment = /*#__PURE__*/ createMockComponent('Fragment')
export var Transition = /*#__PURE__*/ createMockComponent('Transition')
export var TransitionGroup = /*#__PURE__*/ createMockComponent('TransitionGroup')
export var Teleport = /*#__PURE__*/ createMockComponent('Teleport')
export var Suspense = /*#__PURE__*/ createMockComponent('Suspense')
export var KeepAlive = /*#__PURE__*/ createMockComponent('KeepAlive')
export * from 'vue'
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
export function hasInjectionContext() {
return !!getCurrentInstance()
}
@@ -0,0 +1,34 @@
var Vue = require('vue')
var VueCompositionAPI = require('@vue/composition-api')
function install(_vue) {
var vueLib = _vue || Vue
if (vueLib && 'default' in vueLib) {
vueLib = vueLib.default
}
if (vueLib && !vueLib['__composition_api_installed__']) {
if (VueCompositionAPI && 'default' in VueCompositionAPI)
vueLib.use(VueCompositionAPI.default)
else if (VueCompositionAPI)
vueLib.use(VueCompositionAPI)
}
}
install(Vue)
Object.keys(VueCompositionAPI).forEach(function(key) {
exports[key] = VueCompositionAPI[key]
})
exports.Vue = Vue
exports.Vue2 = Vue
exports.isVue2 = true
exports.isVue3 = false
exports.install = install
exports.version = Vue.version
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
exports.hasInjectionContext = function () {
return !!VueCompositionAPI.getCurrentInstance()
}
@@ -0,0 +1,33 @@
import Vue from 'vue'
import type { PluginFunction, PluginObject } from 'vue'
declare const isVue2: boolean
declare const isVue3: boolean
declare const Vue2: typeof Vue | undefined
declare const version: string
declare const install: (vue?: typeof Vue) => void
/**
* @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead.
* Refer to https://github.com/vueuse/vue-demi/issues/41
*/
declare const V: typeof Vue
/**
* DebuggerEvent is a Vue 3 development only feature. This type cannot exist in Vue 2.
*/
export declare type DebuggerEvent = never
// accept no generic because Vue 3 doesn't accept any
// https://github.com/vuejs/vue-next/pull/2758/
export declare type Plugin = PluginObject<any> | PluginFunction<any>
export type { VNode } from 'vue'
export * from '@vue/composition-api'
export {
V as Vue,
Vue2,
isVue2,
isVue3,
version,
install,
}
export declare function hasInjectionContext(): boolean
@@ -0,0 +1,49 @@
import Vue from 'vue'
import VueCompositionAPI, { getCurrentInstance } from '@vue/composition-api/dist/vue-composition-api.mjs'
function install(_vue) {
_vue = _vue || Vue
if (_vue && !_vue['__composition_api_installed__'])
_vue.use(VueCompositionAPI)
}
install(Vue)
var isVue2 = true
var isVue3 = false
var Vue2 = Vue
var version = Vue.version
/**VCA-EXPORTS**/
export * from '@vue/composition-api/dist/vue-composition-api.mjs'
/**VCA-EXPORTS**/
export {
Vue,
Vue2,
isVue2,
isVue3,
version,
install,
}
// Vue 3 components mock
function createMockComponent(name) {
return {
setup() {
throw new Error('[vue-demi] ' + name + ' is not supported in Vue 2. It\'s provided to avoid compiler errors.')
}
}
}
export var Fragment = /*#__PURE__*/ createMockComponent('Fragment')
export var Transition = /*#__PURE__*/ createMockComponent('Transition')
export var TransitionGroup = /*#__PURE__*/ createMockComponent('TransitionGroup')
export var Teleport = /*#__PURE__*/ createMockComponent('Teleport')
export var Suspense = /*#__PURE__*/ createMockComponent('Suspense')
export var KeepAlive = /*#__PURE__*/ createMockComponent('KeepAlive')
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
export function hasInjectionContext() {
return !!getCurrentInstance()
}
@@ -0,0 +1,29 @@
var Vue = require('vue')
Object.keys(Vue).forEach(function(key) {
exports[key] = Vue[key]
})
exports.set = function(target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
target[key] = val
return val
}
exports.del = function(target, key) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
delete target[key]
}
exports.Vue = Vue
exports.Vue2 = undefined
exports.isVue2 = false
exports.isVue3 = true
exports.install = function(){}
@@ -0,0 +1,22 @@
import * as Vue from 'vue'
declare const isVue2: boolean
declare const isVue3: boolean
declare const Vue2: any
declare const install: (vue?: any) => void
/**
* @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead.
* Refer to https://github.com/vueuse/vue-demi/issues/41
*/
declare const V: typeof Vue
export function set<T>(target: any, key: any, val: T): T
export function del(target: any, key: any): void
export * from 'vue'
export {
V as Vue,
Vue2,
isVue2,
isVue3,
install,
}
@@ -0,0 +1,34 @@
import * as Vue from 'vue'
var isVue2 = false
var isVue3 = true
var Vue2 = undefined
function install() {}
export function set(target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
target[key] = val
return val
}
export function del(target, key) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
delete target[key]
}
export * from 'vue'
export {
Vue,
Vue2,
isVue2,
isVue3,
install,
}
@@ -0,0 +1,47 @@
{
"name": "vue-demi",
"version": "0.14.10",
"engines": {
"node": ">=12"
},
"repository": "https://github.com/antfu/vue-demi.git",
"funding": "https://github.com/sponsors/antfu",
"license": "MIT",
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
"main": "lib/index.cjs",
"jsdelivr": "lib/index.iife.js",
"unpkg": "lib/index.iife.js",
"module": "lib/index.mjs",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"require": "./lib/index.cjs",
"import": "./lib/index.mjs",
"browser": "./lib/index.mjs"
},
"./*": "./*"
},
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"files": [
"lib",
"bin",
"scripts"
],
"scripts": {
"postinstall": "node -e \"try{require('./scripts/postinstall.js')}catch(e){}\"",
"release": "npx bumpp --tag --commit --push && npm publish"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
}
@@ -0,0 +1,19 @@
const { switchVersion, loadModule } = require('./utils')
const Vue = loadModule('vue')
if (!Vue || typeof Vue.version !== 'string') {
console.warn('[vue-demi] Vue is not found. Please run "npm install vue" to install.')
}
else if (Vue.version.startsWith('2.7.')) {
switchVersion(2.7)
}
else if (Vue.version.startsWith('2.')) {
switchVersion(2)
}
else if (Vue.version.startsWith('3.')) {
switchVersion(3)
}
else {
console.warn(`[vue-demi] Vue version v${Vue.version} is not supported.`)
}
@@ -0,0 +1,18 @@
const { switchVersion } = require('./utils')
const version = process.argv[2]
const vueEntry = process.argv[3] || 'vue'
if (version === '2.7') {
switchVersion(2.7, vueEntry)
console.log(`[vue-demi] Switched for Vue 2.7 (entry: "${vueEntry}")`)
} else if (version === '2') {
switchVersion(2, vueEntry)
console.log(`[vue-demi] Switched for Vue 2 (entry: "${vueEntry}")`)
} else if (version === '3') {
switchVersion(3, vueEntry)
console.log(`[vue-demi] Switched for Vue 3 (entry: "${vueEntry}")`)
} else {
console.warn(`[vue-demi] expecting version "2" or "2.7" or "3" but got "${version}"`)
process.exit(1)
}
@@ -0,0 +1,62 @@
const fs = require('fs')
const path = require('path')
const dir = path.resolve(__dirname, '..', 'lib')
function loadModule(name) {
try {
return require(name)
} catch (e) {
return undefined
}
}
function copy(name, version, vue) {
vue = vue || 'vue'
const src = path.join(dir, `v${version}`, name)
const dest = path.join(dir, name)
let content = fs.readFileSync(src, 'utf-8')
content = content.replace(/'vue'/g, `'${vue}'`)
// unlink for pnpm, #92
try {
fs.unlinkSync(dest)
} catch (error) { }
fs.writeFileSync(dest, content, 'utf-8')
}
function updateVue2API() {
const ignoreList = ['version', 'default']
const VCA = loadModule('@vue/composition-api')
if (!VCA) {
console.warn('[vue-demi] Composition API plugin is not found. Please run "npm install @vue/composition-api" to install.')
return
}
const exports = Object.keys(VCA).filter(i => !ignoreList.includes(i))
const esmPath = path.join(dir, 'index.mjs')
let content = fs.readFileSync(esmPath, 'utf-8')
content = content.replace(
/\/\*\*VCA-EXPORTS\*\*\/[\s\S]+\/\*\*VCA-EXPORTS\*\*\//m,
`/**VCA-EXPORTS**/
export { ${exports.join(', ')} } from '@vue/composition-api/dist/vue-composition-api.mjs'
/**VCA-EXPORTS**/`
)
fs.writeFileSync(esmPath, content, 'utf-8')
}
function switchVersion(version, vue) {
copy('index.cjs', version, vue)
copy('index.mjs', version, vue)
copy('index.d.ts', version, vue)
if (version === 2)
updateVue2API()
}
module.exports.loadModule = loadModule
module.exports.switchVersion = switchVersion
@@ -0,0 +1,45 @@
{
"name": "@vueuse/core",
"version": "10.11.1",
"description": "Collection of essential Vue Composition Utilities",
"author": "Anthony Fu <https://github.com/antfu>",
"license": "MIT",
"funding": "https://github.com/sponsors/antfu",
"homepage": "https://github.com/vueuse/vueuse#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/vueuse/vueuse.git",
"directory": "packages/core"
},
"bugs": {
"url": "https://github.com/vueuse/vueuse/issues"
},
"keywords": [
"vue",
"vue-use",
"utils"
],
"sideEffects": false,
"exports": {
".": {
"import": "./index.mjs",
"require": "./index.cjs"
},
"./*": "./*",
"./metadata": {
"import": "./metadata.mjs",
"require": "./metadata.cjs"
}
},
"main": "./index.cjs",
"module": "./index.mjs",
"unpkg": "./index.iife.min.js",
"jsdelivr": "./index.iife.min.js",
"types": "./index.d.cts",
"dependencies": {
"@types/web-bluetooth": "^0.0.20",
"@vueuse/metadata": "10.11.1",
"@vueuse/shared": "10.11.1",
"vue-demi": ">=0.14.8"
}
}
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019-PRESENT Anthony Fu<https://github.com/antfu>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,76 @@
interface PackageManifest {
name: string;
display: string;
addon?: boolean;
author?: string;
description?: string;
external?: string[];
globals?: Record<string, string>;
manualImport?: boolean;
deprecated?: boolean;
submodules?: boolean;
build?: boolean;
iife?: boolean;
cjs?: boolean;
mjs?: boolean;
dts?: boolean;
target?: string;
utils?: boolean;
copy?: string[];
}
interface VueUseFunction {
name: string;
package: string;
importPath?: string;
lastUpdated?: number;
category?: string;
description?: string;
docs?: string;
deprecated?: boolean;
internal?: boolean;
component?: boolean;
directive?: boolean;
external?: string;
alias?: string[];
related?: string[];
}
interface VueUsePackage extends PackageManifest {
dir: string;
docs?: string;
}
interface PackageIndexes {
packages: Record<string, VueUsePackage>;
categories: string[];
functions: VueUseFunction[];
}
interface CommitInfo {
functions: string[];
version?: string;
hash: string;
date: string;
message: string;
refs?: string;
body?: string;
author_name: string;
author_email: string;
}
interface ContributorInfo {
name: string;
count: number;
hash: string;
}
declare const metadata: PackageIndexes;
declare const functions: VueUseFunction[];
declare const packages: Record<string, VueUsePackage>;
declare const categories: string[];
declare const functionNames: string[];
declare const categoryNames: string[];
declare const coreCategoryNames: string[];
declare const addonCategoryNames: string[];
declare function getFunction(name: string): VueUseFunction | undefined;
declare function getCategories(functions: VueUseFunction[]): string[];
declare function uniq<T extends any[]>(a: T): any[];
export { type CommitInfo, type ContributorInfo, type PackageIndexes, type PackageManifest, type VueUseFunction, type VueUsePackage, addonCategoryNames, categories, categoryNames, coreCategoryNames, functionNames, functions, getCategories, getFunction, metadata, packages, uniq };
@@ -0,0 +1,76 @@
interface PackageManifest {
name: string;
display: string;
addon?: boolean;
author?: string;
description?: string;
external?: string[];
globals?: Record<string, string>;
manualImport?: boolean;
deprecated?: boolean;
submodules?: boolean;
build?: boolean;
iife?: boolean;
cjs?: boolean;
mjs?: boolean;
dts?: boolean;
target?: string;
utils?: boolean;
copy?: string[];
}
interface VueUseFunction {
name: string;
package: string;
importPath?: string;
lastUpdated?: number;
category?: string;
description?: string;
docs?: string;
deprecated?: boolean;
internal?: boolean;
component?: boolean;
directive?: boolean;
external?: string;
alias?: string[];
related?: string[];
}
interface VueUsePackage extends PackageManifest {
dir: string;
docs?: string;
}
interface PackageIndexes {
packages: Record<string, VueUsePackage>;
categories: string[];
functions: VueUseFunction[];
}
interface CommitInfo {
functions: string[];
version?: string;
hash: string;
date: string;
message: string;
refs?: string;
body?: string;
author_name: string;
author_email: string;
}
interface ContributorInfo {
name: string;
count: number;
hash: string;
}
declare const metadata: PackageIndexes;
declare const functions: VueUseFunction[];
declare const packages: Record<string, VueUsePackage>;
declare const categories: string[];
declare const functionNames: string[];
declare const categoryNames: string[];
declare const coreCategoryNames: string[];
declare const addonCategoryNames: string[];
declare function getFunction(name: string): VueUseFunction | undefined;
declare function getCategories(functions: VueUseFunction[]): string[];
declare function uniq<T extends any[]>(a: T): any[];
export { type CommitInfo, type ContributorInfo, type PackageIndexes, type PackageManifest, type VueUseFunction, type VueUsePackage, addonCategoryNames, categories, categoryNames, coreCategoryNames, functionNames, functions, getCategories, getFunction, metadata, packages, uniq };
@@ -0,0 +1,76 @@
interface PackageManifest {
name: string;
display: string;
addon?: boolean;
author?: string;
description?: string;
external?: string[];
globals?: Record<string, string>;
manualImport?: boolean;
deprecated?: boolean;
submodules?: boolean;
build?: boolean;
iife?: boolean;
cjs?: boolean;
mjs?: boolean;
dts?: boolean;
target?: string;
utils?: boolean;
copy?: string[];
}
interface VueUseFunction {
name: string;
package: string;
importPath?: string;
lastUpdated?: number;
category?: string;
description?: string;
docs?: string;
deprecated?: boolean;
internal?: boolean;
component?: boolean;
directive?: boolean;
external?: string;
alias?: string[];
related?: string[];
}
interface VueUsePackage extends PackageManifest {
dir: string;
docs?: string;
}
interface PackageIndexes {
packages: Record<string, VueUsePackage>;
categories: string[];
functions: VueUseFunction[];
}
interface CommitInfo {
functions: string[];
version?: string;
hash: string;
date: string;
message: string;
refs?: string;
body?: string;
author_name: string;
author_email: string;
}
interface ContributorInfo {
name: string;
count: number;
hash: string;
}
declare const metadata: PackageIndexes;
declare const functions: VueUseFunction[];
declare const packages: Record<string, VueUsePackage>;
declare const categories: string[];
declare const functionNames: string[];
declare const categoryNames: string[];
declare const coreCategoryNames: string[];
declare const addonCategoryNames: string[];
declare function getFunction(name: string): VueUseFunction | undefined;
declare function getCategories(functions: VueUseFunction[]): string[];
declare function uniq<T extends any[]>(a: T): any[];
export { type CommitInfo, type ContributorInfo, type PackageIndexes, type PackageManifest, type VueUseFunction, type VueUsePackage, addonCategoryNames, categories, categoryNames, coreCategoryNames, functionNames, functions, getCategories, getFunction, metadata, packages, uniq };
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,39 @@
{
"name": "@vueuse/metadata",
"type": "module",
"version": "10.11.1",
"description": "Metadata for VueUse functions",
"author": "Anthony Fu <https://github.com/antfu>",
"license": "MIT",
"funding": "https://github.com/sponsors/antfu",
"homepage": "https://github.com/vueuse/vueuse/tree/main/packages/metadata#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/vueuse/vueuse.git",
"directory": "packages/metadata"
},
"bugs": {
"url": "https://github.com/vueuse/vueuse/issues"
},
"keywords": [
"vue",
"vue-use"
],
"sideEffects": false,
"exports": {
".": {
"import": "./index.mjs",
"require": "./index.cjs"
},
"./*": "./*"
},
"main": "./index.cjs",
"module": "./index.mjs",
"types": "./index.d.ts",
"files": [
"index.*"
],
"scripts": {
"update": "esno scripts/update.ts"
}
}
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019-PRESENT Anthony Fu<https://github.com/antfu>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -0,0 +1 @@
../vue-demi/bin/vue-demi-fix.js
@@ -0,0 +1 @@
../vue-demi/bin/vue-demi-switch.js
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-present, Anthony Fu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,229 @@
<p align="center">
<img src="https://github.com/vueuse/vue-demi/blob/main/assets/banner.png?raw=true" width="600"/>
<br>
<a href='https://www.npmjs.com/package/vue-demi'><img src='https://img.shields.io/npm/v/vue-demi?color=42b883' alt='npm'></a>
</p>
<p align="center">
<b>Vue Demi</b> (<i>half</i> in French) is a developing utility<br> allows you to write <b>Universal Vue Libraries</b> for Vue 2 & 3<br>
<i>See more details in <a href='https://antfu.me/posts/make-libraries-working-with-vue-2-and-3'>this blog post</a></i>
</p>
<br>
<br>
## Strategies
- `<=2.6`: exports from `vue` + `@vue/composition-api` with plugin auto installing.
- `2.7`: exports from `vue` (Composition API is built-in in Vue 2.7).
- `>=3.0`: exports from `vue`, with polyfill of Vue 2's `set` and `del` API.
## Usage
Install this as your plugin's dependency:
```bash
npm i vue-demi
# or
yarn add vue-demi
# or
pnpm i vue-demi
```
Add `vue` and `@vue/composition-api` to your plugin's peer dependencies to specify what versions you support.
```jsonc
{
"dependencies": {
"vue-demi": "latest"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^2.0.0 || >=3.0.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
},
"devDependencies": {
"vue": "^3.0.0" // or "^2.6.0" base on your preferred working environment
},
}
```
Import everything related to Vue from it, it will redirect to `vue@2` + `@vue/composition-api` or `vue@3` based on users' environments.
```ts
import { ref, reactive, defineComponent } from 'vue-demi'
```
Publish your plugin and all is done!
> When using with [Vite](https://vitejs.dev), you will need to opt-out the pre-bundling to get `vue-demi` work properly by
> ```js
> // vite.config.js
> export default defineConfig({
> optimizeDeps: {
> exclude: ['vue-demi']
> }
> })
> ```
### Extra APIs
`Vue Demi` provides extra APIs to help distinguish users' environments and to do some version-specific logic.
### `isVue2` `isVue3`
```ts
import { isVue2, isVue3 } from 'vue-demi'
if (isVue2) {
// Vue 2 only
} else {
// Vue 3 only
}
```
### `Vue2`
To avoid bringing in all the tree-shakable modules, we provide a `Vue2` export to support access to Vue 2's global API. (See [#41](https://github.com/vueuse/vue-demi/issues/41).)
```ts
import { Vue2 } from 'vue-demi'
if (Vue2) {
Vue2.config.ignoredElements.push('x-foo')
}
```
### `install()`
Composition API in Vue 2 is provided as a plugin and needs to be installed on the Vue instance before using. Normally, `vue-demi` will try to install it automatically. For some usages where you might need to ensure the plugin gets installed correctly, the `install()` API is exposed to as a safe version of `Vue.use(CompositionAPI)`. `install()` in the Vue 3 environment will be an empty function (no-op).
```ts
import { install } from 'vue-demi'
install()
```
## CLI
### Manually Switch Versions
To explicitly switch the redirecting version, you can use these commands in your project's root.
```bash
npx vue-demi-switch 2
# or
npx vue-demi-switch 3
```
### Package Aliasing
If you would like to import `vue` under an alias, you can use the following command
```bash
npx vue-demi-switch 2 vue2
# or
npx vue-demi-switch 3 vue3
```
Then `vue-demi` will redirect APIs from the alias name you specified, for example:
```ts
import * as Vue from 'vue3'
var isVue2 = false
var isVue3 = true
var Vue2 = undefined
export * from 'vue3'
export {
Vue,
Vue2,
isVue2,
isVue3,
}
```
### Auto Fix
If the `postinstall` hook doesn't get triggered or you have updated the Vue version, try to run the following command to resolve the redirecting.
```bash
npx vue-demi-fix
```
### Isomorphic Testings
You can support testing for both versions by adding npm alias in your dev dependencies. For example:
```json
{
"scripts": {
"test:2": "vue-demi-switch 2 vue2 && jest",
"test:3": "vue-demi-switch 3 && jest",
},
"devDependencies": {
"vue": "^3.0.0",
"vue2": "npm:vue@2"
},
}
```
or
```json
{
"scripts": {
"test:2": "vue-demi-switch 2 && jest",
"test:3": "vue-demi-switch 3 vue3 && jest",
},
"devDependencies": {
"vue": "^2.6.0",
"vue3": "npm:vue@3"
},
}
```
## Examples
See [examples](./examples).
## Who is using this?
- [VueUse](https://github.com/vueuse/vueuse) - Collection of Composition API utils
- [@vue/apollo-composable](https://github.com/vuejs/vue-apollo/tree/v4/packages/vue-apollo-composable) - Apollo GraphQL functions for Vue Composition API
- [vuelidate](https://github.com/vuelidate/vuelidate) - Simple, lightweight model-based validation
- [vue-composition-test-utils](https://github.com/ariesjia/vue-composition-test-utils) - Simple vue composition api unit test utilities
- [vue-use-stripe](https://github.com/frandiox/vue-use-stripe) - Stripe Elements wrapper for Vue.js
- [@opd/g2plot-vue](https://github.com/open-data-plan/g2plot-vue) - G2plot for vue
- [vue-echarts](https://github.com/ecomfe/vue-echarts) - Vue.js component for Apache ECharts.
- [fluent-vue](https://github.com/Demivan/fluent-vue) - Vue.js integration for [Fluent.js](https://github.com/projectfluent/fluent.js) - JavaScript implementation of [Project Fluent](https://projectfluent.org)
- [vue-datatable-url-sync](https://github.com/socotecio/vue-datatable-url-sync) - Synchronize datatable options and filters with the url to keep user preference even after refresh or navigation
- [vue-insta-stories](https://github.com/UnevenSoftware/vue-insta-stories) - Instagram stories in your vue projects.
- [vue-tiny-validate](https://github.com/FrontLabsOfficial/vue-tiny-validate) - Tiny Vue Validate Composition
- [v-perfect-signature](https://github.com/wobsoriano/v-perfect-signature) - Pressure-sensitive signature drawing for Vue 2 and 3
- [vue-winbox](https://github.com/wobsoriano/vue-winbox) - A wrapper component for WinBox.js that adds the ability to mount Vue components.
- [vue-word-highlighter](https://github.com/kawamataryo/vue-word-highlighter) - The word highlighter library for Vue 2 and Vue 3
- [vue-chart-3](https://github.com/victorgarciaesgi/vue-chart-3) - Vue.js component for Chart.js
- [json-editor-vue](https://github.com/cloydlau/json-editor-vue) - JSON editor & viewer for Vue 2 and 3.
- [kidar-echarts](https://github.com/kidarjs/kidar-echarts) - A simpler echarts component for Vue 2 and 3.
- [vue3-sketch-ruler](https://github.com/kakajun/vue3-sketch-ruler) - The zoom operation used for page presentation for Vue 2 and 3( Replace render function with template )
- [vue-rough-notation](https://github.com/Leecason/vue-rough-notation) - RoughNotation wrapper component for Vue 2 and 3.
- [vue-request](https://github.com/AttoJS/vue-request) - Vue composition API for data fetching, supports SWR, polling, error retry, cache request, pagination, etc.
- [vue3-lazyload](https://github.com/murongg/vue3-lazyload) - A vue3.x image lazyload plugin.
- [vue-codemirror6](https://github.com/logue/vue-codemirror6) - CodeMirror6 component for Vue2 and 3.
- [@tanstack/vue-query](https://github.com/TanStack/query) - TanStack Query for Vue.
> open a PR to add your library ;)
## Underhood
See [the blog post](https://antfu.me/posts/make-libraries-working-with-vue-2-and-3/#-introducing-vue-demi).
## License
MIT License © 2020 [Anthony Fu](https://github.com/antfu)
@@ -0,0 +1,3 @@
#!/usr/bin/env node
'use strict'
require('../scripts/postinstall')
@@ -0,0 +1,3 @@
#!/usr/bin/env node
'use strict'
require('../scripts/switch-cli')
@@ -0,0 +1,29 @@
var Vue = require('vue')
Object.keys(Vue).forEach(function(key) {
exports[key] = Vue[key]
})
exports.set = function(target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
target[key] = val
return val
}
exports.del = function(target, key) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
delete target[key]
}
exports.Vue = Vue
exports.Vue2 = undefined
exports.isVue2 = false
exports.isVue3 = true
exports.install = function(){}
@@ -0,0 +1,22 @@
import * as Vue from 'vue'
declare const isVue2: boolean
declare const isVue3: boolean
declare const Vue2: any
declare const install: (vue?: any) => void
/**
* @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead.
* Refer to https://github.com/vueuse/vue-demi/issues/41
*/
declare const V: typeof Vue
export function set<T>(target: any, key: any, val: T): T
export function del(target: any, key: any): void
export * from 'vue'
export {
V as Vue,
Vue2,
isVue2,
isVue3,
install,
}
@@ -0,0 +1,126 @@
var _VueDemiGlobal = typeof globalThis !== 'undefined'
? globalThis
: typeof global !== 'undefined'
? global
: typeof self !== 'undefined'
? self
: this
var VueDemi = (function (VueDemi, Vue, VueCompositionAPI) {
if (VueDemi.install) {
return VueDemi
}
if (!Vue) {
console.error('[vue-demi] no Vue instance found, please be sure to import `vue` before `vue-demi`.')
return VueDemi
}
// Vue 2.7
if (Vue.version.slice(0, 4) === '2.7.') {
for (var key in Vue) {
VueDemi[key] = Vue[key]
}
VueDemi.isVue2 = true
VueDemi.isVue3 = false
VueDemi.install = function () {}
VueDemi.Vue = Vue
VueDemi.Vue2 = Vue
VueDemi.version = Vue.version
VueDemi.warn = Vue.util.warn
VueDemi.hasInjectionContext = function() {
return !!VueDemi.getCurrentInstance()
}
function createApp(rootComponent, rootProps) {
var vm
var provide = {}
var app = {
config: Vue.config,
use: Vue.use.bind(Vue),
mixin: Vue.mixin.bind(Vue),
component: Vue.component.bind(Vue),
provide: function (key, value) {
provide[key] = value
return this
},
directive: function (name, dir) {
if (dir) {
Vue.directive(name, dir)
return app
} else {
return Vue.directive(name)
}
},
mount: function (el, hydrating) {
if (!vm) {
vm = new Vue(Object.assign({ propsData: rootProps }, rootComponent, { provide: Object.assign(provide, rootComponent.provide) }))
vm.$mount(el, hydrating)
return vm
} else {
return vm
}
},
unmount: function () {
if (vm) {
vm.$destroy()
vm = undefined
}
},
}
return app
}
VueDemi.createApp = createApp
}
// Vue 2.6.x
else if (Vue.version.slice(0, 2) === '2.') {
if (VueCompositionAPI) {
for (var key in VueCompositionAPI) {
VueDemi[key] = VueCompositionAPI[key]
}
VueDemi.isVue2 = true
VueDemi.isVue3 = false
VueDemi.install = function () {}
VueDemi.Vue = Vue
VueDemi.Vue2 = Vue
VueDemi.version = Vue.version
VueDemi.hasInjectionContext = function() {
return !!VueDemi.getCurrentInstance()
}
} else {
console.error('[vue-demi] no VueCompositionAPI instance found, please be sure to import `@vue/composition-api` before `vue-demi`.')
}
}
// Vue 3
else if (Vue.version.slice(0, 2) === '3.') {
for (var key in Vue) {
VueDemi[key] = Vue[key]
}
VueDemi.isVue2 = false
VueDemi.isVue3 = true
VueDemi.install = function () {}
VueDemi.Vue = Vue
VueDemi.Vue2 = undefined
VueDemi.version = Vue.version
VueDemi.set = function (target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
target[key] = val
return val
}
VueDemi.del = function (target, key) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
delete target[key]
}
} else {
console.error('[vue-demi] Vue version ' + Vue.version + ' is unsupported.')
}
return VueDemi
})(
(_VueDemiGlobal.VueDemi = _VueDemiGlobal.VueDemi || (typeof VueDemi !== 'undefined' ? VueDemi : {})),
_VueDemiGlobal.Vue || (typeof Vue !== 'undefined' ? Vue : undefined),
_VueDemiGlobal.VueCompositionAPI || (typeof VueCompositionAPI !== 'undefined' ? VueCompositionAPI : undefined)
);
@@ -0,0 +1,34 @@
import * as Vue from 'vue'
var isVue2 = false
var isVue3 = true
var Vue2 = undefined
function install() {}
export function set(target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
target[key] = val
return val
}
export function del(target, key) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
delete target[key]
}
export * from 'vue'
export {
Vue,
Vue2,
isVue2,
isVue3,
install,
}
@@ -0,0 +1,60 @@
var VueModule = require('vue')
// get the real Vue https://github.com/vueuse/vue-demi/issues/192
var Vue = VueModule.default || VueModule
exports.Vue = Vue
exports.Vue2 = Vue
exports.isVue2 = true
exports.isVue3 = false
exports.install = function () {}
exports.warn = Vue.util.warn
// createApp polyfill
exports.createApp = function (rootComponent, rootProps) {
var vm
var provide = {}
var app = {
config: Vue.config,
use: Vue.use.bind(Vue),
mixin: Vue.mixin.bind(Vue),
component: Vue.component.bind(Vue),
provide: function (key, value) {
provide[key] = value
return this
},
directive: function (name, dir) {
if (dir) {
Vue.directive(name, dir)
return app
} else {
return Vue.directive(name)
}
},
mount: function (el, hydrating) {
if (!vm) {
vm = new Vue(Object.assign({ propsData: rootProps }, rootComponent, { provide: Object.assign(provide, rootComponent.provide) }))
vm.$mount(el, hydrating)
return vm
} else {
return vm
}
},
unmount: function () {
if (vm) {
vm.$destroy()
vm = undefined
}
},
}
return app
}
Object.keys(VueModule).forEach(function (key) {
exports[key] = VueModule[key]
})
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
exports.hasInjectionContext = function() {
return !!VueModule.getCurrentInstance()
}
@@ -0,0 +1,38 @@
import Vue from 'vue'
import type { PluginFunction, PluginObject, VueConstructor, Directive, InjectionKey, Component } from 'vue'
declare const isVue2: boolean
declare const isVue3: boolean
declare const Vue2: typeof Vue | undefined
declare const version: string
declare const install: (vue?: typeof Vue) => void
export declare function warn(msg: string, vm?: Component | null): void
/**
* @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead.
* Refer to https://github.com/vueuse/vue-demi/issues/41
*/
declare const V: typeof Vue
// accept no generic because Vue 3 doesn't accept any
// https://github.com/vuejs/vue-next/pull/2758/
export declare type Plugin = PluginObject<any> | PluginFunction<any>
export type { VNode } from 'vue'
export * from 'vue'
export { V as Vue, Vue2, isVue2, isVue3, version, install }
// #region createApp polyfill
export interface App<T = any> {
config: VueConstructor['config']
use: VueConstructor['use']
mixin: VueConstructor['mixin']
component: VueConstructor['component']
directive(name: string): Directive | undefined
directive(name: string, directive: Directive): this
provide<T>(key: InjectionKey<T> | string, value: T): this
mount: Vue['$mount']
unmount: Vue['$destroy']
}
export declare function createApp(rootComponent: any, rootProps?: any): App
// #endregion
export declare function hasInjectionContext(): boolean
@@ -0,0 +1,80 @@
import Vue from 'vue'
import { getCurrentInstance } from 'vue'
var isVue2 = true
var isVue3 = false
var Vue2 = Vue
var warn = Vue.util.warn
function install() {}
// createApp polyfill
export function createApp(rootComponent, rootProps) {
var vm
var provide = {}
var app = {
config: Vue.config,
use: Vue.use.bind(Vue),
mixin: Vue.mixin.bind(Vue),
component: Vue.component.bind(Vue),
provide: function (key, value) {
provide[key] = value
return this
},
directive: function (name, dir) {
if (dir) {
Vue.directive(name, dir)
return app
} else {
return Vue.directive(name)
}
},
mount: function (el, hydrating) {
if (!vm) {
vm = new Vue(Object.assign({ propsData: rootProps }, rootComponent, { provide: Object.assign(provide, rootComponent.provide) }))
vm.$mount(el, hydrating)
return vm
} else {
return vm
}
},
unmount: function () {
if (vm) {
vm.$destroy()
vm = undefined
}
},
}
return app
}
export {
Vue,
Vue2,
isVue2,
isVue3,
install,
warn
}
// Vue 3 components mock
function createMockComponent(name) {
return {
setup() {
throw new Error('[vue-demi] ' + name + ' is not supported in Vue 2. It\'s provided to avoid compiler errors.')
}
}
}
export var Fragment = /*#__PURE__*/ createMockComponent('Fragment')
export var Transition = /*#__PURE__*/ createMockComponent('Transition')
export var TransitionGroup = /*#__PURE__*/ createMockComponent('TransitionGroup')
export var Teleport = /*#__PURE__*/ createMockComponent('Teleport')
export var Suspense = /*#__PURE__*/ createMockComponent('Suspense')
export var KeepAlive = /*#__PURE__*/ createMockComponent('KeepAlive')
export * from 'vue'
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
export function hasInjectionContext() {
return !!getCurrentInstance()
}
@@ -0,0 +1,34 @@
var Vue = require('vue')
var VueCompositionAPI = require('@vue/composition-api')
function install(_vue) {
var vueLib = _vue || Vue
if (vueLib && 'default' in vueLib) {
vueLib = vueLib.default
}
if (vueLib && !vueLib['__composition_api_installed__']) {
if (VueCompositionAPI && 'default' in VueCompositionAPI)
vueLib.use(VueCompositionAPI.default)
else if (VueCompositionAPI)
vueLib.use(VueCompositionAPI)
}
}
install(Vue)
Object.keys(VueCompositionAPI).forEach(function(key) {
exports[key] = VueCompositionAPI[key]
})
exports.Vue = Vue
exports.Vue2 = Vue
exports.isVue2 = true
exports.isVue3 = false
exports.install = install
exports.version = Vue.version
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
exports.hasInjectionContext = function () {
return !!VueCompositionAPI.getCurrentInstance()
}
@@ -0,0 +1,33 @@
import Vue from 'vue'
import type { PluginFunction, PluginObject } from 'vue'
declare const isVue2: boolean
declare const isVue3: boolean
declare const Vue2: typeof Vue | undefined
declare const version: string
declare const install: (vue?: typeof Vue) => void
/**
* @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead.
* Refer to https://github.com/vueuse/vue-demi/issues/41
*/
declare const V: typeof Vue
/**
* DebuggerEvent is a Vue 3 development only feature. This type cannot exist in Vue 2.
*/
export declare type DebuggerEvent = never
// accept no generic because Vue 3 doesn't accept any
// https://github.com/vuejs/vue-next/pull/2758/
export declare type Plugin = PluginObject<any> | PluginFunction<any>
export type { VNode } from 'vue'
export * from '@vue/composition-api'
export {
V as Vue,
Vue2,
isVue2,
isVue3,
version,
install,
}
export declare function hasInjectionContext(): boolean
@@ -0,0 +1,49 @@
import Vue from 'vue'
import VueCompositionAPI, { getCurrentInstance } from '@vue/composition-api/dist/vue-composition-api.mjs'
function install(_vue) {
_vue = _vue || Vue
if (_vue && !_vue['__composition_api_installed__'])
_vue.use(VueCompositionAPI)
}
install(Vue)
var isVue2 = true
var isVue3 = false
var Vue2 = Vue
var version = Vue.version
/**VCA-EXPORTS**/
export * from '@vue/composition-api/dist/vue-composition-api.mjs'
/**VCA-EXPORTS**/
export {
Vue,
Vue2,
isVue2,
isVue3,
version,
install,
}
// Vue 3 components mock
function createMockComponent(name) {
return {
setup() {
throw new Error('[vue-demi] ' + name + ' is not supported in Vue 2. It\'s provided to avoid compiler errors.')
}
}
}
export var Fragment = /*#__PURE__*/ createMockComponent('Fragment')
export var Transition = /*#__PURE__*/ createMockComponent('Transition')
export var TransitionGroup = /*#__PURE__*/ createMockComponent('TransitionGroup')
export var Teleport = /*#__PURE__*/ createMockComponent('Teleport')
export var Suspense = /*#__PURE__*/ createMockComponent('Suspense')
export var KeepAlive = /*#__PURE__*/ createMockComponent('KeepAlive')
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
export function hasInjectionContext() {
return !!getCurrentInstance()
}
@@ -0,0 +1,29 @@
var Vue = require('vue')
Object.keys(Vue).forEach(function(key) {
exports[key] = Vue[key]
})
exports.set = function(target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
target[key] = val
return val
}
exports.del = function(target, key) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
delete target[key]
}
exports.Vue = Vue
exports.Vue2 = undefined
exports.isVue2 = false
exports.isVue3 = true
exports.install = function(){}
@@ -0,0 +1,22 @@
import * as Vue from 'vue'
declare const isVue2: boolean
declare const isVue3: boolean
declare const Vue2: any
declare const install: (vue?: any) => void
/**
* @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead.
* Refer to https://github.com/vueuse/vue-demi/issues/41
*/
declare const V: typeof Vue
export function set<T>(target: any, key: any, val: T): T
export function del(target: any, key: any): void
export * from 'vue'
export {
V as Vue,
Vue2,
isVue2,
isVue3,
install,
}
@@ -0,0 +1,34 @@
import * as Vue from 'vue'
var isVue2 = false
var isVue3 = true
var Vue2 = undefined
function install() {}
export function set(target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
target[key] = val
return val
}
export function del(target, key) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
delete target[key]
}
export * from 'vue'
export {
Vue,
Vue2,
isVue2,
isVue3,
install,
}
@@ -0,0 +1,47 @@
{
"name": "vue-demi",
"version": "0.14.10",
"engines": {
"node": ">=12"
},
"repository": "https://github.com/antfu/vue-demi.git",
"funding": "https://github.com/sponsors/antfu",
"license": "MIT",
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
"main": "lib/index.cjs",
"jsdelivr": "lib/index.iife.js",
"unpkg": "lib/index.iife.js",
"module": "lib/index.mjs",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"require": "./lib/index.cjs",
"import": "./lib/index.mjs",
"browser": "./lib/index.mjs"
},
"./*": "./*"
},
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"files": [
"lib",
"bin",
"scripts"
],
"scripts": {
"postinstall": "node -e \"try{require('./scripts/postinstall.js')}catch(e){}\"",
"release": "npx bumpp --tag --commit --push && npm publish"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
}
@@ -0,0 +1,19 @@
const { switchVersion, loadModule } = require('./utils')
const Vue = loadModule('vue')
if (!Vue || typeof Vue.version !== 'string') {
console.warn('[vue-demi] Vue is not found. Please run "npm install vue" to install.')
}
else if (Vue.version.startsWith('2.7.')) {
switchVersion(2.7)
}
else if (Vue.version.startsWith('2.')) {
switchVersion(2)
}
else if (Vue.version.startsWith('3.')) {
switchVersion(3)
}
else {
console.warn(`[vue-demi] Vue version v${Vue.version} is not supported.`)
}
@@ -0,0 +1,18 @@
const { switchVersion } = require('./utils')
const version = process.argv[2]
const vueEntry = process.argv[3] || 'vue'
if (version === '2.7') {
switchVersion(2.7, vueEntry)
console.log(`[vue-demi] Switched for Vue 2.7 (entry: "${vueEntry}")`)
} else if (version === '2') {
switchVersion(2, vueEntry)
console.log(`[vue-demi] Switched for Vue 2 (entry: "${vueEntry}")`)
} else if (version === '3') {
switchVersion(3, vueEntry)
console.log(`[vue-demi] Switched for Vue 3 (entry: "${vueEntry}")`)
} else {
console.warn(`[vue-demi] expecting version "2" or "2.7" or "3" but got "${version}"`)
process.exit(1)
}
@@ -0,0 +1,62 @@
const fs = require('fs')
const path = require('path')
const dir = path.resolve(__dirname, '..', 'lib')
function loadModule(name) {
try {
return require(name)
} catch (e) {
return undefined
}
}
function copy(name, version, vue) {
vue = vue || 'vue'
const src = path.join(dir, `v${version}`, name)
const dest = path.join(dir, name)
let content = fs.readFileSync(src, 'utf-8')
content = content.replace(/'vue'/g, `'${vue}'`)
// unlink for pnpm, #92
try {
fs.unlinkSync(dest)
} catch (error) { }
fs.writeFileSync(dest, content, 'utf-8')
}
function updateVue2API() {
const ignoreList = ['version', 'default']
const VCA = loadModule('@vue/composition-api')
if (!VCA) {
console.warn('[vue-demi] Composition API plugin is not found. Please run "npm install @vue/composition-api" to install.')
return
}
const exports = Object.keys(VCA).filter(i => !ignoreList.includes(i))
const esmPath = path.join(dir, 'index.mjs')
let content = fs.readFileSync(esmPath, 'utf-8')
content = content.replace(
/\/\*\*VCA-EXPORTS\*\*\/[\s\S]+\/\*\*VCA-EXPORTS\*\*\//m,
`/**VCA-EXPORTS**/
export { ${exports.join(', ')} } from '@vue/composition-api/dist/vue-composition-api.mjs'
/**VCA-EXPORTS**/`
)
fs.writeFileSync(esmPath, content, 'utf-8')
}
function switchVersion(version, vue) {
copy('index.cjs', version, vue)
copy('index.mjs', version, vue)
copy('index.d.ts', version, vue)
if (version === 2)
updateVue2API()
}
module.exports.loadModule = loadModule
module.exports.switchVersion = switchVersion
@@ -0,0 +1,37 @@
{
"name": "@vueuse/shared",
"version": "10.11.1",
"author": "Anthony Fu <https://github.com/antfu>",
"license": "MIT",
"funding": "https://github.com/sponsors/antfu",
"homepage": "https://github.com/vueuse/vueuse/tree/main/packages/shared#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/vueuse/vueuse.git",
"directory": "packages/shared"
},
"bugs": {
"url": "https://github.com/vueuse/vueuse/issues"
},
"keywords": [
"vue",
"vue-use",
"utils"
],
"sideEffects": false,
"exports": {
".": {
"import": "./index.mjs",
"require": "./index.cjs"
},
"./*": "./*"
},
"main": "./index.cjs",
"module": "./index.mjs",
"unpkg": "./index.iife.min.js",
"jsdelivr": "./index.iife.min.js",
"types": "./index.d.cts",
"dependencies": {
"vue-demi": ">=0.14.8"
}
}

Some files were not shown because too many files have changed in this diff Show More