Vue.js 拖动和单击时的过渡

Vue.js transition on drag and click

我正在尝试构建一个日历组件,当我点击 next 或 prev 我想要一个过渡时,我也想在滑动时添加一个过渡,但是我无法使 vue 过渡工作。我只有一个元素(当前月份),在我单击下一步或上一个之后,它所做的只是更改数据。 为了能够添加动态转换:翻译,因为我需要在滑动时获取鼠标位置,我是否应该创建 3 个元素(上个月、当前月份、下个月)?或者我可以只更改数据吗?

我在 vue 文档上尝试了最简单的示例,但每次单击按钮时,转换都不起作用。

 <transition name="home">
    <Calendar></Calendar>
  </transition>

.home-enter-active,
.home-leave-active {
    transition: opacity 4s;
}


.home-enter,
.home-leave-active {
    opacity: 0;
}

这是我的日历组件。

<template>
    <div id="calendar" class="calendar">
        <div>
            <div>{{ state.currentMonthName }}</div>
            <div>{{ state.currentYear }}</div>
            <div>
                <ul class="weekDays">
                    <li v-for="days in state.weekNames" :key="days">{{ days }}</li>
                </ul>
            </div>
            <div class="days">
                <span
                    @click="
                        selectDate(state.currentYear, state.currentMonth - 1, state.getLastDayOfPreviousMonth - state.startDay + day);
                        goPrev();
                    "
                    class="lastMonth"
                    v-for="day in state.startDay"
                    :key="'empty' + day"
                    >{{ state.getLastDayOfPreviousMonth - state.startDay + day }}</span
                >
                <span :class="currenDateClass(state.currentYear, state.currentMonth, day)" @click="selectDate(state.currentYear, state.currentMonth, day)" v-for="day in state.getLastDayOfMonth" :key="day">{{ day }}</span>
                <span
                    @click="
                        goNext();
                        selectDate(state.currentYear, state.currentMonth, day);
                    "
                    class="lastMonth"
                    v-for="day in 6 - state.endDay"
                    :key="'nextMonth' + day"
                    >{{ day }}</span
                >
            </div>
        </div>

        <button @click="goPrev">Prev</button>
        <button @click="goNext">Next</button>
    </div>
</template>

您的转换包装了 Calendar 组件,但它永远不会改变。只包装组件发生变化的部分。来自 docs:

Vue provides a variety of ways to apply transition effects when items are inserted, updated, or removed from the DOM

在他们的示例中,转换用 v-if 包装了一个元素,其中 adds/removes 项来自 DOM,因此应用了转换。在组件内围绕发生变化的内容移动过渡。比如月上的一个过渡:

<template>
  ...
  <transition name="home">
    <div :key="state.currentMonthName">{{ state.currentMonthName }}</div>
  </transition>
  ...
</template>

注意:过渡必须包裹一个元素。如果没有 div 或其他一些标签,这将无法工作。

key 道具强制 div 在月份更改时重新呈现,以便触发转换。这是 key documentation 中的建议。使用 key,你可以包装任何你想要的东西,当键改变时它会全部重新渲染。

这是一个使用您的转换 CSS 和一个更简单的模板的演示:

Vue.component('Calendar', {
  template: `
    <div id="calendar" class="calendar">
        <div>
            <transition name="home">
                <div :key="indexMonth">{{ months[indexMonth] }}</div>
            </transition>
        </div>
 
        <button @click="goPrev">Prev</button>
        <button @click="goNext">Next</button>
    </div>
  `,
  data() {
    return {
      months: [ "January", "February", "March", "April", "May", "June",
               "July", "August", "September", "October", "November", "December" ],
      indexMonth: 0
    }
  },
  methods: {
    goPrev() {
        this.indexMonth = this.indexMonth === 0 ? this.months.length - 1 : this.indexMonth - 1;
    },
    goNext() {
        this.indexMonth = this.indexMonth === 11 ? 0 : this.indexMonth + 1;
    }
  }
})

/***** APP *****/
new Vue({
  el: "#app"
});
.home-enter-active,
.home-leave-active {
    transition: opacity 1s;
}

.home-enter,
.home-leave-active {
    opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
    <Calendar></Calendar>
</div>