index.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <!-- 公告栏组件 -->
  2. <template>
  3. <transition name="el-fade-in-linear">
  4. <div class="notice-bar" v-show="open && show">
  5. <div class="notice-bar__icon"></div>
  6. <div ref="wrap" class="notice-bar__wrap">
  7. <div ref="content" class="notice-bar__content" :style="contentStyle">
  8. <span class="notice-bar__content_item" v-for="(item, index) in noticeList">{{ item.title }}</span>
  9. </div>
  10. </div>
  11. <div class="close">
  12. <el-button size="mini" @click="handleClearTimer">关闭</el-button>
  13. </div>
  14. </div>
  15. </transition>
  16. </template>
  17. <script>
  18. import { mapMutations, mapGetters, mapActions } from 'vuex'
  19. // import { getNoticeList } from '@/api/notificationCenter'
  20. export default {
  21. name: 'NoticeBar',
  22. props: {
  23. speed: {
  24. type: Number,
  25. default: 50
  26. },
  27. defaultWidth: {
  28. type: Number,
  29. default: 375
  30. }
  31. },
  32. data() {
  33. return {
  34. contentStyle: {
  35. transitionDuration: '0s',
  36. transform: 'translateX(0px)'
  37. },
  38. wrapWidth: 0,
  39. contentWidth: 0,
  40. time: 0,
  41. timer: null,
  42. convertSpeed: 1,
  43. noticeList: [],
  44. noticeTimer: null,
  45. open: null
  46. }
  47. },
  48. computed: {
  49. ...mapGetters(['show'])
  50. },
  51. watch: {
  52. open(val, oval) {
  53. if (val) {
  54. clearInterval(this.noticeTimer)
  55. } else {
  56. this.noticeTimer = setInterval(() => {
  57. this.$nextTick(() => {
  58. this.getList()
  59. this.updateUnreadNotice()
  60. })
  61. }, 5000)
  62. }
  63. }
  64. },
  65. mounted() {
  66. // this.getList()
  67. this.updateUnreadNotice()
  68. },
  69. beforeDestroy() {
  70. this.handleClearTimer()
  71. },
  72. methods: {
  73. ...mapMutations({
  74. SET_SHOW: 'app/SET_SHOW'
  75. }),
  76. ...mapActions({
  77. updateUnreadNotice: 'app/getUnreadNum'
  78. }),
  79. handleClearTimer() {
  80. this.open = false
  81. this.SET_SHOW(null)
  82. clearInterval(this.timer)
  83. clearInterval(this.noticeTimer)
  84. },
  85. getList() {
  86. let params = {
  87. pageNum: 1,
  88. pageSize: -1,
  89. params: [{ param: 'read_flag', compare: '=', value: 'NO' }]
  90. }
  91. // getNoticeList(params).then(res => {
  92. // this.noticeList = res.data.records
  93. // if (this.noticeList.length) {
  94. // this.open = true
  95. // this.SET_SHOW(true)
  96. // this.$nextTick(() => {
  97. // clearInterval(this.timer)
  98. // clearInterval(this.noticeTimer)
  99. // this.init()
  100. // this.noticeTimer = setInterval(() => {
  101. // this.getList()
  102. // this.updateUnreadNotice()
  103. // }, this.time * 1000)
  104. // })
  105. // } else {
  106. // this.open = false
  107. // this.SET_SHOW(null)
  108. // }
  109. // })
  110. },
  111. initAttribute() {},
  112. init() {
  113. const _width = innerWidth
  114. this.convertSpeed = (_width / this.defaultWidth) * this.speed // 根据分辨率转化成不同的速度
  115. this.wrapWidth = this.$refs.wrap.offsetWidth
  116. this.contentWidth = this.$refs.content.offsetWidth
  117. this.startAnimate()
  118. this.timer = setInterval(() => {
  119. this.startAnimate()
  120. }, this.time * 1000)
  121. this.$once('hook:beforeDestroy', () => {
  122. clearInterval(this.timer)
  123. this.timer = null
  124. })
  125. },
  126. startAnimate() {
  127. this.contentStyle.transitionDuration = '0s'
  128. this.contentStyle.transform = 'translateX(' + this.wrapWidth + 'px)'
  129. this.time = (this.wrapWidth + this.contentWidth) / this.convertSpeed
  130. setTimeout(() => {
  131. this.contentStyle.transitionDuration = this.time + 's'
  132. this.contentStyle.transform = 'translateX(-' + this.contentWidth + 'px)'
  133. }, 200)
  134. },
  135. tipClick() {
  136. this.$emit('click')
  137. }
  138. }
  139. }
  140. </script>
  141. <style scoped lang="less">
  142. .transition-box {
  143. margin-bottom: 10px;
  144. width: 200px;
  145. height: 100px;
  146. border-radius: 4px;
  147. background-color: #409eff;
  148. text-align: center;
  149. color: #fff;
  150. padding: 40px 20px;
  151. box-sizing: border-box;
  152. margin-right: 20px;
  153. }
  154. .close {
  155. margin-right: 20px;
  156. }
  157. .notice-bar {
  158. position: relative;
  159. width: 100%;
  160. height: 54px;
  161. padding-left: 0;
  162. padding-right: 0;
  163. display: flex;
  164. align-items: center;
  165. background-color: rgba(255, 255, 255, 1);
  166. box-shadow: 0 1px 4px rgb(0 21 41 / 8%);
  167. z-index: 1999;
  168. .notice-bar__icon {
  169. img {
  170. width: 100%;
  171. }
  172. }
  173. .notice-bar__content_item {
  174. margin-right: 100px;
  175. }
  176. .notice-bar__wrap {
  177. position: relative;
  178. display: flex;
  179. flex: 1;
  180. height: 100%;
  181. align-items: center;
  182. overflow: hidden;
  183. .notice-bar__content {
  184. position: absolute;
  185. white-space: nowrap;
  186. transition-timing-function: linear;
  187. }
  188. }
  189. }
  190. </style>