├── .gitignore ├── index.js ├── package-lock.json ├── package.json └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | export function createPlugin({ ref }) { 2 | function plugin(app, ops) { 3 | const methods = {}; 4 | const computed = {}; 5 | 6 | for (let [key, func] of Object.entries(ops)) { 7 | 8 | // 1. add original function to methods 9 | 10 | const $fetch = 'asyncomp_fetch_' + key; 11 | methods[$fetch] = func; 12 | 13 | // 2. create computed property that uses original function to asynchronously fetch the value 14 | // and asssign it to the Vue.ref instance 15 | 16 | const $ref = ref(null); 17 | function cfetch() { 18 | this[$fetch]($ref); 19 | return $ref; 20 | } 21 | 22 | // 3. create computed propery with the original function name that uses previous computed property 23 | // to return Vue's ref.value 24 | 25 | const $cfetch = 'asyncomp_cfetch_' + key; 26 | computed[$cfetch] = cfetch; 27 | 28 | function comp() { 29 | return this[$cfetch].value; 30 | } 31 | computed[key] = comp; 32 | } 33 | app.mixin({ methods, computed }); 34 | } 35 | return plugin 36 | } 37 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue3-async-computed", 3 | "version": "3.0.0", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue3-async-computed", 3 | "version": "3.0.0", 4 | "description": "This Vue 3 plugin allows you to create computed properties that are computed asynchronously", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo todo" 8 | }, 9 | "keywords": [ 10 | "vue", 11 | "vue3", 12 | "async", 13 | "computed" 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/mainclass/vue3-async-computed.git" 18 | }, 19 | "homepage": "https://github.com/mainclass/vue3-async-computed#readme", 20 | "bugs": { 21 | "url": "https://github.com/mainclass/vue3-async-computed/issues" 22 | }, 23 | "author": "Andrii Ka ", 24 | "license": "ISC", 25 | "peerDependencies": { 26 | "vue": ">=3.0.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # vue3-async-computed 2 | 3 | This Vue 3 plugin allows you to create computed properties that are computed asynchronously. 4 | 5 | ```js 6 | import * as Vue from 'vue'; 7 | import * as AsyncComputed from 'vue3-async-computed'; 8 | 9 | const asyncComputed = AsyncComputed.createPlugin({ ref: Vue.ref }); 10 | 11 | Vue.createApp({ 12 | 13 | data() { 14 | return { 15 | userID: 1, 16 | } 17 | }, 18 | 19 | }).use(asyncComputed, { 20 | 21 | async profile(result) { 22 | result.value = `loading profile for user ${this.userID}...`; 23 | const response = await fetch(`https://httpbin.org/get?userID=${this.userID}`); 24 | const data = await response.json(); 25 | result.value = data; 26 | }, 27 | 28 | }).mount('#app'); 29 | ``` 30 | 31 | And then, in HTML: 32 | 33 | ```html 34 |
{{ userID }}: {{ profile }}
35 | ``` 36 | 37 | ## Install 38 | 39 | Install using `npm install vue3-async-computed` 40 | 41 | ## Examples 42 | 43 | - Basic example, the app displays price information for any selected crypto currency: [JSFiddle](https://jsfiddle.net/andriika/otagfzjL/) 44 | 45 | ## Todo 46 | Describe how to approach manual re-calculation of the async computed properties. Provide an example. 47 | --------------------------------------------------------------------------------