何时使用过渡vs过渡组

时间:2019-01-25 10:23:03

标签: javascript html vue.js transition

我正在尝试向表单添加过渡,以便当用户选择问题的特定答案时,它将动态显示下一个问题。目前,我看起来像这样:

<input type="text" :value="vueModel.question1" />
<div v-if="vueModel.question1 === 'hello'">
    //Do something
</div>
<div v-else-if="vueModel.question1 === 'hihi'">
    //Do something
</div>
<div v-else>
    //Do something
</div>

我的问题是,我应该这样添加过渡吗? (为什么?)

<input type="text" :value="vueModel.question1" />
<transition-group name="slide-fade" mode="in-out">
    <div v-if="vueModel.question1 === 'hello'" key="key1">
        //Do something
    </div>
    <div v-else-if="vueModel.question1 === 'hihi'" key="key2">
        //Do something
    </div>
    <div v-else key="key3">
        //Do something
    </div>
</transition-group>

还是这种方式? (为什么?)

<input type="text" :value="vueModel.question1" />
<transition name="slide-fade" mode="in-out">
    <div v-if="vueModel.question1 === 'hello'" key="key1">
        //Do something
    </div>
    <div v-else-if="vueModel.question1 === 'hihi'" key="key2">
        //Do something
    </div>
    <div v-else key="key3">
        //Do something
    </div>
</transition>

或者,还有其他方法可以更好地做到这一点,并且该方法符合Vue的最佳做法吗?

1 个答案:

答案 0 :(得分:1)

因此,当您有一个项目列表并且想要同时渲染和过滤时(例如,使用v-for)?在这种情况下,您可以使用transition-group组件。与transition不同,这将呈现一个实际元素:在下一个截图中像div。但是,您可以更改使用tag属性呈现的元素。

注意

  

始终要求内部的元素具有唯一的键属性。

更新

如果您有一个问题,然后想“做某事”,请像本示例中那样仅使用transition

transitiontransition-group之间的主要区别在于过渡将影响一个组件。这意味着,如果您有一个组件要替换为另一个组件,则可以使用过渡。

new Vue({
  el: '#vue-transition',
  data: {
    show: false,
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">

<div id="vue-transition">
  <button @click="show = !show"> Simple Transition </button>
  <transition
    name="custom-classes-transition"
    enter-active-class="animated tada"
    leave-active-class="animated bounceOutRight"
  >
    <p v-if="show">Teocci</p>
  </transition>
</div>

另一方面,transition-group从元素列表中渲染实际元素,因此始终要求内部的元素具有唯一的键属性。例如,如果您有9个问题,但您想要呈现每个元素随机过渡到 SAME 组中另一个位置的过渡。

new Vue({
  el: '#list-complete-demo',
  data: {
    items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
  },
  methods: {
    shuffle: function() {
      this.items = _.shuffle(this.items)
    }
  }
})
.list-complete-item {
  transition: all 1s;
  display: inline-block;
  margin-right: 10px;
}

.list-complete-enter,
.list-complete-leave-to {
  opacity: 0;
  transform: translateY(30px);
}

.list-complete-leave-active {
  position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>

<div id="list-complete-demo" class="demo">
  <button v-on:click="shuffle">Shuffle</button>
  <transition-group name="list-complete" tag="p">
    <span v-for="item in items" v-bind:key="item" class="list-complete-item">
      {{ item }}
    </span>
  </transition-group>
</div>

因此,如果您只想“做某事”,请使用本代码段中所示的transition来实现所需的目的。

let app = new Vue({
  el: '#vue-selector',
  data: {
    questions: [{
        id: 0,
        description: 'Question 01',
        answer: 'hihi'
      },
      {
        id: 1,
        description: 'Question 02',
        answer: 'lala'
      },
      {
        id: 2,
        description: 'Question 03',
        answer: 'hello'
      },
      {
        id: 3,
        description: 'Question 04',
        answer: 'none'
      },
      {
        id: 4,
        description: 'Question 05',
        answer: 'teo'
      },
    ],
    answer: {
      question: -1,
      text: '',
    },
    answerText: '',
    selected: '',
  },
  computed: {
    computedQuestions: function() {
      let vm = this;
      return this.questions.filter(function(item, index) {
        return index !== vm.answers;
      })
    }
  },
  methods: {
    answerQuestion: function(index) {
      this.answer.question = index;
      this.answer.text = this.answerText;
    },
    beforeEnter: function(el) {
      el.style.opacity = 0
      el.style.height = 0
    },
    enter: function(el, done) {
      var delay = el.dataset.index * 150
      setTimeout(function() {
        Velocity(
          el, {
            opacity: 1,
            height: '1.6em'
          }, {
            complete: done
          }
        )
      }, delay)
    },
    leave: function(el, done) {
      var delay = el.dataset.index * 150
      setTimeout(function() {
        Velocity(
          el, {
            opacity: 0,
            height: 0
          }, {
            complete: done
          }
        )
      }, delay)
    },
  },
});
div.selector {
  display: block;
  padding-top: 25px;
  padding-bottom: 125px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/velocity/2.0.3/velocity.min.js"></script>

<div id="vue-selector">
  <div>Question 01</div>
  <input v-model="answerText" placeholder="answer me">
  <button @click="answerQuestion(0)"> Answer </button>

  <transition name="slide-fade" mode="in-out">
    <div v-if="answer.text === 'hello'">
      Do something A
    </div>
    <div v-else-if="answer.text === 'hihi'">
      Do something B
    </div>
    <div v-else>
      Waiting for answer
    </div>
  </transition>
</div>