vueuse / vueuse Goto Github PK
View Code? Open in Web Editor NEWCollection of essential Vue Composition Utilities for Vue 2 and 3
Home Page: https://vueuse.org
License: MIT License
Collection of essential Vue Composition Utilities for Vue 2 and 3
Home Page: https://vueuse.org
License: MIT License
got the warning when using the i18n package.
warning in ./node_modules/@vueuse/i18n/index.esm.js
"export 'default' (imported as 'Vue') was not found in 'vue'
the project freshly created with vue-cli with typescript and vue3 option.
Great Lib, Thanks a LOT !
But it seems no createGlobalState in npm, while in the doc site. Please publish code in npm ?
let rawValue = storage.getItem(key)
if (rawValue === undefined && defaultValue) {
rawValue = Serializers[type].write(defaultValue)
storage.setItem(key, rawValue)
} else {
data.value = Serializers[type].read(rawValue, defaultValue)
}
localStorage.setItem方法必须穿俩个参数,不会出现有key,值是undefined的情况吧?这个判断的意义是?
I get errors like
ERROR in node_modules/@vueuse/core/index.d.ts(1,21):
1:21 Cannot find module '@vue/composition-api/dist/reactivity/ref' or its corresponding type declarations.
> 1 | import { Ref } from '@vue/composition-api/dist/reactivity/ref';
Same code works with composition-api v0.6.1
Currently useElementVisibility
seems to make use of listening to the document scroll and tests if the element is visible each time it changes. I think it would also be good to have a composable that makes use of the intersection observer api. I have created a basic implementation myself here https://gist.github.com/jacobclevenger/86653ce2335073833cd13fb2b74b38ae and it works like this
<template>
<div ref="self">Is Visible: {{isIntersecting}}</div>
</tempate>
<script lang="ts" setup>
import { ref } from 'vue'
import { useIntersectionObserver } from './useIntersectionObserver'
export const self = ref<HTMLElement | null>()
export const { onIntersected, onNotIntersected, isIntersecting } = useIntersectionObserver()
onIntersected(() => {
console.log('Is Intersecting')
})
onNotIntersected(() => {
console.log('Is Not Intersecting')
})
</script>
Not this implementation also allows you to pass in useIntersectionObserver(el, true)
which will make the intersection observer fire once and then it will stop observing the element visibility.
I'm not sure if this fits with this project, but I have found this to be useful for myself so I thought I would propose it here as well.
Yes, we still do support IE11. We hope to be able to drop it soon, but today we still do. We have quite some dependencies and all of them seem to ship ES5 compatible bundles except vueuse. Is this intentional?
Suggested Feature
Support ServerSentEvents
via useEventSource
the same way we have WebSockets
via useWebSocket
Hi! In Vue3, vue instance no longer implement the event emitter interface.
So eventBus
will no longer be available.
import Vue from 'vue';
const bus = new Vue();
bus.$on('xxx', '...');
bus.$emit('xxx', '...');
there's a way to implement this event emitter/pubsub feature by composition-api?
Version: 2.0.26 (Vue 2)
Chrome: 81.0.4044.12 on OSX
const myBool = useStorage("anything", true);
watchEffect(() => {
console.log(myBool.value); // prints false
});
I put a breakpoint in useStorage and in the read method, there seems to be a bug:
// rawValue is set to null if key is not in local storage
var rawValue = storage.getItem(key);
// check specifically looks for undefined but rawValue is null
if (rawValue === undefined && defaultValue) {
Due to the null/undefined mixup, the code enters the else clause and there seems to be an issue there too.
data.value = Serializers[type].read(rawValue, defaultValue);
If passes in two values to the serializer (rawValue=null, defaultValue=true), but the serializer's read method only takes one argument:
boolean: {
read: function (v) { return v === 'true'; },
write: function (v) { return String(v); },
},
Since the first argument is null, it returns false.
I've been wanting something like vue-async-computed
for Vue's composition API, but couldn't find anything so I created it myself. I made a gist with an explainer and an initial implementation here.
Because of its generic nature and broad use cases, the useAsyncComputed
function may be a nice counterpart to the existing useAsyncState
.
What do you think?
Hey @antfu! Thanks for all the work with the lib ❤️
Great to see you added a composable for ref history! We had to build one because the useUndo
from vue-composable was not flexible enough for our use case. I was planning to submit a proposal for a similar one at one point. The API is not the same though, so I may release it as a separate lib since it has different tradeoffs. There are some API tweaks that could be useful in the current on in vueuse. If you like any of these changes, I could create PRs for them.
flush: 'sync'
history, redoHistory
to prev, next
useUndo
. I think they are more in line with the rest of the API (undo, redo, clear) and it reads better when you use an object for the composable return:const history = useRefHistory(aRef)
if( history.prev.length > 0 ) { ... } // instead of history.history
if( history.next.length > 0 ) { ... } // instead of history.redoHistory
batch(), commit()
functions, that complements pause(), resume()
(it can be discussed if we should have both pairs after adding batch and commit, IMO they both have different use cases)history.batch()
// change state, across several user events (pointermove for example)
and when the interaction ends
history.commit()
If we want to do the same with pause(), resume()
, we would need to add another set to the ref to trigger the history point after it is resumed.
I also think that batch(), commit()
is better suited for this cases because we can add a cancel()
function, that will go back to the last history point, finish the batch and resume history (it can also be called revert()
if we want to follow a git analogy).
commit()
can also let us build a manual history composable, with the same API, where the trigger is not automatic but the user is the one in charge of deciding when there is a history point. It also serves as a way to add a sync history point in case the user decides not to use flush: 'sync'
but still needs it in a particular case.
I think the other differences with what I had in mind are more about extra features and configuration, and it is not clear to me that the gained flexibility will be enough to justify a more complex API in vueuse. This is why I think there could be space for another lib, with different tradeoffs (more options, but more time to learn it, and more verbose config). But the above proposals could be good for vueuse, and later if people migrate from vue-composable or to other libs, they would have a closer API.
@antfu what do you think about adding isSupported to useShare? This will break the current implementation.
export async function useShare(shareOpts: ShareOptions) {
const _navigator = (window.navigator as NavigatorWithShare)
const isSupported = _navigator && _navigator.share
const share = () => {
if (isSupported) {
let granted = true
if (shareOpts.files && _navigator.canShare)
granted = _navigator.canShare({ files: shareOpts.files })
if (granted)
return _navigator.share(shareOpts)
}
}
return {
isSupported,
share,
}
}
Demo
<script>
import { useShare } from '@vueuse/core'
setup() {
const { isSupported, share } = useShare({ title: 'Hello', text: 'Hello my friend!', url: location.href })
return {
isSupported
share,
}
},
</script>
<div>
<button @click="share" :disabled="!isSupported">Share</button>
</div>
The TypeScript compiler option --isolatedModules
reports an error:
node_modules/@vueuse/core/dist/index.d.ts:492:278 - error TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided.
It would be nice if vueuse would not prevent the use of this compiler option.
after install the dependcies, I run npm run dev
to start the storybook but failed.
from the error stack I noticed that three dependcies cannot be found:
Should these three packages be added in the package.json
?
I base on
"@vue/composition-api": "^0.5.0",
"@vueuse/core": "^2.0.24",
Hello!
Awesome to see the preparation for the first stable release https://github.com/antfu/vueuse/issues/166 🎉
We have been using useRefHistory for https://github.com/Leniolabs/layoutit-grid using the extended API and it has been working well. The only thing that I am still not sure of is the right API choice to freeze is the default flush:sync. I think we should still try to make it work with the same default, 'pre', as watch/watchEffect.
I had to import batch in several places to fix issues with the flush:sync. I could have placed them in the actions, but it is still easy to get spurious history points. There also seems to be an issue with array refs and splice. Looks like calling splice is generating two history points (maybe a bug in Vue.js itself?).
I have an idea to use two watchers that may enable us to offer pre/post (and also sync as an option), so we could choose pre as the default. I still have to see if it works, but if not, I still think we should try to find a solution.
@antfu should I create a PR against the new dev branch if I managed to get it right? What do you think?
Hi 👋
I wish to contribute but unable to run yarn dev
due to a syntax error in useWebWorkerFn:
'const' enums are not supported
what am I missing? 🤔
Thanks!
Node v12.11.1
Yarn 1.22.10
MacOS 10.15.5
Hey, i would like to contribute a port of https://github.com/alewin/useworker.
Its a Hook to extract heavy operation right in your Component Code without writing extra files. It uses Object Url to create workers at runtime and represent workers as promises.
I really like it and i would like to use it in Vue. What do you think of it?
I've done some work already, but would like to get some Feedback first.
First thing i am struggleing with is babel. It converts the code i am extracting to the worker, which is fine but then uses babel helper functions in the extracted code, wich aren't available in the worker context. How can i solve that issue? Is there a way to tell babel, this is worker code dont use helpers? Or is this a thing the limits the ability of that hook?
Somehow i haven't had any issues with that in react
Perfect, your proposal just works fine!
Thank you very much, highly appreciated :)
Lars
Originally posted by @larsreith in storybookjs/storybook#11580 (comment)
While I'm in here, would you mind if I added one more util to the library? This one would be for transitioning state along cubic bezier curves. Below is an example of what I'm proposing...
<template>
<div>
<input v-model.number="baseNumber" /> {{ number }}
</div>
</template>
<script>
export default {
setup() {
const baseNumber = ref(0)
const number = useStateTransition(baseNumber, {
duration: 1000,
steps: 30, // probably a reasonable default, but allows for custom framerates
transition: [0.77, 0, 0.175, 1] // maybe have aliases like 'easeInOutQuart'?
})
return { baseNumber, number }
}
}
</script>
This took me a while to track down, but after upgrading to @4.0.0-beta.4
my whole app started throwing a million errors as the main instance got initialised twice.
I used @4.0.0-beta.2
fine.
Not even sure how to describe this bug.
The library has great potential! Thank you for your work. I only use one function from it so i will be removing it for now.
I wish i could provide a simple bug, but at the moment we're in crunch mode to launch production and this has cost me 2 days already :(
I might return back with a proper issue once i have time.
First off, awesome repo you have here!
Would you accept a utility for determining a component's position within the viewport? This sort of thing can be handy when trying to defer expensive operations like data fetching or complex rendering. Here is a brief example of what I am proposing...
<template>
<div>
{{ elementIsVisible ? "I'm visible in the viewport" : "You can't see me" }}
</div>
</template>
<script>
export default {
setup() {
const { elementIsVisible } = useElementVisibility();
return { elementIsVisible };
},
};
</script>
If you're open to this util, I'll put together a PR. And just for fun, here is a more realistic example showing how this kind of thing could be used to do infinite-scroll pagination 🤷♂️
import { useElementVisibility } from '@vueuse/core'
export default {
setup() {
const { elementIsVisible } = useElementVisibility();
return { elementIsVisible };
},
watch: {
elementIsVisible(visible) {
if (visible) this.$emit('enter-viewport');
},
},
};
<template>
<div>
<Whatever
v-for="thing in things"
:thing="thing"
:key="thing.id"
/>
<InfiniteScroll @enter-viewport="fetchMoreArticles" />
</div>
</template>
Add basic JSDocs to each function. The minimal work will be copying the first sentence of docs to it.
This is a checklist of all the functions of VueUse. It's is useful for review or making changes the go through every function.
It would be nice if the type of the storage
parameter of useStorage
would be Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>
instead of the full Storage
interface. This way it would be compatible with https://github.com/ripeworks/local-storage-fallback/blob/master/index.d.ts#L1.
While this repo is currenly under heavy development, I though creating an Issue would be better than a PR.
tilt
and roll
says .nan
and demo not working.useTimeoutFn, useTimeout, useAsyncState
Maximum call stack size exceeded
Hi there, is there any way how to utilize more useAxios
hooks and put them in a chain? How to do that? Thank you!
createGlobalState
stops tracking changes after component that first used global state is disposed.
Tried it with vue@3
and can reproduce it there too, so it is not @vue/composition-api
issue.
Added pull request with reproduction tests: #129
FAIL packages/core/useTimeout/index.test.ts
● export
[vue-composition-api] must call Vue.use(plugin) before using any function.
2 |
3 | export function useTimeout(interval = 1000, startRightNow = true) {
> 4 | const ready = ref(false)
| ^
5 |
6 | let timer: any = null
PASS packages/core/useCounter/index.test.ts
FAIL packages/core/useWindowSize/index.test.ts
● useWindowSize › should work
expect(received).toBe(expected) // Object.is equality
Expected: 1024
Received: undefined
17 | })
18 |
> 19 | expect(wrapper.vm.width).toBe(window.innerWidth)
| ^
20 | expect(wrapper.vm.height).toBe(window.innerHeight)
21 | })
● useWindowSize › sets handler for window "resize" event
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: "resize", Anything, undefined
Number of calls: 0
29 | })
30 |
> 31 | expect(windowAddEventListener).toHaveBeenCalledWith('resize', expect.anything(), undefined)
| ^
32 | })
33 | })
If I want to add support to save to local storage the app state, so the state will be preserved next time the app is reloaded
const state = ref({ ... })
function serializeState(state) { ... }
function parseState(state) { ... }
Right now I need to do something like this:
const { undo, redo, pause, resume, history } = useRefHistory(state,{
dump: serializeState, // custom dump, to avoid double serialization
parse: parseState
})
const stateStorage = useStorage('app-state')
watch( history, () => {
// user needs to know that last history point is in history[0] and not at the end
stateStorage.value = history.value[0] // serialized because dump: serializeState
}, { deep: true }) // we need to watch deeply the history array
I want to watch the history instead of the current state ref because I am using pause and resume while the user is dragging stuff around (and I only want to generate one history point for the whole interaction).
I think this is a common case, and there are several details that people could get wrong. We could add a section to the docs to show how to use these two composables together, but maybe we could extend the API of useRefHistory
to simplify this pattern.
const { undo, redo, pause, resume, last } = useRefHistory(state,{
dump: serializeState,
parse: parseState
})
const stateStorage = useLocalStorage('app-state')
watch( last, () => {
stateStorage.value = last.value // serialized because dump: serializeState
})
This removes the need for { deep: true }
and to know that history[0] is the last history point
const { undo, redo, pause, resume, last } = useRefHistory(state,{
dump: serializeState,
parse: parseState
})
const stateStorage = useLocalStorage('app-state',{ track: last })
I do not find a good name for the option, but the idea will be that everytime that the ref changes, stateStorage is actualized. We could also ask users to do this instead:
const stateStorage = useLocalStorage('app-state')
syncRef( last, stateStorage, { flush: 'pre' })
const { undo, redo, pause, resume, storage } = useStoredRefHistory(state,{
dump: serializeState, // custom dump, to avoid double serialization
parse: parseState,
storage: { key: 'app-state', ...otherStorageOptions }
})
I think that this use case may so common that it may justify this last option (name could also be useRefHistoryWithStorage)
What do you think? I am missing a better option?
I was looking into the debouncing option you raised for useStorage and I wanted to first see if the same can be achieved in a more flexible way.
Please take this as a dump of ideas and not a definite API. I thought about this while trying to design the API for other composables, and I want to share it in case it is useful in some way for vueuse.
The problem that I see with adding a denounce option is that we may also want to add a throttle one later (or pausable, or other ideas we may have later). We are adding complexity to the main composable, and users will need to pay for this even if they do not use it. There are other composables like useRefHistory where users may expect the same functionality.
So, what if the API lets the user define the filtering function to be used? I think you called it updater in the useDebounce implementation. I am using filter
as the option name just because it is called like that in Rx, but I am not married with the name. The signature for filter is ( (fn) => void ) => void
const count = useStorage('counter', 0, { filter: debounceFilter(200) })
const count = useStorage('counter', 0, { filter: throttleFilter(300) })
const { filter, pause, resume } = pausableFilter()
const count = useStorage('counter', 0, { filter })
debounceFilter
could be implemented as:
export function debounceFilter(delay = 200) {
return (fn) => useDebounceFn(() => fn(), delay)
}
The idea is that inside useStorage, instead of a direct watch(data, commit, options)
we use watch(data, filter(commit), options)
So, the filter
option gives users the possibility to decide which triggered values to accept from the watch.
Also, if we have these filters in the lib, we can also implement useDebounceRef, useThrotleRef, etc using a more general useFilteredRef
export function pausableFilter() {
const tracking = ref(true)
function pause() {
tracking.value = false
}
function resume() {
tracking.value = true
}
function filter(fn) {
return () => {
if( tracking.value ) {
fn()
}
}
return { tracking, pause, resume, filter }
}
The filters are composable also, allowing users to create pausable throttled storage for example
const { filter, pause, resume } = pausableFilter()
const count = useStorage('counter', 0, { filter: filter(throttleFilter(300)) })
And they can actually create their own filters, pausing or delaying according to their app needs (using other app refs, etc)
I also wonder if we could simplify useRefHistory by removing the pausable part out of the main composable, and letting users choose if they want that functionality
const data = ref(0)
const { filter, pause, resume } = pausableFilter()
const { undo, redo } = useRefHistory(data, { filter })
It is also good that we are not adding an extra watch for every filter. Another possible API for composables that are watching an input ref is to expect the user to give us a filtered ref, something like:
const data = ref(0)
const { pausableRef, pause, resume } = usePausableRef(data)
const { undo, redo } = useRefHistory(pausableRef)
This only works with API that are tracking an input ref (so we can not use it in useStorage), but we could offer this possibility also.
I think there are other possible APIs we could explore. I thought about letting the user give us the watch
function to be used, but then you may need to use the same options (flush, deep) in several places.
For common cases, we can also bundle filters for convenience like:
const data = ref(0)
const { undo, redo, pause, resume } = usePausableRefHistory(data)
implemented as
export function usePausableRefHistory(ref, options) {
const { filter, pause, resume } = pausableFilter()
return { ...useRefHistory(data, { filter }), pause, resume }
}
So we can still offer the general composable and specialized ones, and users will only pay for what they use. Take the pausable filter extraction as an example to extrapolate to other cases, because the current API allows users to commit using resume(true)
. There may be a better API to also support external triggers. Or the filter may also receive the value, so you can implement validation filters, remove values if they are negative, etc. Or that maybe another option orthogonal to this one.
What do you think? Is something like a filter option worth exploring so we do not need to implement debounce/throttle/pausable in each composable?
Disclaimer: I do not know if I can actually do this myself but looks interesting, so at least I wanted to share it 😃
Since Vue 3 has officially released for a while now. I think it's time for us to roll out from beta aim for a stable release.
Checklist
Preview: https://dev--vueuse.netlify.app/
npm package, powered by
To replace the package with nightly build:
via npm
npm i @vueuse/core@npm:@knightly/vueuse@dev
or edit your package.json
"dependencies": {
"@vueuse/core": "npm:@knightly/vueuse@dev"
}
New @vueuse/router package
Event filter system
pausableWatch
, debouncedWatch
, thottledWatch
, watchWithFilter
useTransition
- named transition presets are removed. Import them from TransitionPresets
intead. #190
import { useTransition } from '@vueuse/core'
useTransition(baseNumber, {
duration: 1000,
transition: 'easeInOutCubic',
})
Changed to
import { useTransition, TransitionPresets } from '@vueuse/core'
useTransition(baseNumber, {
duration: 1000,
transition: TransitionPresets.easeInOutCubic,
})
asyncComputed
- evaluating state is now passed through arguments instead of returning tuple
import { asyncComputed } from '@vueuse/core'
const [state, evaluating] = asyncComputed(async () => {}, {})
Changed to
import { asyncComputed } from '@vueuse/core'
const evaluating = ref(false)
const state = asyncComputed(async () => {}, {}, evaluating)
useEventListener
- event target moved from 4th argument to first
import { useEventListener } from '@vueuse/core'
useEventListener('click', handler, undefined, document)
Changed to
import { useEventListener } from '@vueuse/core'
useEventListener(document, 'click', handler)
useRefHistory
- `flush` now default to `pre`, returned `current` renamed to `source`, hisotry point `value` renamed to `snapshot`
useWebWorkerFn
- `workerStatus` changed from enum to literal unions
import { useWebWorkerFn, WorkStatus } from '@vueuse/core'
const { workerStatus } = useWebWorkerFn(fn)
workerStatus.value === WorkStatus.running
Changed to
import { useWebWorkerFn } from '@vueuse/core'
const { workerStatus } = useWebWorkerFn(fn)
workerStatus.value === 'RUNNING'
useNow
import { useNow } from '@vueuse/core'
const now = useNow()
Changed to
import { useTimestamp } from '@vueuse/core'
const { timestamp: now, pause, resume } = useTimestamp()
useRaf
useTimeout / useInterval
- returned `activated` renamed to `isActive`
useRafFn
- `start` / `stop` renamed to `resume` / `pause`
useXXXObserver
- API changes
Refer to docs and types for more details.
The type definition file for the Vue 3 version of Vueuse attempts to import @vue/composition-api
which causes errors at build time. I don't believe this package is needed for Vue 3 and installing it causes more errors as it depends on Vue 2
Relevant Packages:
"@vueuse/core": "^3.0.34",
"core-js": "^3.6.4",
"vue": "^3.0.0-beta.17"
Error Log:
ERROR Failed to compile with 2 errors5:22:59 AM
1:22:59 AM: error in /opt/build/repo/node_modules/@vueuse/core/index.d.ts
1:22:59 AM: ERROR in /opt/build/repo/node_modules/@vueuse/core/index.d.ts(1,51):
1:22:59 AM: 1:51 Cannot find module '@vue/composition-api' or its corresponding type declarations.
1:22:59 AM: > 1 | import { Ref, WatchStopHandle, ComputedRef } from '@vue/composition-api';
1:22:59 AM: | ^
1:22:59 AM: 2 | import { Ref as Ref$1 } from '@vue/runtime-dom';
1:22:59 AM: 3 |
1:22:59 AM: 4 | declare function createGlobalState<T extends object>(factory: () => T): () => T;
1:22:59 AM: error in /opt/build/repo/node_modules/@vueuse/core/index.d.ts
1:22:59 AM: ERROR in /opt/build/repo/node_modules/@vueuse/core/index.d.ts(7,23):
1:22:59 AM: 7:23 Cannot find module '@vue/composition-api' or its corresponding type declarations.
1:22:59 AM: 5 |
1:22:59 AM: 6 | declare function useAsyncState<T>(promise: Promise<T>, defaultState: T, delay?: number, catchFn?: (e: Error) => void): {
1:22:59 AM: > 7 | state: Ref<import("@vue/composition-api").UnwrapRef<T>>;
1:22:59 AM: | ^
1:22:59 AM: 8 | ready: Ref<boolean>;
1:22:59 AM: 9 | };
The functions useLocalStorage and useSessionStorage offer TS signatures that accept a third argument storage
. However, it looks to me as if this third argument is never used.
ERROR in .../node_modules/@vueuse/core/dist/index.d.ts(1,23):
1:23 Cannot find type definition file for 'resize-observer-browser'.
> 1 | /// <reference types="resize-observer-browser" />
| ^
2 | import { Ref, WatchStopHandle, ComputedRef, WatchOptions } from 'vue-demi';
3 | import { Ref as Ref$1, UnwrapRef, WatchStopHandle as WatchStopHandle$1, ComputedRef as ComputedRef$1 } from 'vue-demi';
4 | export * from '@vueuse/shared';
ERROR in .../node_modules/@vueuse/core/dist/index.d.ts(377,87):
377:87 Cannot find name 'ResizeObserverCallback'.
375 | declare function useRefHistory<Raw, Serialized = Raw>(current: Ref<Raw>, options?: UseRefHistoryOptions<Raw, Serialized>): UseRefHistoryReturn<Raw, Serialized>;
376 |
> 377 | declare function useResizeObserver(el: Ref<HTMLElement | null | undefined>, callback: ResizeObserverCallback): {
| ^
378 | stop: WatchStopHandle$1;
379 | };
380 |
Version: typescript 4.0.3
This is a review of the current usage of flush timing in vueuse. I think I understand better the reason the previous default for useRefHistory
was 'sync'
now. If we would have called this composable watchRefHistory
, I think it will be easier to see why I pushed for 'pre'. If the name would be computedRefHistory
, then 'sync'
would be better. I wonder if using "watch" as prefix instead of "use" is not better, but maybe if the documentation is clear this is not a problem.
controlledComputed
is using flush: 'sync'
and it is not configurable, I think this is correct because it is the way computed
works.
syncRef
defaults to 'sync'
, but in the docs it says the default is 'post'.
Because the name is syncRef, it is kind of hard to not use 'sync' as the default here. I think it also should behave like computed. Also, bySyncRef
is not configurable and is using 'sync'
I can send a PR to change the default in the docs to 'sync'
useStorage
is using 'post'
as its default and it is not configurable. Was 'post'
used because there was a limitation about making flush configurable for this one?
when
is using 'sync'
as its default, but it looks more like a watcher to me. I think we could change its default to 'pre' to align it to the watch API
Error:
139:44 No overload matches this call.
Overload 1 of 2, '(docRef: DocumentReference<TaskList[]>, errorHandler?: ((err: Error) => void) | undefined): Ref<TaskList[] | null>', gave the following error.
Argument of type 'CollectionReference<DocumentData>' is not assignable to parameter of type 'DocumentReference<TaskList[]>'.
Type 'CollectionReference<DocumentData>' is missing the following properties from type 'DocumentReference<TaskList[]>': collection, set, update, delete
Overload 2 of 2, '(docRef: Query<TaskList[]>, errorHandler?: ((err: Error) => void) | undefined): Ref<TaskList[][]>', gave the following error.
Argument of type 'CollectionReference<DocumentData>' is not assignable to parameter of type 'Query<TaskList[]>'.
The types returned by 'where(...)' are incompatible between these types.
Type 'Query<DocumentData>' is not assignable to type 'Query<TaskList[]>'.
Type 'DocumentData' is missing the following properties from type 'TaskList[]': length, pop, push, concat, and 28 more.
Code:
type ID = string
interface Task {
id: ID
title: string
isDone: boolean
}
interface TaskList {
id: ID
title: string
items: Task[]
}
const tasksCollection = db
.collection('users')
.doc(userId)
.collection('tasks')
const tasks = useFirestore<TaskList[]>(tasksCollection)
versions:
"vue": "^2.6.11",
"typescript": "^3.9.2",
"firebase": "^7.14.4",
"@vue/composition-api": "^0.3.4",
"@vueuse/core": "^2.0.27",
"@vueuse/firebase": "^2.0.27",
Just like https://github.com/reactivestack/cookies/tree/master/packages/react-cookie but in Vue style
I already wrote a composition-api wrapper for universal-cookie module in my work project and want to add pull request to vueuse with this wrapper
But it would require universal-cookie
as peerDependency
@antfu what do you think about third party library?
Hello i wanna add an addon to vue use to use rxjs like
import { useSubscription, from, fromEvent, toObserver } from "@vueuse/rx"
import { interval, Subject } from "rxjs"
import { takeUntil, mapTo } from "rxjs/operators"
...
const button = ref<HtmlButtonElement>(null)
// or
const button = new Subject()
const counter = ref<number>(0)
useSubscription(
from(counter).subscribe(v => console.log(v))
)
useSubscription( // it allows auto unsubscribe
interval(1000).pipe(
takeUntil(fromEvent(button, 'click')),
//or
takeUntil(button),
mapTo(1),
).subscribe(toObserver(counter))
)
...
<button ref="button" />
or
<button @click="button.next" />
Hello!
Just letting you know that here y.value
is currently set to event.pageX
and event.touches[0].clientX
. There's also kind of the same problem a bit further down with elY
.
Right now this causes y
and elementY
to return x
and elementX
respectively.
Thank you for your work!
Edit: I actually noticed this because I thought useParallax() was acting weird and indeed it looks like it's because of useMouseInElement() and elementY.
Hi!
What's actually the recommend way to add composables from @vueuse/core to a @vueuse addon?
If I'm going to add for example an addon @vueuse/myaddon
and using useLocalStorage
from @vueuse/core
I see two options:
Option 1 - relative:
Via '../../composables/useLocalStorage' the useLocalStorage
. Here the functions gets bundled in @vueuse/aws
too
which is not necessarily wanted.
Option 2 - via package
'from @vueuse/core' which requires to add @vueuse/core
to @vueuse/core
as dependency including updating packages.json
.
I would prefer first option 1 without bundling the function twice. Any ideas?
Global dependencies such as window
, document
, navigator
should be configurable. #173
This is a checklist of all the functions of VueUse. It's is useful for review or making changes the go through every function.
In the latest beta, StopHandle
has been renamed to WatchStopHandle
which means that @vueuse
currently causes a type error.
A follow up to the conversation started here https://github.com/antfu/vueuse/issues/166#issuecomment-723396628. Our useTransition
behavior can use a bit of polishing before the upcoming stable release. I'm using this issue just as a place to keep track of things.
useRafFn
usage out of watch
callbackIn my case 0
is the array index which it is rather common I think. Instead default value is used - https://github.com/antfu/vueuse/blob/master/packages/core/useStorage/index.ts#L9-L11
Hi, sorry I know I've been spamming this repo a bit lately, but I've got just one more util if you're open to it. I'd like to add a util to detect if the window is active / minimized. This can be useful for things like auto-pausing media, updating the document title, etc...
// hidden and visibility would be reactive aliases of
// document.hidden and document.visibilityState
const { hidden, visibility } = usePageVisibility({
onChange() {
// ...
},
onHide() {
// ...
},
onShow() {
// ...
}
});
When using the current version of this package and TypeScript 3.7.4, I get the following error on compilation:
ERROR in /my/folder/node_modules/@vueuse/core/index.d.ts(201,138):
201:138 Cannot find name 'State'.
199 | name: DescriptorNamePolyfill;
200 | };
> 201 | declare function usePermission(permissionDesc: GeneralPermissionDescriptor | PermissionDescriptor['name'] | DescriptorNamePolyfill): Ref<State>;
| ^
202 |
203 | declare function usePreferredColorScheme(): Readonly<Ref<"dark" | "light" | "no-preference">>;
204 |
This appears to be because the function signature is exported but not the type from usePermission
:
In my usecase,
setup() {
const amount = ref<number>(0);
const { data, close, status } = useEventSource(
"http://localhost:2222/cash"
);
watch(data, (data, _) => {
amount.value = Number(data);
});
return { amount: computed(() => amount.value), close, status };
}
I started the connection on setup and click to close the EventSource, but there is still "pending" on devtool even if the status turn into CLOSED.
In my own useEventSource code below, the connection can be closed correctly with status "canceled" on devtool.
export function useEventSource(url: string) {
const state = ref<string>("");
const source = new EventSource(url);
source.onopen = e => {
console.log("event source opened");
};
source.onmessage = function (e) {
state.value = e.data;
};
source.onerror = function () {
console.log("EventSource failed.");
source.close();
};
const close = () => {
source.close();
};
return {
state: computed(() => state.value),
close
};
}
In my nodejs backend, the difference between useEventSource in the project and my useEventSource code is that my case can correctly print "client close the connection".
app.get("/cash", function (req, res) {
res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive"
});
res.connection.setTimeout(0);
console.log("start casting coins");
req.on("close", () => {
console.log("client close the connection");
});
});
I read the source code but I still don't know how to fix it and what's the difference they are.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.