Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Eager Vue computed property - use for cheap computed properties that always update but that don't trigger updates when their value doesn't change
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
}
}
}
}
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
})
},
}
}
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)
}
import { watchEffect, readonly } from 'vue'
export function eagerComputed<T = any> (effect: () => T) {
const holder = ref<T>()
watchEffect(() => {
holder.value = effect()
})
return readonly(holder)
}
@Akryum

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment