proxiedModel.mjs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. // Composables
  2. import { useToggleScope } from "./toggleScope.mjs"; // Utilities
  3. import { computed, ref, toRaw, watch } from 'vue';
  4. import { getCurrentInstance, toKebabCase } from "../util/index.mjs"; // Types
  5. // Composables
  6. export function useProxiedModel(props, prop, defaultValue) {
  7. let transformIn = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : v => v;
  8. let transformOut = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : v => v;
  9. const vm = getCurrentInstance('useProxiedModel');
  10. const internal = ref(props[prop] !== undefined ? props[prop] : defaultValue);
  11. const kebabProp = toKebabCase(prop);
  12. const checkKebab = kebabProp !== prop;
  13. const isControlled = checkKebab ? computed(() => {
  14. void props[prop];
  15. return !!((vm.vnode.props?.hasOwnProperty(prop) || vm.vnode.props?.hasOwnProperty(kebabProp)) && (vm.vnode.props?.hasOwnProperty(`onUpdate:${prop}`) || vm.vnode.props?.hasOwnProperty(`onUpdate:${kebabProp}`)));
  16. }) : computed(() => {
  17. void props[prop];
  18. return !!(vm.vnode.props?.hasOwnProperty(prop) && vm.vnode.props?.hasOwnProperty(`onUpdate:${prop}`));
  19. });
  20. useToggleScope(() => !isControlled.value, () => {
  21. watch(() => props[prop], val => {
  22. internal.value = val;
  23. });
  24. });
  25. const model = computed({
  26. get() {
  27. const externalValue = props[prop];
  28. return transformIn(isControlled.value ? externalValue : internal.value);
  29. },
  30. set(internalValue) {
  31. const newValue = transformOut(internalValue);
  32. const value = toRaw(isControlled.value ? props[prop] : internal.value);
  33. if (value === newValue || transformIn(value) === internalValue) {
  34. return;
  35. }
  36. internal.value = newValue;
  37. vm?.emit(`update:${prop}`, newValue);
  38. }
  39. });
  40. Object.defineProperty(model, 'externalValue', {
  41. get: () => isControlled.value ? props[prop] : internal.value
  42. });
  43. return model;
  44. }
  45. //# sourceMappingURL=proxiedModel.mjs.map