Last active
September 14, 2023 08:59
-
-
Save Akryum/2670684086c92b846ba3be657243435f to your computer and use it in GitHub Desktop.
Eager Vue computed property - use for cheap computed properties that always update but that don't trigger updates when their value doesn't change
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function useEagerComputed() { | |
const properties = [] | |
function eagerComputed(definitions) { | |
const computedProps = {} | |
for (const key in definitions) { | |
const effect = definitions[key] | |
properties.push({ key, effect }) | |
computedProps[key] = function () { | |
return this.$data[key] | |
} | |
} | |
return computedProps | |
} | |
const mixin = { | |
data() { | |
const data = {} | |
for (const prop of properties) { | |
data[prop.key] = undefined | |
} | |
return data | |
}, | |
created() { | |
for (const prop of properties) { | |
this.$watch(prop.effect.bind(this), (value) => { | |
this.$data[prop.key] = value | |
}) | |
} | |
} | |
} | |
return { | |
mixin, | |
eagerComputed | |
} | |
} | |
// Usage in component: | |
const { mixin, eagerComputed } = useEagerComputed() | |
export default { | |
name: 'HelloWorld', | |
mixins: [mixin], | |
data() { | |
return { | |
loadingId: 0, | |
id: 0 | |
} | |
}, | |
methods: { | |
update() { | |
this.loadingId = (this.loadingId + 1) % 3 | |
} | |
}, | |
computed: { | |
...eagerComputed({ | |
isLoading() { | |
return this.loadingId === this.id | |
} | |
}), | |
myObj() { | |
console.log('computation') | |
return { | |
isLoading: this.isLoading | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function eagerComputedMixin<T = any> (key: string, effect: () => T) { | |
return { | |
data () { | |
return { | |
[key]: undefined, | |
} | |
}, | |
created () { | |
this.$watch(effect.bind(this), (value) => { | |
this.$data[key] = value | |
}) | |
}, | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { watchEffect, readonly } from '@vue/composition-api' | |
export function eagerComputed<T = any> (effect: () => T) { | |
const holder = ref<T>() | |
watchEffect(() => { | |
holder.value = effect() | |
}) | |
return readonly(holder) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { watchEffect, readonly } from 'vue' | |
export function eagerComputed<T = any> (effect: () => T) { | |
const holder = ref<T>() | |
watchEffect(() => { | |
holder.value = effect() | |
}) | |
return readonly(holder) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example with Vue 2: https://codesandbox.io/s/vue-eager-computed-vue2-f7eud?file=/src/components/HelloWorld.vue:147-697