vue-final/vue-final-modal

How to handle reactive props/attrs between parent and child components

retikaellis opened this issue · 3 comments

Version

vue-final-modal: 4.5.3
vue: 3.4.15
nuxt: 3.10.0

Hi! First of all, thank you so much for your work. I'm starting to try the modal in a nuxt 3 app, using useModal(). I don't know if I'm missing something, but I realized the props you pass as attrs are not reactive/are not changing in the child component (ModalConfirm in this case). Here's a code sample. What I'm actually trying to achieve is to change a isLoading boolean prop, so I can show a loading spinner on the confirm button, while making an async request to my API on the onConfirm action.

const modalTitle = ref('')

const { open, close } = useModal({ component: ModalConfirm, attrs: { title: modalTitle.value, onClose() { close() }, onConfirm() { modalTitle.value = "Hello" }, }, slots: { default: "Whatever" }, })

I also need reactive props/attrs.

I think I am going to attempt making a wrapping composable that watches any prop changes and updates the props using the patchOptions function provided by useModal

This is function is demonstrated here https://vue-final-modal.org/api/composables/use-modal

Here's my implementation. Seems to work well. @retikaellis

// reactiveModal.ts
import { useModal, type UseModalOptions } from 'vue-final-modal';

type useReactiveModalOptions = UseModalOptions<any> & {
	attrs: ComputedRef;
};

export const useReactiveModal = (options: useReactiveModalOptions) => {
	const modal = useModal(options);
	const { patchOptions } = modal;

	watch(
		() => options.attrs,
		newVal => {
			patchOptions({ attrs: newVal });
		}
	);

	return modal;
};

Works for me:

const modalProps = reactive<ContentProps>({});

const { open, close} = useModal({
  component: ModalContent,
  attrs: modalProps ,
})

const toggleModalHandler = (data: ContentProps) => {
  modalProps.someProp = data.someProp;
  other props
  open();
};