Home > database >  custom vue reactive() like customRef()
custom vue reactive() like customRef()

Time:10-23

How to create reactive() object with custom setter (debounced) like with customRef()

CodePudding user response:

You can use computed inside reactive. Namely, you might want to use a Writable Computed (getter/setter):

import { ref, reactive, computed } from 'vue'
const whatever = ref('test')

const state = reactive({
  myProp: computed({
    get() { 
      console.log('myProp was read');
      return whatever.value
    },
    set(val) {
      console.log(`myProp was set to ${val}`)
      whatever.value = val
    }
  })
})

Test:

const { createApp, ref, reactive, computed, toRefs } = Vue
const app = createApp({
  setup() {
    const whatever = ref('test')

    const state = reactive({
      myProp: computed({
        get() { 
          console.log('myProp was read');
          return whatever.value
        },
        set(val) {
          console.log(`myProp was set to ${val}`)
          whatever.value = val
        }
      }),
      emitter: computed({
        get() {
          return true
        },
        set(val) {
          console.log(`I was set to ${val} but I'm not changing value...`)
        }
      })
    })
    return { ...toRefs(state), whatever }
  }
})
app.mount('#app')
<script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js"></script>
<div id="app">
  <input v-model="myProp" />
  <pre v-text="{
    whatever,
    myProp,
    emitter
  }"></pre>
  <button @click="emitter = !emitter">Click me!</button>
</div>

Notice the getter is only called once per change, not once for each place where it's used in <template>.

  • Related