useObjectModel.ts (999B)
1 import { ref, watch } from 'vue'; 2 import type { Ref } from 'vue'; 3 4 import { deepCopy, deepEqual } from '@/core/utils'; 5 6 /* 7 * Generate an internal ref that implements support for v-model with objects 8 * @param {Function} prop A function returning the prop 9 * @param {Function} emit A function for emitting update events 10 * @returns {Ref<object>} The internal ref 11 */ 12 export default function defineObjectModel<T>(prop: () => T, emit: (x: T) => void): Ref<T> { 13 /** 14 * The internal value 15 */ 16 const internalValue: Ref<T> = ref<T>(prop()) as Ref<T>; 17 18 /** 19 * Update the internal value when the component value changes 20 */ 21 watch(prop, (newValue: T) => { 22 if (!deepEqual<T>(internalValue.value, newValue)) { 23 internalValue.value = deepCopy<T>(newValue); 24 } 25 }, { deep: true }); 26 27 /** 28 * Update the component value when the internal value changes 29 */ 30 watch(internalValue, (newValue: T) => { 31 emit(deepCopy<T>(newValue)); 32 }, { deep: true }); 33 34 return internalValue; 35 }