How to listen emit event in parent component in vue3

Viewed 4672

I want to pass event from child comment to parent. I did same thing in vue2 but i don't know how to that in vue3.

This one is child component setup method.

      setup(props, { emit }) {
            const router = useRouter();
            const form = ref(
                {
                    email: "ajay@gmail.com",
                    password: "123456789",
                    isLoading: false,
                },
            );
            const user = ref("");
            const error = ref("");

            function login() {
                User.login(this.form).then(() => {
                    emit('login', true);
                   // this.$root.$emit("login", true);  -- vue2

                   localStorage.setItem("auth", "true");
                   router.push('/dashboard');
                })
                .catch(error => {});
            }

            return { form, login, user, error};
       }

from here emit login method and i want to listen in parent comment.

this is parent component, emit.on method not working here

  setup(props, { emit }) {
        const router = useRouter();
        const state = reactive({
            isLoggedIn: false,
        });

        onMounted(async () => {
            emit.on("login", () => {   // `vue2` this.$root.$on("login"`
                this.isLoggedIn = true;
            });
          
        });
1 Answers

In parent component you should add a handler for that emitted event :

<child @login="onLogin"></child>
 setup(props, { emit }) {
        const router = useRouter();
        const state = reactive({
            isLoggedIn: false,
        });
 
   function onLogin(){
      state.isLoggedIn=true,
    }

   return{state,onLogin}

} 

Or make a composable function named useAuth in separate file :

import {reactive} from 'vue'

   const state = reactive({
            isLoggedIn: false,
        });
const useAuth=()=>{
  
   function onLogin(){
         state.isLogged=true;
    }
return {state,onLogin}
}

export default useAuth();

then import the function inside the two components :

child :

import useAuth from './useAuth'
....
      setup(props, { emit }) {
            const router = useRouter();
             const {useAuth} =useAuth();
         ....
      function login() {
                User.login(this.form).then(() => {
                    onLogin() //will call the nested function that set loggedIn to true
                

                   localStorage.setItem("auth", "true");
                   router.push('/dashboard');
                })
                .catch(error => {});
            }

in parent :

import useAuth from './useAuth'
....
  setup(props, { emit }) {
        const router = useRouter();
       const {state} =useAuth();
       //it replaces your local state 

Related