2

这是场景:

  • 有一个与 vue-router 一起重用的 Page 组件
  • 此 Page 组件包含动态组件,Element1 或 Element2,具体取决于当前页面

当父路由发生变化时,如何在这个动态嵌套组件上触发离开转换?

它应该与下面的代码一起使用,但是当您更改页面时,page beforeRouteLeave并且element leave永远不会打印到控制台。

(参见代码中的 3x------ BUG: never fired -----部分)

const Index = {
  template: `<div id="app">
    <router-link :to="{ path: '1' }">page 1</router-link> | 
    <router-link :to="{ path: '2' }">page 2</router-link>
    <router-view :key="'a' + $route.params.id"></router-view>
  </div>`
};

const Element1 = {
  template: `<transition @enter="transitionEnter" @leave="transitionLeave">
    <div class="element" v-show="show">Element 1</div>
  </transition>`,
  props: {
    show: Boolean
  },
  methods: {
    transitionEnter(el, done) {
      console.log('element 1 enter')
      done()
    },
    transitionLeave(el, done) {
      console.log('------ BUG: never fired -----')
      console.log('element 1 leave')
      done()
    }
  }
};

const Element2 = {
  template: `<transition @enter="transitionEnter" @leave="transitionLeave">
    <div class="element" v-show="show">Element 2</div>
  </transition>`,
  props: {
    show: Boolean
  },
  methods: {
    transitionEnter(el, done) {
      console.log('element 2 enter')
      done()
    },
    transitionLeave(el, done) {
      console.log('------ BUG: never fired -----')
      console.log('element 2 leave')
      done()
    }
  }
};

const Page = {
  template: `<transition @enter="transitionEnter" @leave="transitionLeave">
    <div>
      <p>page {{ id }}</p>
      <component :is="element" :show="elementShow"></component>
    </div>
  </transition>`,
  components: {
    Element1,
    Element2,
  },
  data() {
    return {
      id: this.$route.params.id,
      elementShow: false,
    }
  },
  computed: {
    element() {
      return 'Element' + this.id
    }
  },
  methods: {
    transitionEnter(el, done) {
      console.log('page', this.id, 'enter');
      done();
    },
    transitionLeave(el, done) {
      console.log('page', this.id, 'leave');
      done();
    },
  },
  mounted() {
    this.elementShow = true
  },
  beforeRouteLeave(to, from, next) {
    console.log('------ BUG: never fired -----')
    console.log('page beforeRouteLeave')
    this.elementShow = false
    setTimeout(next)
  },
};

const App = Vue.extend(Index);

const router = new VueRouter({
  routes: [{
    path: '/:id',
    component: Page
  }, {
    path: '*',
    redirect: '/1'
  }]
})

const app = new App({ router }).$mount('#app');
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app"></div>

4

0 回答 0