亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Vuejs - 一次一個項目的過渡組輪播動畫

Vuejs - 一次一個項目的過渡組輪播動畫

揚帆大魚 2023-10-14 15:57:23
我正在嘗試使用 Vue 轉換組來實現輪播/幻燈片效果:他們每次都會對一個列表項(步驟)進行動畫處理,其中上一個步驟會上升,而當前的步驟會隨著時間軸的內容而上升。我不確定我想要完成的任務是否可以使用transition-group,因為整個父塊都會動畫,而不是子節點。如果是這樣的話,如果我至少可以為父塊設置動畫,我會很高興。另一個需要注意的是,當我使用transition-groupwithoutv-if或沒有過濾列表時,默認情況下會呈現所有步驟,這不好。這是我的 HTML 結構:<transition-group class="steps-viewport" name="steps" tag="div">? <div v-for="step in currentStep" :key="step.order" class="step-wrapper">? ? <h3 class="is-size-5 mb-6 has-text-grey-light">? ? ? Passo {{ step.order }}? ? </h3>? ? <h1 class="is-size-3">{{ step.title }}</h1>? ? <h2 class="is-size-4 mt-2 has-text-grey">{{ step.headline }}</h2>? ? <component? ? ? class="mt-5"? ? ? v-bind:is="step.component"? ? ? @status-changed="handleStatusChange($event)"? ? ></component>? </div></transition-group>這是我的 CSS:.component-wrapper {? width: 100%;? .steps-viewport {? ? height: calc(100vh - 10rem);? ? overflow: hidden;? ? display: flex;? ? flex-direction: column;? ? .step-wrapper {? ? ? flex: 0 0 calc(100vh - 10rem);? ? ? display: flex;? ? ? justify-content: center;? ? ? flex-direction: column;? ? }? }}最后但并非最不重要的一點是我的組件的腳本:import ProductInfo from "./ProductInfo";export default {? components: {? ? ProductInfo? },? props: {? ? defaultActiveStep: {? ? ? type: Number,? ? ? default: 1? ? }? },? watch: {? ? activeStep() {? ? ? this.$emit("step-changed", this.activeStep);? ? }? },? computed: {? ? currentStep() {? ? ? return this.steps.filter(s => s.order === this.activeStep);? ? }? },? data: () => {? ? return {? ? ? activeStep: 1,? ? ? steps: [? ? ? ? {? ? ? ? ? order: 1,? ? ? ? ? title: "Title 1?",? ? ? ? ? headline:? ? ? ? ? ? "Headline 1",? ? ? ? ? component: "product-info"? ? ? ? },? ? ? ? {? ? ? ? ? order: 2,? ? ? ? ? title: "Title 2",? ? ? ? ? headline:? ? ? ? ? ? "Headline 2.",? ? ? ? ? component: "product-info"? ? ? ? },
查看完整描述

1 回答

?
鳳凰求蠱

TA貢獻1825條經驗 獲得超4個贊

您需要定義特殊的類來針對轉換的不同階段,在本例中為.steps-enter-active(中間轉換狀態)和.steps-enter-to(最終狀態)。

為了使其在頁面加載時發生,您還需要傳遞該appear屬性。


如果你想要整個order塊轉換,你可以這樣做:

new Vue({

  el: '#app',


  computed: {

    currentStep() {

      return this.steps.filter(s => s.order === this.activeStep);

    }

  },


  data: () => {

    return {

      activeStep: 1,

      steps: [{

          order: 1,

          title: "Title 1?",

          headline: "Headline 1",

          component: "product-info"

        },

        {

          order: 2,

          title: "Title 2",

          headline: "Headline 2.",

          component: "product-info"

        },

        {

          order: 3,

          title: "Title 3",

          headline: "Headline 3.",

          component: "product-info"

        },

        {

          order: 4,

          title: "Title 4!",

          headline: "Headline 4",

          component: "product-info"

        }

      ]

    };

  },

});


Vue.config.productionTip = false;

Vue.config.devtools = false;

.component-wrapper {

  width: 100%;

}


.steps-viewport {

  height: calc(100vh - 10rem);

  /* overflow: hidden */

  display: flex;

  flex-direction: column;

}


.step-wrapper {

  flex: 0 0 calc(100vh - 10rem);

  display: flex;

  justify-content: center;

  flex-direction: column;

}


.steps-enter-active {

  opacity: 0;

  transform: translateY(100%);

  transition: all 0.4s;

}


.steps-enter-to {

  opacity: 1;

  transform: translateY(0);

}

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>


<div id="app">

  <transition-group class="steps-viewport" name="steps" tag="div" appear>

    <div v-for="step in currentStep" :key="step.order" class="step-wrapper">

      <h3 class="is-size-5 mb-6 has-text-grey-light">

        Passo {{ step.order }}

      </h3>

      <h1 class="is-size-3">{{ step.title }}</h1>

      <h2 class="is-size-4 mt-2 has-text-grey">{{ step.headline }}</h2>

    </div>

  </transition-group>

</div>

如果您希望其中的每個元素進行過渡,您可以這樣做,添加transition-delay

new Vue({

  el: '#app',


  computed: {

    currentStep() {

      return this.steps.filter(s => s.order === this.activeStep);

    }

  },


  data: () => {

    return {

      activeStep: 1,

      steps: [{

          order: 1,

          title: "Title 1?",

          headline: "Headline 1",

          component: "product-info"

        },

        {

          order: 2,

          title: "Title 2",

          headline: "Headline 2.",

          component: "product-info"

        },

        {

          order: 3,

          title: "Title 3",

          headline: "Headline 3.",

          component: "product-info"

        },

        {

          order: 4,

          title: "Title 4!",

          headline: "Headline 4",

          component: "product-info"

        }

      ]

    };

  },

});


Vue.config.productionTip = false;

Vue.config.devtools = false;

.component-wrapper {

  width: 100%;

}


.steps-viewport {

  height: calc(100vh - 10rem);

  /* overflow: hidden */

  display: flex;

  flex-direction: column;

}


.step-wrapper {

  flex: 0 0 calc(100vh - 10rem);

  display: flex;

  justify-content: center;

  flex-direction: column;

}


.steps-enter-active {

  opacity: 0;

  transform: translateY(100%);

  transition: all 0.4s;

}


.steps-enter-to {

  opacity: 1;

  transform: translateY(0);

}

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>


<div id="app">

  <div v-for="step in currentStep" :key="step.order" class="step-wrapper">

    <transition-group class="steps-viewport" name="steps" tag="div" appear>

      <h3 class="is-size-5 mb-6 has-text-grey-light" key="1">

        Passo {{ step.order }}

      </h3>

      <h1 class="is-size-3" style="transition-delay: 0.1s" key="2">{{ step.title }}</h1>

      <h2 class="is-size-4 mt-2 has-text-grey" style="transition-delay: 0.2s" key="3">{{ step.headline }}</h2>

    </transition-group>

  </div>

</div>

要也轉出,您需要使用transition相反,這樣您就可以使用mode="out-in"它允許元素在下一個進入之前先轉出。

您還需要使用 來定位 CSS 中過渡元素的子元素.steps-enter-active > *。然后,只需添加一個.steps-leave-to定義要離開的狀態的類:

new Vue({

  el: '#app',


  computed: {

    currentStep() {

      return this.steps.filter(s => s.order === this.activeStep);

    }

  },


  methods: {

    nextStep() {

      if (this.activeStep !== this.steps.length) {

        this.activeStep++;

      } else {

        this.activeStep = 1;

      }

    }

  },


  data: () => {

    return {

      activeStep: 1,

      steps: [{

          order: 1,

          title: "Title 1?",

          headline: "Headline 1",

          component: "product-info"

        },

        {

          order: 2,

          title: "Title 2",

          headline: "Headline 2.",

          component: "product-info"

        },

        {

          order: 3,

          title: "Title 3",

          headline: "Headline 3.",

          component: "product-info"

        },

        {

          order: 4,

          title: "Title 4!",

          headline: "Headline 4",

          component: "product-info"

        }

      ]

    };

  },

});


Vue.config.productionTip = false;

Vue.config.devtools = false;

.component-wrapper {

  width: 100%;

}


.steps-viewport {

  height: calc(100vh - 10rem);

  /* overflow: hidden */

  display: flex;

  flex-direction: column;

}


.step-wrapper {

  flex: 0 0 calc(100vh - 10rem);

  display: flex;

  justify-content: center;

  flex-direction: column;

}


.step-wrapper,

.step-wrapper>* {

  transition: all 0.4s;

}


.step-wrapper>h1 {

  transition-delay: 0.1s;

}


.step-wrapper>h2 {

  transition-delay: 0.2s;

}


.steps-enter-active>* {

  opacity: 0;

  transform: translateY(100%);

}


.steps-leave-to>* {

  opacity: 0;

  transform: translateY(-100%);

}


.steps-enter-to>* {

  opacity: 1;

  transform: translateY(0);

}

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>


<div id="app">

  <transition name="steps" mode="out-in" duration="600" appear>

    <div v-for="step in currentStep" :key="step.order" class="step-wrapper">

      <h3 class="is-size-5 mb-6 has-text-grey-light">

        Passo {{ step.order }}

      </h3>

      <h1 class="is-size-3">{{ step.title }}</h1>

      <h2 class="is-size-4 mt-2 has-text-grey">{{ step.headline }}</h2>

    </div>

  </transition>

  <button @click="nextStep()">Next</button>

</div>

最后,為了在添加新元素后讓所有內容順利向上移動,您可以將初始字段包裝在 div 中,將新元素包裝在過渡中,并將第一個 div 的高度減少新元素的高度。

您還需要轉換高度并配置時間(轉換延遲和持續時間屬性)以正確匹配:

new Vue({

  el: '#app',


  computed: {

    currentStep() {

      return this.steps.filter(s => s.order === this.activeStep);

    }

  },


  methods: {

    nextStep() {

      this.$refs.addStep.disabled = false;

      this.extraStep = false;

      this.$refs.addAnotherStep.disabled = false;

      this.anotherExtraStep = false;


      if (this.activeStep !== this.steps.length) {

        this.activeStep++;

      } else {

        this.activeStep = 1;

      }

    },

    addStep() {

      const initial = document.querySelector('.step-initial');

      const input = document.querySelector('.step-input');


      // 52px = input height + margin + border

      initial.style.maxHeight = initial.offsetHeight - 52 + 'px';


      if (!this.extraStep) {

        this.$refs.addStep.disabled = true;

        this.extraStep = true;

      } else {

        this.$refs.addAnotherStep.disabled = true;

        this.anotherExtraStep = true;

      }

    }

  },


  data: () => {

    return {

      extraStep: false,

      anotherExtraStep: false,

      activeStep: 1,

      steps: [{

          order: 1,

          title: "Title 1?",

          headline: "Headline 1",

          component: "product-info"

        },

        {

          order: 2,

          title: "Title 2",

          headline: "Headline 2.",

          component: "product-info"

        },

        {

          order: 3,

          title: "Title 3",

          headline: "Headline 3.",

          component: "product-info"

        },

        {

          order: 4,

          title: "Title 4!",

          headline: "Headline 4",

          component: "product-info"

        }

      ]

    };

  },

});


Vue.config.productionTip = false;

Vue.config.devtools = false;

#app {

  position: relative;

  height: calc(300px + 52px);

}


.component-wrapper {

  width: 100%;

}


.steps-viewport {

  /* height: calc(100vh - 10rem); */

  /* overflow: hidden */

  display: flex;

  flex-direction: column;

}


.step-wrapper,

.step-wrapper * {

  transition: all 0.2s;

}


.step-wrapper * {

  margin: 0;

}


.step-initial {

  display: flex;

  justify-content: space-evenly;

  flex-direction: column;

  height: 300px;

  max-height: 300px;

}


.step-initial *:nth-child(2) {

  transition-delay: 0.05s;

}


.step-initial *:nth-child(3) {

  transition-delay: 0.1s;

}


.steps-enter-active .step-initial * {

  opacity: 0;

  transform: translateY(100%);

}


.steps-leave-to .step-initial *,

.steps-leave-to .step-input {

  opacity: 0;

  transform: translateY(-100%);

}


.steps-leave-to .step-input:nth-of-type(2) {

  transition-delay: 0.2s;

}


.steps-leave-to .step-input:nth-of-type(3) {

  transition-delay: 0.3s;

}


.steps-enter-to .step-initial * {

  opacity: 1;

  transform: translateY(0);

}


.step-input {

  margin: 20px 0;

  height: 30px;

}


.steps-input-enter-active {

  opacity: 0;

  transform: translateY(100%);

}


.steps-input-leave-to {

  opacity: 0;

  transform: translateY(-100%);

}


.steps-input-enter-to {

  opacity: 1;

  transform: translateY(0);

}


.step-btns {

  position: absolute;

  bottom: 10px;

}

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>


<div id="app">

  <transition name="steps" mode="out-in" duration="350" appear>

    <div v-for="step in currentStep" :key="step.order" class="step-wrapper">

      <div class="step-initial">

        <h3 class="is-size-5 mb-6 has-text-grey-light">

          Passo {{ step.order }}

        </h3>

        <h1 class="is-size-3">{{ step.title }}</h1>

        <h2 class="is-size-4 mt-2 has-text-grey">{{ step.headline }}</h2>

      </div>

      <transition name="steps-input">

        <div v-if="extraStep" class="step-input">

          <input />

        </div>

      </transition>

      <transition name="steps-input">

        <div v-if="anotherExtraStep" class="step-input">

          <input />

        </div>

      </transition>

    </div>

  </transition>

  <div class="step-btns">

    <button @click="nextStep()">Next</button>

    <button @click="addStep()" ref="addStep">Add Step</button>

    <button @click="addStep()" ref="addAnotherStep">Add Another Step</button>

  </div>

</div>


查看完整回答
反對 回復 2023-10-14
  • 1 回答
  • 0 關注
  • 125 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號