Comments (5)
I have the same problem with migrating to vue3. Wile the concept of this library would still work there, it is much simpler to write it using the composite API. This avoids having to install it globally (=> use in libraries, tree shaking) and makes some code cleaner.
This is my current version, written in Typescript
import {reactive, ComputedRef, Ref, computed, watchEffect, WatchStopHandle} from "vue";
enum AsyncStatus {
ERROR = 'error', SUCCESS = 'success', LOADING = 'loading'
}
interface AsyncAccess<T> extends ComputedRef<T> {
status: Ref<AsyncStatus>,
error: Ref<any>,
retry: () => void
}
export function asyncComputed<T> (func: (() => Promise<T>), options: {default?: T | Ref<T>, lazy?: boolean} = {}): AsyncAccess<T | undefined> {
const optionsWithDefaults = {
default: undefined,
lazy: false,
...options
};
const state = reactive({
result: undefined as any | undefined,
status: AsyncStatus.LOADING,
error: null as any,
hasEverRun: false
});
let hasEverRequested = false;
const result = computed<T | undefined>(() => {
if (!hasEverRequested) {
retry();
}
if (state.hasEverRun) {
return state.result;
} else {
return options.default as T | undefined;
}
})
let lastRetryCalled: Symbol | null = null
let stopLast: WatchStopHandle | null = null;
const retry = () => {
hasEverRequested = true;
if (stopLast) {
stopLast();
stopLast = null;
}
stopLast = watchEffect(() => {
let me = Symbol('retry');
lastRetryCalled = me;
state.status = AsyncStatus.LOADING
state.error = null;
func().then(value => {
if (lastRetryCalled === me) {
state.status = AsyncStatus.SUCCESS
state.result = value;
state.error = null;
state.hasEverRun = true;
}
}, error => {
if (lastRetryCalled === me) {
state.status = AsyncStatus.ERROR;
state.error = error;
state.hasEverRun = true;
}
});
})
}
if (!optionsWithDefaults.lazy) {
retry()
}
Object.defineProperty(result, 'status', {
value: computed(() => state.status)
});
Object.defineProperty(result, 'error', {
value: computed(() => state.error)
})
Object.defineProperty(result, 'retry', {
value: retry
})
return result as AsyncAccess<T>;
}
Use it like this:
setup () {
const test = reactive({ counter: 1 })
const aValue = asyncComputed(async () => {
console.log('Computing eager value')
const myCounter = test.counter
await new Promise(resolve => setTimeout(resolve, 2000))
return myCounter
}, { default: 0 })
const lazyValue = asyncComputed(async () => {
console.log('Computing lazy value')
const myCounter = test.counter
await new Promise(resolve => setTimeout(resolve, 2000))
return myCounter
}, { lazy: true })
return {
test, // < current value of test
aValue, // < in the UI, you can write {{ aValue }} to access current value
aStatus: aValue.status, // < allows you to use v-if="aStatus === 'loading'"
lazyValue // use as {{ lazyValue }} in the UI. The value will only load after you attempted to access it
}
}
from vue-async-computed.
In vue3 use can use VueUse to deal with async computed properties
from vue-async-computed.
This is my current version, written in Typescript
Thanks a lot, that works like a charm! I only had to make it export default function
instead of export function
to be able to import in Vue components. Wondering if it is coming out-of-the-box any time soon. It should really.
from vue-async-computed.
They seem to have recently renamed asyncComputed
to computedAsync
, so the new link is VueUse.
npm install --save @vueuse/core
import { ref } from 'vue'
import { computedAsync } from '@vueuse/core'
const name = ref('jack')
const userInfo = computedAsync(
async () => {
return await mockLookUp(name.value)
},
null, // initial state
)
from vue-async-computed.
At the moment (in migration phase) in our project its not a simple as just using asyncComputed from vueuse, tho that will be a refactor goal after initial migration.
Is there any actual reason it wouldn't work in vue3 w/ compat mode?
I forked so I could just allow the peerDependency to allow "vue": "2 - 3"
still in the process of migration but so far it seems fine.
from vue-async-computed.
Related Issues (20)
- Typescript / vue-async-computed Property 'foo' does not exist on type 'CombinedVueInstance<Vue, {...} HOT 2
- Doesn't seem to deep watch properties. HOT 2
- Initial State of Async Call 'updating' set to true when using shouldUpdate()
- Add support to installation as mixin.
- Make Promise as return of method update() or new method updatePromise()
- Provide option to exclude or explicitly list watched properties
- Value getting computed on route changes
- kjidjvtlcdgjj
- Use with Nuxt? HOT 1
- Provide cancel method
- implement set like get
- "this.$options is undefined" is being raised when using vue async computed
- "lazy: true" fails to stop updates HOT 1
- TypeScript support in 3.8.0 HOT 4
- Add vue-async-computed-decorator to README.md HOT 2
- Issue updating reactive variables in asyncComputed HOT 1
- asyncComputed return only default value HOT 2
- how to use this plugin with class based vue components? HOT 2
- Executed without being called, normal computed works different HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from vue-async-computed.