简体   繁体   English

与Vue路由器配合使用Vue 2中的可重用组件

[英]Using reusable components in Vue 2 in comination with vue router

I seem to do something wrong when I'm trying to target child components in nested router-views with click events. 当我尝试使用点击事件定位嵌套路由器视图中的子组件时,我似乎做错了。

Current situation: I have a component one and component two. 现状:我有一个组成部分和第二个组成部分。 Both have a child component called dialog. 两者都有一个称为对话框的子组件。

Component one and two are being loaded through a router-view in parent component dashboard. 组件一和组件二是通过父组件仪表板中的路由器视图加载的。 Each view has a button to show their child component "Modal". 每个视图都有一个按钮来显示其子组件“模态”。

The button seems to work fine on the view that gets loaded on pageload. 该按钮似乎在页面加载时加载的视图上正常工作。 But as soon as I switch routes the showModal function does not know the dialog element from which view to target. 但是,一旦我切换了路由,showModal函数就不知道要从哪个视图定向到该对话框元素。

I thought the components would be destroyed and rebuilt upon switching routes but apparently not. 我以为组件会在切换路线时被破坏并重建,但显然不会。

Here is my code, I hope someone is able to help: 这是我的代码,希望有人能够提供帮助:

App 应用程式

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)
/**
 * First we will load all of this project's JavaScript dependencies which
 * include Vue and Vue Resource. This gives a great starting point for
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap')

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the body of the page. From here, you may begin adding components to
 * the application, or feel free to tweak this setup for your needs.
 */

Vue.component('vuetest', require('./components/vuetest.vue'))

const Dashboard = require('./components/dashboard.vue')
const FirstRoute = require('./components/firstroute.vue')
const Second = require('./components/secondroute.vue')

const routes = [
    {
        path: '/dashboard',
        component: Dashboard,
        children: [
            {
                path: 'firstview',
                name: 'firstview',
                canReuse: false,
                component: FirstRoute
            },
            {
                path: 'secondview',
                name: 'secondview',
                canReuse: false,
                component: Second
            }
        ]
    }
]

const router = new VueRouter({
    routes // short for routes: routes
})

window.EventHub = new Vue()

const app = new Vue({
    el: '#app',
    router
});

Vuetest Vuetest

<template>
    <div>
        <h1>Vue Test</h1>
        <router-view></router-view>
    </div>
</template>

<script>
    export default {
        created() {

        },
        mounted() {
            console.log('Component ready.')
        }
    }
</script>

Dashboard Route 仪表板路线

<template>
    <div>
        <h1>Dashboard</h1>
        <navigation></navigation>
        <router-view></router-view>
    </div>
</template>
<script>
    Vue.component('navigation', require('./navigation.vue'))
</script>

Navigation 导航

<template>
    <div>
        <router-link :to="{ name: 'firstview' }">first</router-link>
        <router-link :to="{ name: 'secondview' }">second</router-link>
    </div>
</template>

First Route 第一路线

<template>
    <div class="firstroute">
        <h1>First Route</h1>
        <button class="showmodal" v-on:click="showModal">Showmodal</button>
        <modal></modal>
    </div>
</template>
<script>
    export default {
        methods: {
            showModal: function () {
                EventHub.$emit('showModal')
            }
        }
    }
    Vue.component('modal', require('./modal.vue'));
</script>

Second Route 第二条路线

<template>
    <div class="secondroute">
        <h1>Second Route</h1>
        <button class="showmodal" v-on:click="showModal">Showmodal</button>
        <modal></modal>
    </div>
</template>
<script>
    export default {
        methods: {
            showModal: function () {
                EventHub.$emit('showModal')
            }
        }
    }
    Vue.component('modal', require('./modal.vue'));
</script>

Modal 语气

<template>
    <div class="dialog hidden">
        Dialog
    </div>
</template>
<style>
    .hidden {
        display: none;
    }
</style>
<script>
    export default{
        created() {
            EventHub.$on('showModal', this.showModal);
        },
        methods: {
            showModal: function() {
                document.querySelector('.dialog').classList.toggle('hidden');
            }
        }
    }
</script>

I really appreciate any help. 我非常感谢您的帮助。

tiny recomendations 小小的建议

':class' directive instead of native code: ':class'指令而不是本机代码:

document.querySelector('.dialog').classList.toggle('hidden');

components: 组件:

import Modal from './modal' 

export default {
  ...
  components:
    Modal
  }
  ...
}

instead of 代替

Vue.component('modal', require('./modal.vue'));

.. also Vuex is a good point for this case .. Vuex在这种情况下也是一个好点

additional: 额外:

https://github.com/vuejs/vue-devtools https://github.com/vuejs/vue-devtools

https://jsfiddle.net/uLaj738k/2/ https://jsfiddle.net/uLaj738k/2/

As it turns out the problem was the moment I called the querySelector method. 事实证明,问题出在我调用querySelector方法的那一刻。

Assigning the .dialog element to a const in mounted() solved my problem. .dialog元素分配给mounted()的const解决了我的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM