¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <view |
| | | class="u-tooltip" |
| | | :style="[$u.addStyle(customStyle)]" |
| | | > |
| | | <u-overlay |
| | | :show="showTooltip && tooltipTop !== -10000 && overlay" |
| | | customStyle="backgroundColor: rgba(0, 0, 0, 0)" |
| | | @click="overlayClickHandler" |
| | | ></u-overlay> |
| | | <view class="u-tooltip__wrapper"> |
| | | <text |
| | | class="u-tooltip__wrapper__text" |
| | | :id="textId" |
| | | :ref="textId" |
| | | :userSelect="false" |
| | | :selectable="false" |
| | | @longpress.stop="longpressHandler" |
| | | :style="{ |
| | | color: color, |
| | | backgroundColor: bgColor && showTooltip && tooltipTop !== -10000 ? bgColor : 'transparent' |
| | | }" |
| | | >{{ text }}</text> |
| | | <u-transition |
| | | mode="fade" |
| | | :show="showTooltip" |
| | | duration="300" |
| | | :customStyle="{ |
| | | position: 'absolute', |
| | | top: $u.addUnit(tooltipTop), |
| | | zIndex: zIndex, |
| | | ...tooltipStyle |
| | | }" |
| | | > |
| | | <view |
| | | class="u-tooltip__wrapper__popup" |
| | | :id="tooltipId" |
| | | :ref="tooltipId" |
| | | > |
| | | <view |
| | | class="u-tooltip__wrapper__popup__indicator" |
| | | hover-class="u-tooltip__wrapper__popup__indicator--hover" |
| | | v-if="showCopy || buttons.length" |
| | | :style="[indicatorStyle, { |
| | | width: $u.addUnit(indicatorWidth), |
| | | height: $u.addUnit(indicatorWidth), |
| | | }]" |
| | | > |
| | | <!-- ç±äºnvue䏿¯æä¸è§å½¢ç»å¶ï¼è¿éå°±åä¸ä¸ªåæ¹å½¢ï¼åæè½¬45degï¼å¾å°é²åºçä¸ä¸ªä¸è§ --> |
| | | </view> |
| | | <view class="u-tooltip__wrapper__popup__list"> |
| | | <view |
| | | v-if="showCopy" |
| | | class="u-tooltip__wrapper__popup__list__btn" |
| | | hover-class="u-tooltip__wrapper__popup__list__btn--hover" |
| | | @tap="setClipboardData" |
| | | > |
| | | <text |
| | | class="u-tooltip__wrapper__popup__list__btn__text" |
| | | >å¤å¶</text> |
| | | </view> |
| | | <u-line |
| | | direction="column" |
| | | color="#8d8e90" |
| | | v-if="showCopy && buttons.length > 0" |
| | | length="18" |
| | | ></u-line> |
| | | <block v-for="(item , index) in buttons" :key="index"> |
| | | <view |
| | | class="u-tooltip__wrapper__popup__list__btn" |
| | | hover-class="u-tooltip__wrapper__popup__list__btn--hover" |
| | | > |
| | | <text |
| | | class="u-tooltip__wrapper__popup__list__btn__text" |
| | | @tap="btnClickHandler(index)" |
| | | >{{ item }}</text> |
| | | </view> |
| | | <u-line |
| | | direction="column" |
| | | color="#8d8e90" |
| | | v-if="index < buttons.length - 1" |
| | | length="18" |
| | | ></u-line> |
| | | </block> |
| | | </view> |
| | | </view> |
| | | </u-transition> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import props from './props.js'; |
| | | // #ifdef APP-NVUE |
| | | const dom = uni.requireNativePlugin('dom') |
| | | // #endif |
| | | // #ifdef H5 |
| | | import ClipboardJS from "./clipboard.min.js" |
| | | // #endif |
| | | /** |
| | | * Tooltip |
| | | * @description |
| | | * @tutorial https://www.uviewui.com/components/tooltip.html |
| | | * @property {String | Number} text éè¦æ¾ç¤ºçæç¤ºæå |
| | | * @property {String | Number} copyText ç¹å»å¤å¶æé®æ¶ï¼å¤å¶çææ¬ï¼ä¸ºç©ºå使ç¨textå¼ |
| | | * @property {String | Number} size ææ¬å¤§å°ï¼é»è®¤ 14 ï¼ |
| | | * @property {String} color åä½é¢è²ï¼é»è®¤ '#606266' ï¼ |
| | | * @property {String} bgColor å¼¹åºæç¤ºæ¡æ¶ï¼ææ¬çèæ¯è²ï¼é»è®¤ 'transparent' ï¼ |
| | | * @property {String} direction å¼¹åºæç¤ºçæ¹åï¼top-䏿¹ï¼bottom-䏿¹ï¼é»è®¤ 'top' ï¼ |
| | | * @property {String | Number} zIndex å¼¹åºæç¤ºçz-indexï¼nvueæ æï¼é»è®¤ 10071 ï¼ |
| | | * @property {Boolean} showCopy æ¯å¦æ¾ç¤ºå¤å¶æé®ï¼é»è®¤ true ï¼ |
| | | * @property {Array} buttons æ©å±çæé®ç» |
| | | * @property {Boolean} overlay æ¯å¦æ¾ç¤ºéæé®ç½©ä»¥é²æ¢è§¦æ¸ç©¿éï¼é»è®¤ true ï¼ |
| | | * @property {Object} customStyle å®ä¹éè¦ç¨å°çå¤é¨æ ·å¼ |
| | | * |
| | | * @event {Function} |
| | | * @example |
| | | */ |
| | | export default { |
| | | name: 'u-tooltip', |
| | | mixins: [uni.$u.mpMixin, uni.$u.mixin, props], |
| | | data() { |
| | | return { |
| | | // æ¯å¦å±ç¤ºæ°æ³¡ |
| | | showTooltip: true, |
| | | // çæå¯ä¸idï¼é²æ¢ä¸ä¸ªé¡µé¢å¤ä¸ªç»ä»¶ï¼é æå¹²æ° |
| | | textId: uni.$u.guid(), |
| | | tooltipId: uni.$u.guid(), |
| | | // åå§æ¶çè³ä¸ºå¾å¤§çå¼ï¼è®©å
¶ç§»å°å±å¹å¤é¢ï¼ä¸ºäºè®¡ç®å
ç´ ç尺寸 |
| | | tooltipTop: -10000, |
| | | // æ°æ³¡çä½ç½®ä¿¡æ¯ |
| | | tooltipInfo: { |
| | | width: 0, |
| | | left: 0 |
| | | }, |
| | | // ææ¬çä½ç½®ä¿¡æ¯ |
| | | textInfo: { |
| | | width: 0, |
| | | left: 0 |
| | | }, |
| | | // ä¸è§å½¢æç¤ºå¨çæ ·å¼ |
| | | indicatorStyle: {}, |
| | | // æ°æ³¡å¨å¯è½è¶
åºå±å¹è¾¹æ²¿èå´æ¶ï¼éæ°å®ä½åï¼è·ç¦»å±å¹è¾¹æ²¿çè·ç¦» |
| | | screenGap: 12, |
| | | // ä¸è§å½¢æç¤ºå¨ç宽é«ï¼ç±äºå¯¹å
ç´ è¿è¡äºè§åº¦æè½¬ï¼ç²¾ç¡®è®¡ç®æç¤ºå¨ä½ç½®æ¶ï¼éè¦ç¨å°å
¶å°ºå¯¸ä¿¡æ¯ |
| | | indicatorWidth: 14, |
| | | } |
| | | }, |
| | | watch: { |
| | | propsChange() { |
| | | this.getElRect() |
| | | } |
| | | }, |
| | | computed: { |
| | | // ç¹å«å¤çH5çå¤å¶ï¼å 为H5æµè§å¨æ¯èªå¸¦ç³»ç»å¤å¶åè½çï¼å¨H5ç¯å¢ |
| | | // å½ä¸äºä¾èµåæ°ååæ¶ï¼éè¦éæ°è®¡ç®æ°æ³¡åæç¤ºå¨çä½ç½®ä¿¡æ¯ |
| | | propsChange() { |
| | | return [this.text, this.buttons] |
| | | }, |
| | | // è®¡ç®æ°æ³¡åæç¤ºå¨çä½ç½®ä¿¡æ¯ |
| | | tooltipStyle() { |
| | | const style = { |
| | | transform: `translateY(${this.direction === 'top' ? '-100%' : '100%'})`, |
| | | }, |
| | | sys = uni.$u.sys(), |
| | | getPx = uni.$u.getPx, |
| | | addUnit = uni.$u.addUnit |
| | | if (this.tooltipInfo.width / 2 > this.textInfo.left + this.textInfo.width / 2 - this.screenGap) { |
| | | this.indicatorStyle = {} |
| | | style.left = `-${addUnit(this.textInfo.left - this.screenGap)}` |
| | | this.indicatorStyle.left = addUnit(this.textInfo.width / 2 - getPx(style.left) - this.indicatorWidth / |
| | | 2) |
| | | } else if (this.tooltipInfo.width / 2 > sys.windowWidth - this.textInfo.right + this.textInfo.width / 2 - |
| | | this.screenGap) { |
| | | this.indicatorStyle = {} |
| | | style.right = `-${addUnit(sys.windowWidth - this.textInfo.right - this.screenGap)}` |
| | | this.indicatorStyle.right = addUnit(this.textInfo.width / 2 - getPx(style.right) - this |
| | | .indicatorWidth / 2) |
| | | } else { |
| | | const left = Math.abs(this.textInfo.width / 2 - this.tooltipInfo.width / 2) |
| | | style.left = this.textInfo.width > this.tooltipInfo.width ? addUnit(left) : -addUnit(left) |
| | | this.indicatorStyle = {} |
| | | } |
| | | if (this.direction === 'top') { |
| | | style.marginTop = '-10px' |
| | | this.indicatorStyle.bottom = '-4px' |
| | | } else { |
| | | style.marginBottom = '-10px' |
| | | this.indicatorStyle.top = '-4px' |
| | | } |
| | | return style |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | this.getElRect() |
| | | }, |
| | | // é¿æè§¦åäºä»¶ |
| | | async longpressHandler() { |
| | | this.tooltipTop = 0 |
| | | this.showTooltip = true |
| | | }, |
| | | // ç¹å»éæé®ç½© |
| | | overlayClickHandler() { |
| | | this.showTooltip = false |
| | | }, |
| | | // ç¹å»å¼¹åºæé® |
| | | btnClickHandler(index) { |
| | | this.showTooltip = false |
| | | // 妿éè¦å±ç¤ºå¤å¶æé®ï¼æ¤å¤indexéè¦å 1ï¼å 为å¤å¶æé®å¨ç¬¬ä¸ä¸ªä½ç½® |
| | | this.$emit('click', this.showCopy ? index + 1 : index) |
| | | }, |
| | | // æ¥è¯¢å
容é«åº¦ |
| | | queryRect(ref) { |
| | | // #ifndef APP-NVUE |
| | | // $uGetRect为uViewèªå¸¦çèç¹æ¥è¯¢ç®åæ¹æ³ï¼è¯¦è§ææ¡£ä»ç»ï¼https://www.uviewui.com/js/getRect.html |
| | | // ç»ä»¶å
é¨ä¸è¬ç¨this.$uGetRectï¼å¯¹å¤ç为uni.$u.getRectï¼äºè
åè½ä¸è´ï¼åç§°ä¸å |
| | | return new Promise(resolve => { |
| | | this.$uGetRect(`#${ref}`).then(size => { |
| | | resolve(size) |
| | | }) |
| | | }) |
| | | // #endif |
| | | |
| | | // #ifdef APP-NVUE |
| | | // nvueä¸ï¼ä½¿ç¨domæ¨¡åæ¥è¯¢å
ç´ é«åº¦ |
| | | // è¿åä¸ä¸ªpromiseï¼è®©è°ç¨æ¤æ¹æ³ç主ä½è½ä½¿ç¨thenåè° |
| | | return new Promise(resolve => { |
| | | dom.getComponentRect(this.$refs[ref], res => { |
| | | resolve(res.size) |
| | | }) |
| | | }) |
| | | // #endif |
| | | }, |
| | | // å
ç´ å°ºå¯¸ |
| | | getElRect() { |
| | | // è°ç¨ä¹åï¼å
å°æç¤ºå¨è°æ´å°å±å¹å¤ï¼æ¹ä¾¿è·å尺寸 |
| | | this.showTooltip = true |
| | | this.tooltipTop = -10000 |
| | | uni.$u.sleep(500).then(() => { |
| | | this.queryRect(this.tooltipId).then(size => { |
| | | this.tooltipInfo = size |
| | | // è·åæ°æ³¡å°ºå¯¸ä¹åï¼å°å
¶éèï¼ä¸ºäºè®©ä¸æ¬¡åæ¢æ°æ³¡æ¾ç¤ºä¸éèæ¶ï¼ææ·¡å
¥æ·¡åºçææ |
| | | this.showTooltip = false |
| | | }) |
| | | this.queryRect(this.textId).then(size => { |
| | | this.textInfo = size |
| | | }) |
| | | }) |
| | | }, |
| | | // å¤å¶ææ¬å°ç²è´´æ¿ |
| | | setClipboardData() { |
| | | // å
³éç»ä»¶ |
| | | this.showTooltip = false |
| | | this.$emit('click', 0) |
| | | // #ifndef H5 |
| | | uni.setClipboardData({ |
| | | // ä¼å
使ç¨copyTextåæ®µï¼å¦ææ²¡æï¼åé»è®¤ä½¿ç¨textåæ®µå½åå¤å¶çå
容 |
| | | data: this.copyText || this.text, |
| | | success: () => { |
| | | this.showToast && uni.$u.toast('å¤å¶æå') |
| | | }, |
| | | fail: () => { |
| | | this.showToast && uni.$u.toast('å¤å¶å¤±è´¥') |
| | | }, |
| | | complete: () => { |
| | | this.showTooltip = false |
| | | } |
| | | }) |
| | | // #endif |
| | | |
| | | // #ifdef H5 |
| | | let event = window.event || e || {} |
| | | let clipboard = new ClipboardJS('', { |
| | | text: () => this.copyText || this.text |
| | | }) |
| | | clipboard.on('success', (e) => { |
| | | this.showToast && uni.$u.toast('å¤å¶æå') |
| | | clipboard.off('success') |
| | | clipboard.off('error') |
| | | // å¨å页åºç¨ä¸ï¼éè¦éæ¯DOMççå¬ |
| | | clipboard.destroy() |
| | | }) |
| | | clipboard.on('error', (e) => { |
| | | this.showToast && uni.$u.toast('å¤å¶å¤±è´¥') |
| | | clipboard.off('success') |
| | | clipboard.off('error') |
| | | // å¨å页åºç¨ä¸ï¼éè¦éæ¯DOMççå¬ |
| | | clipboard.destroy() |
| | | }) |
| | | clipboard.onClick(event) |
| | | // #endif |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import "../../libs/css/components.scss"; |
| | | |
| | | .u-tooltip { |
| | | position: relative; |
| | | @include flex; |
| | | |
| | | &__wrapper { |
| | | @include flex; |
| | | justify-content: center; |
| | | /* #ifndef APP-NVUE */ |
| | | white-space: nowrap; |
| | | /* #endif */ |
| | | |
| | | &__text { |
| | | font-size: 14px; |
| | | } |
| | | |
| | | &__popup { |
| | | @include flex; |
| | | justify-content: center; |
| | | |
| | | &__list { |
| | | background-color: #060607; |
| | | position: relative; |
| | | flex: 1; |
| | | border-radius: 5px; |
| | | padding: 0px 0; |
| | | @include flex(row); |
| | | align-items: center; |
| | | overflow: hidden; |
| | | |
| | | &__btn { |
| | | padding: 11px 13px; |
| | | |
| | | &--hover { |
| | | background-color: #58595B; |
| | | } |
| | | |
| | | &__text { |
| | | line-height: 12px; |
| | | font-size: 13px; |
| | | color: #FFFFFF; |
| | | } |
| | | } |
| | | } |
| | | |
| | | &__indicator { |
| | | position: absolute; |
| | | background-color: #060607; |
| | | width: 14px; |
| | | height: 14px; |
| | | bottom: -4px; |
| | | transform: rotate(45deg); |
| | | border-radius: 2px; |
| | | z-index: -1; |
| | | |
| | | &--hover { |
| | | background-color: #58595B; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |