fa8b108fbb540f541aca120cee557c8035bcecf4.svn-base 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import '../../less/reload-effect.less'
  2. import { randomString } from '@/utils/util'
  3. // 修改数据特效
  4. export default {
  5. props: {
  6. vNode: null,
  7. // 是否启用特效
  8. effect: Boolean,
  9. },
  10. data() {
  11. return {
  12. // vNode: null,
  13. innerEffect: false,
  14. // 应付同时多个特效
  15. effectIdx: 0,
  16. effectList: [],
  17. }
  18. },
  19. watch: {
  20. vNode: {
  21. deep: true,
  22. immediate: true,
  23. handler(vNode, old) {
  24. this.innerEffect = this.effect
  25. if (this.innerEffect && old != null) {
  26. let topLayer = this.renderSpan(old, 'top')
  27. this.effectList.push(topLayer)
  28. }
  29. },
  30. },
  31. },
  32. methods: {
  33. // 条件渲染内容 span
  34. renderVNode() {
  35. if (this.vNode == null) {
  36. return null
  37. }
  38. let bottom = this.renderSpan(this.vNode, 'bottom')
  39. // 启用了特效,并且有旧数据,就渲染特效顶层
  40. if (this.innerEffect && this.effectList.length > 0) {
  41. this.$emit('effect-begin')
  42. // 1.4s 以后关闭特效
  43. window.setTimeout(() => {
  44. let item = this.effectList[this.effectIdx]
  45. if (item && item.elm) {
  46. // 特效结束后,展示先把 display 设为 none,而不是直接删掉该元素,
  47. // 目的是为了防止页面重新渲染,导致动画重置
  48. item.elm.style.display = 'none'
  49. }
  50. // 当所有的层级动画都结束时,再删掉所有元素
  51. if (++this.effectIdx === this.effectList.length) {
  52. this.innerEffect = false
  53. this.effectIdx = 0
  54. this.effectList = []
  55. this.$emit('effect-end')
  56. }
  57. }, 1400)
  58. return [this.effectList, bottom]
  59. } else {
  60. return bottom
  61. }
  62. },
  63. // 渲染内容 span
  64. renderSpan(vNode, layer) {
  65. let options = {
  66. key: layer + this.effectIdx + randomString(6),
  67. class: ['j-vxe-reload-effect-span', `layer-${layer}`],
  68. style: {},
  69. }
  70. if (layer === 'top') {
  71. // 最新渲染的在下面
  72. options.style['z-index'] = (9999 - this.effectIdx)
  73. }
  74. return this.$createElement('span', options, [vNode])
  75. },
  76. },
  77. render(h) {
  78. return h('div', {
  79. class: ['j-vxe-reload-effect-box'],
  80. }, [this.renderVNode()])
  81. },
  82. }