当需要渲染整个列表,就需要使用 transition-group
官网上显示的列表过渡与单元素过渡的区别
image.png
示例
效果图
列表过渡.gif
示例代码

  1. <template>
  2. <div>
  3. <button @click="show = !show"> clcik </button>
  4. <transition-group >
  5. <div v-if="show" key="word">hello word</div>
  6. <div v-if="show" key="text">hello text</div>
  7. </transition-group>
  8. </div>
  9. </template>
  10. <script>
  11. export default {
  12. data(){
  13. return{
  14. show:false,
  15. }
  16. }
  17. }
  18. </script>
  19. <style scoped>
  20. .v-enter,
  21. .v-leave-to{
  22. opacity: 0;
  23. transform: translate(30px);
  24. }
  25. .v-enter-active,
  26. .v-leave-active{
  27. transition: all .3s ;
  28. }
  29. .v-enter-to,
  30. .v-leave {
  31. opacity: 1;
  32. transform: translate(0);
  33. }
  34. </style>

列表的排序过渡

transition-group 组件中提供啦一个新特性:v-move ,它会在元素改变定位的过程中使用
内部的实现:Vue 使用了一个叫 FLIP 简单的动画队列,使用 transforms 将元素从之前的位置平滑过渡新的位置。
需要注意的是使用 FLIP 过渡的元素不能设置为 display: inline 。作为替代方案,可以设置为 display: inline-block 或者放置于 flex 中。

示例

没有设置v-move的效果 设置v-move效果
区别在排序的效果中
列表过渡-v-move.gif 列表过渡-v-move2.gif列表过渡-v-move2.gif
源码

  1. <template>
  2. <div>
  3. <button @click="handleAdd">添加</button>
  4. <button @click="handleDelete">删除</button>
  5. <button @click="handleShuffle">排序</button>
  6. <transition-group tag="ul">
  7. <li v-for="li in list" :key="li"> {{ li }}</li>
  8. </transition-group>
  9. </div>
  10. </template>
  11. <script>
  12. export default {
  13. data(){
  14. return{
  15. list:[1,2,3,4,5,6,7,8,9],
  16. nextNum:10,
  17. }
  18. },
  19. methods:{
  20. handleAdd(){
  21. this.nextNum ++;
  22. let index = this.rendomIndex()
  23. this.list.splice(index,0,this.nextNum);
  24. },
  25. handleDelete(){
  26. let index = this.rendomIndex()
  27. this.list.splice(index,1)
  28. },
  29. rendomIndex(){
  30. return Math.floor(Math.random() * this.list.length);
  31. },
  32. handleShuffle(){
  33. this.list.sort(() => Math.random() - 0.5 )
  34. }
  35. }
  36. }
  37. </script>
  38. <style scoped>
  39. ul,li{
  40. list-style: none;
  41. display: block;
  42. }
  43. button{
  44. display: block;
  45. margin: 10px auto;
  46. }
  47. .v-enter,
  48. .v-leave-to{
  49. opacity: 0;
  50. transform: translateX(30px);
  51. }
  52. .v-enter-active,
  53. .v-leave-active{
  54. transition: all .3s;
  55. }
  56. .v-leave,
  57. .v-enter-to{
  58. opacity: 1;
  59. transform: translateX(0);
  60. }
  61. .v-move{
  62. transition: all .3s;
  63. }
  64. </style>

案例

关键字搜索

效果图
列表过渡-关键字搜索.gif

  1. <template>
  2. <div>
  3. 关键字搜索
  4. <input type="text" v-model="value">
  5. <transition-group tag="ul">
  6. <li v-for="li in computedLists" :key="li.name">{{ li.name }}</li>
  7. </transition-group>
  8. </div>
  9. </template>
  10. <script>
  11. export default {
  12. data(){
  13. return {
  14. value:'',
  15. lists:[
  16. {name:'zhangsan'},
  17. {name:'lisi'},
  18. {name:'wangwu'},
  19. {name:'liumang'},
  20. {name:'pangzi '},
  21. ]
  22. }
  23. },
  24. computed:{
  25. computedLists(){
  26. return this.lists.filter(ele => ele.name.includes(this.value) )
  27. }
  28. }
  29. }
  30. </script>
  31. <style scoped>
  32. ul,li{
  33. list-style: none;
  34. }
  35. li {
  36. height: 24px;
  37. }
  38. .v-enter,
  39. .v-leave-to {
  40. opacity: 0;
  41. height: 0px;
  42. }
  43. .v-leave-active,
  44. .v-enter-active {
  45. transition: all .3s;
  46. }
  47. .v-enter-to,
  48. .v-leave {
  49. opacity: 1;
  50. height: 24px;
  51. }
  52. </style>

关键字搜索使用js钩子实现

  1. <template>
  2. <div>
  3. 关键字搜索
  4. <input type="text" v-model="value">
  5. <transition-group
  6. tag="ul"
  7. @before-enter="beforeEnter"
  8. @enter="enter"
  9. @leave="leave"
  10. >
  11. <li v-for="li in computedLists" :key="li.name">{{ li.name }}</li>
  12. </transition-group>
  13. </div>
  14. </template>
  15. <script>
  16. export default {
  17. data(){
  18. return {
  19. value:'',
  20. lists:[
  21. {name:'zhangsan'},
  22. {name:'lisi'},
  23. {name:'wangwu'},
  24. {name:'liumang'},
  25. {name:'pangzi '},
  26. ]
  27. }
  28. },
  29. computed:{
  30. computedLists(){
  31. return this.lists.filter(ele => ele.name.includes(this.value) )
  32. }
  33. },
  34. methods:{
  35. beforeEnter(el){
  36. el.style.opacity = 0;
  37. el.style.height = 0;
  38. },
  39. enter(el,done){
  40. Velocity(el,{
  41. opacity:1,
  42. height:'24px'
  43. },{
  44. duration:300,
  45. complete:done
  46. })
  47. },
  48. leave(el,done){
  49. Velocity(el,{
  50. opacity:0,
  51. height:'0px',
  52. },{
  53. duration:300,
  54. complete:done
  55. })
  56. }
  57. }
  58. }
  59. </script>
  60. <style scoped>
  61. ul,li{
  62. list-style: none;
  63. }
  64. li {
  65. height: 24px;
  66. }
  67. </style>