Vue 组件:$emitting 不适用于父子组件。我做错了啥?

Posted

技术标签:

【中文标题】Vue 组件:$emitting 不适用于父子组件。我做错了啥?【英文标题】:Vue components: $emitting not working for parent-child components. What I'm doing wrong?Vue 组件:$emitting 不适用于父子组件。我做错了什么? 【发布时间】:2022-01-05 12:25:27 【问题描述】:

我有一个登录组件,我在 App.vue 主 vue 组件中调用它。 在登录 vue 中,当我单击必须借助 vue js 路由器激活另一个 vue 组件的任何按钮时,必须将登录页面替换为该新的 vue 组件。所以我搜索了解决方案,但没有找到任何有效的解决方案。有趣的事情......解决方案存在,但不知何故它们对我不起作用。我想我错过了一些东西,但究竟是什么?这是我试图找出哪里不对劲的第二天。一件事有效,但作为野蛮人方法 - v-on:click.native 在登录 vue 中的任何点击后隐藏登录 vue,但这不是我想要的。

重要!我在 laravel 项目中使用 vue js。 Laravel 版本 8 和 vue js 版本 2

这是我的代码

登录.vue

<template>
<div id="login">
    <header-nav></header-nav>
    ...
                    <form>
                       ...
                            <label>
                                <input type="email" v-model="email" name="email" class="form-control" placeholder="email">
                            </label>
                        ...
                            <label>
                                <input type="password" v-model = "password" name="password" class="form-control" placeholder="password">
                            </label>
                        ...
                            <label>
                                <input type="checkbox">
                            </label>Remember Me
                        ...
                            <input type="submit" v-on:click.prevent="login" value="Login" class="btn float-right login_btn">
                       ...
                    </form>
                <div class="card-footer">
                    <div class="d-flex justify-content-center links">
                        Don't have an account?
                        <router-link to="register" v-on:click.prevent='hideLogin'>Sign Up</router-link>
                    </div>
                    <div class="d-flex justify-content-center">
                        <a href="#">Forgot your password?</a>
                    </div>
                </div>
</div>
</template>

<script>

import HeaderNav from "../layout/HeaderNav";

export default 
    name: "Login",
    components: HeaderNav,
    data: () => 
        return 
            email: '',
            password: ''
        
    ,

    methods:
        login()
            this.$store.dispatch('users/login', email: this.email, password: this.password)
        ,

        hideLogin()
            this.$emit('hideLogin');
            console.log('Hide login');
        
    ,

    template: HeaderNav


</script>  

App.vue

<template>
    <div>
        <login v-if="!isHidden" v-on:hideLogin="isHidden = true"></login>
        <router-view></router-view>
    </div>
</template>

<script>
    import Login from "./auth/Login";

    export default 
        name: "App",
        components: 
            Login
        ,
        data () 
            return 
                isHidden: false
            
        ,
    
</script> 

【问题讨论】:

尝试在路径前加上/,比如&lt;router-link to="/register" 您是否将v-on:click.native 添加到路由器链接? @BoussadjraBrahim 路由器有效。隐藏不想工作。 Register.vue 打开,但它位于 Login.vue 下面而不是替换它。我明白它为什么会在下面,这就是为什么我试图通过事件监听器隐藏登录。 @Rwd 我猜它有效!地狱......我在登录组件而不是路由器链接上写了click.native!稍等一下,我想再试一次以确保它解决了我的问题。 【参考方案1】:

正如this post 中提到的那样,使用click.native 是您需要使用router-link 来监听onclick 事件,例如

<router-link to="register" v-on:click.native='hideLogin'>Sign Up</router-link>

话虽如此,另一个常见的选择是监听路由器本身的变化并在路由变化时关闭模型:

一种方法是更新hideLogin 文件中的hideLogin 逻辑:

router-link 中移除点击监听器并为$route 添加一个监听器

export default 
    name: "Login",
    components: HeaderNav,
    data: () => 
        return 
            email: '',
            password: ''
        
    ,

    methods: 
        login() 
            this.$store.dispatch('users/login', email: this.email, password: this.password)
        ,

        hideLogin() 
            this.$emit('hideLogin');
            console.log('Hide login');
        
    ,

    template: HeaderNav,
    
    watch: 
        $route() 
            this.hideLogin();
        
    

这样,当您导航到register 路由(或任何其他路由)时,将调用hideLogin 方法。


仅供参考,您可以将v-on: 替换为@,例如@click.native.

【讨论】:

非常感谢我的朋友!!!你是狙击手!一枪直接瞄准! @RubenKubalyan 很高兴我能帮上忙! :)

以上是关于Vue 组件:$emitting 不适用于父子组件。我做错了啥?的主要内容,如果未能解决你的问题,请参考以下文章

vue组件通信

Vue父子组件通信之$emit(基于vue2.5,ES6)

Vue - 父子组件通信 - $emit传多个参数父组件如何接收

vue中 关于$emit的用法(父子组件传值)

vue的$emit 与$on父子组件与兄弟组件的之间通信

vue 中父子组件传值:props和$emit