uni-notice-bar.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <template>
  2. <view v-if="show" class="uni-noticebar" :style="{backgroundColor:backgroundColor,color:color}" @click="onClick">
  3. <view v-if="showClose === 'true' || showClose === true" class="uni-noticebar__close">
  4. <uni-icon type="closefill" size="12"></uni-icon>
  5. </view>
  6. <view class="uni-noticebar__content" :class="setContenClass">
  7. <view v-if="showIcon === 'true' || showIcon === true" class="uni-noticebar__content-icon" :style="{backgroundColor:backgroundColor,color:color}">
  8. <uni-icon type="sound" size="14" :color="color"></uni-icon>
  9. </view>
  10. <view class="uni-noticebar__content-text" :class="setTextClass">
  11. <!-- #ifdef H5 -->
  12. <view class="uni-noticebar__content-inner" :id="elId" :style="{'animation-duration': animation,'-webkit-animation-duration': animation}">{{text}}</view>
  13. <!-- #endif -->
  14. <!-- #ifndef H5 -->
  15. <view class="uni-noticebar__content-inner" :id="elId" :style="{'animation': animation,'-webkit-animation': animation}">{{text}}</view>
  16. <!-- #endif -->
  17. </view>
  18. <view class="uni-noticebar__content-more" v-if="showGetMore === 'true' || showGetMore === true" @click="clickMore" :style="{width:moreText ? '180upx' : '20px'}">
  19. <view class="uni-noticebar__content-more-text" v-if="moreText">{{moreText}}</view>
  20. <uni-icon type="arrowright" size="14"></uni-icon>
  21. </view>
  22. </view>
  23. </view>
  24. </template>
  25. <script>
  26. import uniIcon from '../uni-icon/uni-icon.vue'
  27. export default {
  28. name: "uni-notice-bar",
  29. components: {
  30. uniIcon
  31. },
  32. props: {
  33. text: String,
  34. moreText: String,
  35. backgroundColor: {
  36. type: String,
  37. default: '#fffbe8'
  38. },
  39. speed: { //默认1s滚动100px
  40. default: 100
  41. },
  42. color: {
  43. default: '#de8c17'
  44. },
  45. single: { //是否单行
  46. default: false
  47. },
  48. scrollable: { //是否滚动,添加后控制单行效果取消
  49. default: false
  50. },
  51. showIcon: { //是否显示左侧icon
  52. default: false
  53. },
  54. showGetMore: { //是否显示右侧查看更多
  55. default: false
  56. },
  57. showClose: { //是否显示左侧关闭按钮
  58. default: false
  59. }
  60. },
  61. data() {
  62. const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
  63. return {
  64. elId: elId,
  65. show: true,
  66. animation: ''
  67. }
  68. },
  69. watch: {
  70. text(newValue, oldValue) {
  71. this.$nextTick(() => {
  72. setTimeout(this.setAnimation, 200)
  73. })
  74. }
  75. },
  76. computed: {
  77. setTextClass() {
  78. let classList = []
  79. if (this.scrollable === true || this.scrollable === 'true') {
  80. classList.push('uni-noticebar--scrollable')
  81. } else {
  82. if (this.single === 'true' || this.single === true || this.moreText) {
  83. classList.push('uni-noticebar--single')
  84. }
  85. }
  86. return classList
  87. },
  88. setContenClass() {
  89. let classList = []
  90. if (this.scrollable === true || this.scrollable === 'true' || this.single === 'true' || this.single === true ||
  91. this.moreText) {
  92. classList.push('uni-noticebar--flex')
  93. }
  94. return classList
  95. }
  96. },
  97. mounted() {
  98. this.setAnimation()
  99. },
  100. methods: {
  101. clickMore() {
  102. this.$emit('getmore')
  103. },
  104. onClick(e) {
  105. let clientX = e.touches ? (e.touches[0] ? e.touches[0].clientX : e.changedTouches[0].clientX) : e.detail.clientX;
  106. if (uni.upx2px(48) + 12 > clientX && (String(this.showClose) === 'true')) {
  107. this.show = false
  108. this.$emit('close')
  109. }
  110. this.$emit('click')
  111. },
  112. setAnimation() {
  113. if (this.scrollable === false || this.scrollable === 'false') {
  114. return;
  115. }
  116. //#ifdef MP-TOUTIAO
  117. setTimeout(() => {
  118. uni.createSelectorQuery().in(this).select(`#${this.elId}`).boundingClientRect().exec((ret) => {
  119. console.log(ret)
  120. this.animation = `notice ${ret[0].width / this.speed}s linear infinite both`;
  121. });
  122. }, 500)
  123. // #endif
  124. //#ifdef H5
  125. setTimeout(() => {
  126. uni.createSelectorQuery().in(this).select(`#${this.elId}`).boundingClientRect().exec((ret) => {
  127. this.animation = `${ret[0].width / this.speed}s`;
  128. });
  129. }, 200)
  130. // #endif
  131. // #ifndef MP-TOUTIAO || H5
  132. setTimeout(() => {
  133. uni.createSelectorQuery().in(this).select(`#${this.elId}`).boundingClientRect().exec((ret) => {
  134. this.animation = `notice ${ret[0].width / this.speed}s linear infinite both`;
  135. });
  136. }, 200)
  137. // #endif
  138. }
  139. }
  140. }
  141. </script>
  142. <style>
  143. @charset "UTF-8";
  144. .uni-noticebar {
  145. padding: 12upx 24upx;
  146. font-size: 24upx;
  147. line-height: 1.5;
  148. margin: 10upx 0;
  149. display: flex;
  150. flex-direction: row;
  151. justify-content: center;
  152. align-items: center;
  153. justify-content: left
  154. }
  155. .uni-noticebar__close {
  156. color: #999;
  157. margin-right: 24upx;
  158. display: flex;
  159. flex-direction: row;
  160. justify-content: center;
  161. align-items: center
  162. }
  163. .uni-noticebar__content {
  164. flex: 1;
  165. overflow: hidden
  166. }
  167. .uni-noticebar__content.uni-noticebar--flex {
  168. flex: 1;
  169. display: flex;
  170. flex-direction: row
  171. }
  172. .uni-noticebar__content-icon {
  173. display: inline-block;
  174. z-index: 1;
  175. padding-right: 12upx
  176. }
  177. .uni-noticebar__content-more {
  178. width: 180upx;
  179. display: flex;
  180. flex-direction: row;
  181. justify-content: center;
  182. align-items: center;
  183. justify-content: flex-end;
  184. word-break: keep-all;
  185. margin-left: 10upx;
  186. color: #999
  187. }
  188. .uni-noticebar__content-more-text {
  189. font-size: 24upx;
  190. white-space: nowrap
  191. }
  192. .uni-noticebar__content-text {
  193. word-break: break-all;
  194. line-height: 1.5;
  195. display: inline
  196. }
  197. .uni-noticebar__content-text.uni-noticebar--single {
  198. text-overflow: ellipsis;
  199. white-space: nowrap;
  200. overflow: hidden
  201. }
  202. .uni-noticebar__content-text.uni-noticebar--scrollable {
  203. flex: 1;
  204. display: block;
  205. overflow: hidden
  206. }
  207. .uni-noticebar__content-text.uni-noticebar--scrollable .uni-noticebar__content-inner {
  208. padding-left: 100%;
  209. white-space: nowrap;
  210. display: inline-block;
  211. /* #ifdef H5 */
  212. animation-name: notice;
  213. animation-timing-function: linear;
  214. animation-fill-mode: both;
  215. animation-iteration-count: infinite;
  216. /* #endif */
  217. transform: translateZ(0)
  218. }
  219. .uni-noticebar__content-inner {
  220. font-size: 24upx;
  221. display: inline
  222. }
  223. @keyframes notice {
  224. 100% {
  225. transform: translate3d(-100%, 0, 0)
  226. }
  227. }
  228. </style>