在切换其中的动态组件后,Vue 2组件重新渲染

时间:2017-01-30 10:33:53

标签: vue.js vuejs2 vue-component vue-loader

我有一个导入其他两个组件的主要组件:

  1. 管理页面
  2. 登录页面
  3. 在主要组件中我有:

    <template>
      <div id="app">
        <component v-bind:is="currentView"></component>
      </div>
    </template>
    
    <script>
    import AdminPage from './components/adminPage/AdminPage'
    import LoginPage from './components/LoginPage'
    
    export default {
      name: 'app',
      components: {
        AdminPage, LoginPage
      },
      data: function() {
        return {
          currentView: 'LoginPage'
        }
      },
      created() {
           this.$bus.$on('eventFromLoginPage', event => {
                this.currentView = "AdminPage";
            });
      }
    }
    </script> 
    

    并且在登录页面中,我有一个向主应用程序发出触发器的方法:

    changeView: function() {
           this.$bus.$emit('eventFromLoginPage');
     }
    

    主要组件由main.js文件调用:

    import Vue from 'vue'
    import App from './App'
    
    Object.defineProperty(Vue.prototype, '$bus', {
        get() {
            return this.$root.bus;
        }
    });
    
    var bus = new Vue({})
    
    new Vue({
      el: '#app',
      template: '<App/>',
      components: { App },
      data: {
        bus: bus
      }
    })
    

    问题在于,虽然当我在登录页面中调用changeView函数时,会发送触发器并且主组件中的视图会根据需要更改为adminPage,但是主页面将被重新呈现并且视图将返回到登录页面。

    问题:为什么在更改“currentView”状态后主要组件会重新渲染,如何将Admin页面保留为视图。

1 个答案:

答案 0 :(得分:2)

  • 在模板内部调用Vue是很奇怪的。在顶级HTML元素上调用它。
  • 仅在事件由发出事件的组件的父链外部的事件处理时使用总线
  • 使用v-on和方法
  • 处理事件

AdminPage = {
  template: '<div>The admin page</div>'
};

LoginPage = {
  template: '<div>The LOGIN page<button @click="doLogin">Login</button></div>',
  methods: {
    doLogin: function() {
      this.$emit('eventFromLoginPage');
    }
  }
};

App = {
  template: '<component v-bind:is="currentView" v-on:eventFromLoginPage="goToAdminPage"></component>',
  components: {
    AdminPage, LoginPage
  },
  data: function() {
    return {
      currentView: 'LoginPage'
    }
  },
  methods: {
    goToAdminPage: function() {
      this.currentView = 'AdminPage';
    }
  }
};

new Vue({
  el: '#app',
  components: {
    App
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>
<div id="app">
  <App></App>
</div>