¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <view |
| | | class="u-notice" |
| | | @tap="clickHandler" |
| | | > |
| | | <slot name="icon"> |
| | | <view |
| | | class="u-notice__left-icon" |
| | | v-if="icon" |
| | | > |
| | | <u-icon |
| | | :name="icon" |
| | | :color="color" |
| | | size="19" |
| | | ></u-icon> |
| | | </view> |
| | | </slot> |
| | | <view |
| | | class="u-notice__content" |
| | | ref="u-notice__content" |
| | | > |
| | | <view |
| | | ref="u-notice__content__text" |
| | | class="u-notice__content__text" |
| | | :style="[animationStyle]" |
| | | > |
| | | <text |
| | | v-for="(item, index) in innerText" |
| | | :key="index" |
| | | :style="[textStyle]" |
| | | >{{item}}</text> |
| | | </view> |
| | | </view> |
| | | <view |
| | | class="u-notice__right-icon" |
| | | v-if="['link', 'closable'].includes(mode)" |
| | | > |
| | | <u-icon |
| | | v-if="mode === 'link'" |
| | | name="arrow-right" |
| | | :size="17" |
| | | :color="color" |
| | | ></u-icon> |
| | | <u-icon |
| | | v-if="mode === 'closable'" |
| | | @click="close" |
| | | name="close" |
| | | :size="16" |
| | | :color="color" |
| | | ></u-icon> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | <script> |
| | | import props from './props.js'; |
| | | // #ifdef APP-NVUE |
| | | const animation = uni.requireNativePlugin('animation') |
| | | const dom = uni.requireNativePlugin('dom') |
| | | // #endif |
| | | /** |
| | | * RowNotice æ»å¨éç¥ä¸çæ°´å¹³æ»å¨æ¨¡å¼ |
| | | * @description æ°´å¹³æ»å¨ |
| | | * @tutorial https://www.uviewui.com/components/noticeBar.html |
| | | * @property {String | Number} text æ¾ç¤ºçå
容ï¼å符串 |
| | | * @property {String} icon æ¯å¦æ¾ç¤ºå·¦ä¾§çé³é徿 (é»è®¤ 'volume' ) |
| | | * @property {String} mode é忍¡å¼ï¼link-æ¾ç¤ºå³ç®å¤´ï¼closable-æ¾ç¤ºå³ä¾§å
³é徿 |
| | | * @property {String} color æåé¢è²ï¼å徿 ä¹ä¼ä½¿ç¨æåé¢è² (é»è®¤ '#f9ae3d' ) |
| | | * @property {String} bgColor èæ¯é¢è² (é»è®¤ ''#fdf6ec' ) |
| | | * @property {String | Number} fontSize åä½å¤§å°ï¼åä½px (é»è®¤ 14 ) |
| | | * @property {String | Number} speed æ°´å¹³æ»å¨æ¶çæ»å¨é度ï¼å³æ¯ç§æ»å¨å¤å°px(rpx)ï¼è¿æå©äºæ§å¶æåæ 论å¤å°æ¶ï¼é½è½æä¸ä¸ªæå®çé度 (é»è®¤ 80 ) |
| | | * |
| | | * @event {Function} click ç¹å»éåæå触å |
| | | * @event {Function} close ç¹å»å³ä¾§å
³é徿 触å |
| | | * @example |
| | | */ |
| | | export default { |
| | | name: 'u-row-notice', |
| | | mixins: [uni.$u.mpMixin, uni.$u.mixin,props], |
| | | data() { |
| | | return { |
| | | animationDuration: '0', // å¨ç»æ§è¡æ¶é´ |
| | | animationPlayState: 'paused', // å¨ç»çå¼å§åç»ææ§è¡ |
| | | // nvueä¸ï¼å
容åçååï¼å¯¼è´æ»å¨å®½åº¦ä¹ååï¼éè¦æ å¿ä¸ºæ¯å¦éè¦éæ°è®¡ç®å®½åº¦ |
| | | // ä¸è½å¨å
容ååæ¶ç´æ¥éæ°è®¡ç®ï¼å 为nvueçanimation模åä¸ä¸æ¬¡çæ»å¨ä¸æ¯åå¥½ç»æï¼ä¼æå½±å |
| | | nvueInit: true, |
| | | show: true |
| | | }; |
| | | }, |
| | | watch: { |
| | | text: { |
| | | immediate: true, |
| | | handler(newValue, oldValue) { |
| | | // #ifdef APP-NVUE |
| | | this.nvueInit = true |
| | | // #endif |
| | | // #ifndef APP-NVUE |
| | | this.vue() |
| | | // #endif |
| | | |
| | | if(!uni.$u.test.string(newValue)) { |
| | | uni.$u.error('noticebarç»ä»¶direction为rowæ¶ï¼è¦æ±textåæ°ä¸ºå符串形å¼') |
| | | } |
| | | } |
| | | }, |
| | | fontSize() { |
| | | // #ifdef APP-NVUE |
| | | this.nvueInit = true |
| | | // #endif |
| | | // #ifndef APP-NVUE |
| | | this.vue() |
| | | // #endif |
| | | }, |
| | | speed() { |
| | | // #ifdef APP-NVUE |
| | | this.nvueInit = true |
| | | // #endif |
| | | // #ifndef APP-NVUE |
| | | this.vue() |
| | | // #endif |
| | | } |
| | | }, |
| | | computed: { |
| | | // æåå
å®¹çæ ·å¼ |
| | | textStyle() { |
| | | let style = {} |
| | | style.color = this.color |
| | | style.fontSize = uni.$u.addUnit(this.fontSize) |
| | | return style |
| | | }, |
| | | animationStyle() { |
| | | let style = {} |
| | | style.animationDuration = this.animationDuration |
| | | style.animationPlayState = this.animationPlayState |
| | | return style |
| | | }, |
| | | // å
é¨å¯¹ç¨æ·ä¼ å
¥çæ°æ®è¿ä¸æ¥åå²ï¼æ¾å°å¤ä¸ªtextæ ç¾å¾ªç¯ï¼å¦åå¦æç¨æ·ä¼ å
¥çå符串å¾é¿ï¼100个å符以ä¸ï¼ |
| | | // æ¾å¨ä¸ä¸ªtextæ ç¾ä¸è¿è¡æ»å¨ï¼å¨ä½ç«¯å®åæºä¸ï¼å¨ç»å¯è½ä¼åºç°æå¨ç°è±¡ï¼éè¦åå²å°å¤ä¸ªtextä¸å¯è§£å³æ¤é®é¢ |
| | | innerText() { |
| | | let result = [], |
| | | // æ¯ç»textæ ç¾çå符é¿åº¦ |
| | | len = 20 |
| | | const textArr = this.text.split('') |
| | | for (let i = 0; i < textArr.length; i += len) { |
| | | // 对æåçåçtextè¿è¡sliceåå²ï¼å¾å°ç为æ°ç»åè¿è¡joinæ¼æ¥ä¸ºå符串 |
| | | result.push(textArr.slice(i, i + len).join('')) |
| | | } |
| | | return result |
| | | } |
| | | }, |
| | | mounted() { |
| | | // #ifdef APP-PLUS |
| | | // å¨APPä¸(å«nvue)ï¼çå¬å½åwebviewæ¯å¦å¤äºéèç¶æ(è¿å
¥ä¸ä¸é¡µæ¶å³ä¸ºhideç¶æ) |
| | | // 妿webivewéèäºï¼ä¸ºäºèçæ§è½çæèï¼åºåæ¢å¨ç»çæ§è¡ï¼åæ¶ä¹æ¯ä¸ºäºä¿æè¿å
¥ä¸ä¸é¡µè¿ååï¼æ»å¨ä½ç½®ä¿æä¸å |
| | | var pages = getCurrentPages() |
| | | var page = pages[pages.length - 1] |
| | | var currentWebview = page.$getAppWebview() |
| | | currentWebview.addEventListener('hide', () => { |
| | | this.webviewHide = true |
| | | }) |
| | | currentWebview.addEventListener('show', () => { |
| | | this.webviewHide = false |
| | | }) |
| | | // #endif |
| | | |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | // #ifdef APP-NVUE |
| | | this.nvue() |
| | | // #endif |
| | | |
| | | // #ifndef APP-NVUE |
| | | this.vue() |
| | | // #endif |
| | | |
| | | if(!uni.$u.test.string(this.text)) { |
| | | uni.$u.error('noticebarç»ä»¶direction为rowæ¶ï¼è¦æ±textåæ°ä¸ºå符串形å¼') |
| | | } |
| | | }, |
| | | // vueçå¤ç |
| | | async vue() { |
| | | // #ifndef APP-NVUE |
| | | let boxWidth = 0, |
| | | textWidth = 0 |
| | | // è¿è¡ä¸å®çå»¶æ¶ |
| | | await uni.$u.sleep() |
| | | // æ¥è¯¢çååæåç宽度 |
| | | textWidth = (await this.$uGetRect('.u-notice__content__text')).width |
| | | boxWidth = (await this.$uGetRect('.u-notice__content')).width |
| | | // æ ¹æ®t=s/v(æ¶é´=è·¯ç¨/é度)ï¼è¿é为ä½ä¸éè¦å ä¸#u-notice-boxç宽度ï¼å 为ä¸è®¾ç½®äº.u-notice-contentæ ·å¼ä¸è®¾ç½®äºpadding-left: 100% |
| | | // æ°å·§è®¡ç®åºæ¥çç»æä¸å·²ç»å
å«äº#u-notice-boxç宽度 |
| | | this.animationDuration = `${textWidth / uni.$u.getPx(this.speed)}s` |
| | | // è¿éå¿
é¡»è¿æ ·å¼å§å¨ç»ï¼å¦åå¨APPä¸å¨ç»é度ä¸ä¼æ¹å |
| | | this.animationPlayState = 'paused' |
| | | setTimeout(() => { |
| | | this.animationPlayState = 'running' |
| | | }, 10) |
| | | // #endif |
| | | }, |
| | | // nvueçå¤ç |
| | | async nvue() { |
| | | // #ifdef APP-NVUE |
| | | this.nvueInit = false |
| | | let boxWidth = 0, |
| | | textWidth = 0 |
| | | // è¿è¡ä¸å®çå»¶æ¶ |
| | | await uni.$u.sleep() |
| | | // æ¥è¯¢çååæåç宽度 |
| | | textWidth = (await this.getNvueRect('u-notice__content__text')).width |
| | | boxWidth = (await this.getNvueRect('u-notice__content')).width |
| | | // å°æåç§»å¨å°çåçå³è¾¹æ²¿ï¼ä¹æä»¥éè¦è¿ä¹åï¼æ¯å 为nvue䏿¯æ100%åä½ï¼å¦åå¯ä»¥éè¿css设置 |
| | | animation.transition(this.$refs['u-notice__content__text'], { |
| | | styles: { |
| | | transform: `translateX(${boxWidth}px)` |
| | | }, |
| | | }, () => { |
| | | // 妿éç¦æ¢å¨ç»ï¼åå¼å§æ»å¨ |
| | | !this.stopAnimation && this.loopAnimation(textWidth, boxWidth) |
| | | }); |
| | | // #endif |
| | | }, |
| | | loopAnimation(textWidth, boxWidth) { |
| | | // #ifdef APP-NVUE |
| | | animation.transition(this.$refs['u-notice__content__text'], { |
| | | styles: { |
| | | // ç®æ ç§»å¨ç»ç¹ä¸º-textWidthï¼ä¹å³å½æåçæå³è¾¹è´´å°çåç左边æ¡çä½ç½® |
| | | transform: `translateX(-${textWidth}px)` |
| | | }, |
| | | // æ»å¨æ¶é´ç计ç®ä¸ºï¼æ¶é´ = è·¯ç¨(boxWidth + textWidth) / éåº¦ï¼æåè½¬ä¸ºæ¯«ç§ |
| | | duration: (boxWidth + textWidth) / uni.$u.getPx(this.speed) * 1000, |
| | | delay: 10 |
| | | }, () => { |
| | | animation.transition(this.$refs['u-notice__content__text'], { |
| | | styles: { |
| | | // éæ°å°æåç§»å¨å°çåçå³è¾¹æ²¿ |
| | | transform: `translateX(${this.stopAnimation ? 0 : boxWidth}px)` |
| | | }, |
| | | }, () => { |
| | | // 妿éç¦æ¢å¨ç»ï¼åç»§ç»ä¸ä¸è½®æ»å¨ |
| | | if (!this.stopAnimation) { |
| | | // 夿æ¯å¦éè¦åå§å计ç®å°ºå¯¸ |
| | | if (this.nvueInit) { |
| | | this.nvue() |
| | | } else { |
| | | this.loopAnimation(textWidth, boxWidth) |
| | | } |
| | | } |
| | | }); |
| | | }) |
| | | // #endif |
| | | }, |
| | | getNvueRect(el) { |
| | | // #ifdef APP-NVUE |
| | | // è¿åä¸ä¸ªpromise |
| | | return new Promise(resolve => { |
| | | dom.getComponentRect(this.$refs[el], (res) => { |
| | | resolve(res.size) |
| | | }) |
| | | }) |
| | | // #endif |
| | | }, |
| | | // ç¹å»éåæ |
| | | clickHandler(index) { |
| | | this.$emit('click') |
| | | }, |
| | | // ç¹å»å³ä¾§æé®ï¼éè¦å¤æç¹å»çæ¯å
³é徿 è¿æ¯ç®å¤´å¾æ |
| | | close() { |
| | | this.$emit('close') |
| | | } |
| | | }, |
| | | // #ifdef APP-NVUE |
| | | beforeDestroy() { |
| | | this.stopAnimation = true |
| | | }, |
| | | // #endif |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import "../../libs/css/components.scss"; |
| | | |
| | | .u-notice { |
| | | @include flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | |
| | | &__left-icon { |
| | | align-items: center; |
| | | margin-right: 5px; |
| | | } |
| | | |
| | | &__right-icon { |
| | | margin-left: 5px; |
| | | align-items: center; |
| | | } |
| | | |
| | | &__content { |
| | | text-align: right; |
| | | flex: 1; |
| | | @include flex; |
| | | flex-wrap: nowrap; |
| | | overflow: hidden; |
| | | |
| | | &__text { |
| | | font-size: 14px; |
| | | color: $u-warning; |
| | | /* #ifndef APP-NVUE */ |
| | | // è¿ä¸å¥å¾éè¦ï¼ä¸ºäºè½è®©æ»å¨å·¦å³è¿æ¥èµ·æ¥ |
| | | padding-left: 100%; |
| | | word-break: keep-all; |
| | | white-space: nowrap; |
| | | animation: u-loop-animation 10s linear infinite both; |
| | | /* #endif */ |
| | | @include flex(row); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | @keyframes u-loop-animation { |
| | | 0% { |
| | | transform: translate3d(0, 0, 0); |
| | | } |
| | | |
| | | 100% { |
| | | transform: translate3d(-100%, 0, 0); |
| | | } |
| | | } |
| | | </style> |