123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- <template>
- <view class="ui-popover" :class="popover ? 'show' : 'hide'">
- <view
- class="ui-popover-button"
- :class="[ui]"
- :id="'popover-button-' + elId"
- :style="{ zIndex: index + zIndexConfig.popover }"
- @tap="popoverClick"
- @mouseleave="mouseleave"
- @mouseover="mouseover"
- >
- <slot></slot>
- </view>
- <view class="ui-popover-box" :style="BoxStyle">
- <view class="ui-popover-content-box" :id="'popover-content-' + elId" :style="contentStyle">
- <view
- class="ui-popover-content radius text-a"
- :class="bg"
- :style="{ zIndex: index + zIndexConfig.popover + 2 }"
- >
- <view class="p-3 text-sm" v-if="tips">{{ tips }}</view>
- <block v-else><slot name="content" /></block>
- </view>
- <view class="ui-popover-arrow" :class="bg" :style="arrowStyle"></view>
- </view>
- </view>
- <view
- class="ui-popover-mask"
- :class="mask ? 'bg-mask-50' : ''"
- :style="{ zIndex: index + zIndexConfig.popover - 1 }"
- @tap="popover = false"
- v-if="(popover && tips == '' && time == 0) || mask"
- ></view>
- </view>
- </template>
- <script>
- import { guid } from '@/sheep/helper';
- import zIndexConfig from '@/sheep/config/zIndex.js';
- import sheep from '@/sheep';
- export default {
- name: 'suPopover',
- data() {
- return {
- elId: guid(),
- zIndexConfig,
- popover: false,
- BoxStyle: '',
- contentStyle: '',
- arrowStyle: '',
- button: {},
- content: {},
- };
- },
- props: {
- ui: {
- type: String,
- default: '',
- },
- tips: {
- type: String,
- default: '',
- },
- bg: {
- type: String,
- default: 'ui-BG',
- },
- mask: {
- type: Boolean,
- default: false,
- },
- show: {
- type: [Boolean, String],
- default: 'change',
- },
- hover: {
- type: Boolean,
- default: false,
- },
- index: {
- type: Number,
- default: 0,
- },
- time: {
- type: Number,
- default: 0,
- },
- bottom: {
- type: Boolean,
- default: false,
- },
- isChange: {
- type: Boolean,
- default: false,
- },
- },
- watch: {
- popover(val) {
- this._computedQuery(
- sheep.$platform.device.windowWidth,
- sheep.$platform.device.windowHeight,
- );
- if (val) {
- if (this.tips != '' || this.time > 0) {
- setTimeout(
- () => {
- this.popover = false;
- },
- this.time == 0 ? 3000 : this.time,
- );
- }
- this.sys_layer = this.sys_layer + 100;
- } else {
- this.sys_layer = this.sys_layer - 100;
- }
- this.$emit('update:show', val);
- },
- show(val) {
- this.popover = val;
- },
- },
- mounted() {
- this.$nextTick(() => {
- this._computedQuery(
- sheep.$platform.device.windowWidth,
- sheep.$platform.device.windowHeight,
- );
- // #ifdef H5
- uni.onWindowResize((res) => {
- this._computedQuery(res.size.windowWidth, res.size.windowHeight);
- });
- // #endif
- });
- },
- methods: {
- _onHide() {
- this.popover = false;
- },
- _computedQuery(w, h) {
- uni
- .createSelectorQuery()
- .in(this)
- .select('#popover-button-' + this.elId)
- .boundingClientRect((button) => {
- if (button != null) {
- this.button = button;
- } else {
- console.log('popover-button-' + this.elId + ' data error');
- }
- })
- .select('#popover-content-' + this.elId)
- .boundingClientRect((content) => {
- if (content != null) {
- this.content = content;
- let button = this.button;
- //contentStyle
- let contentStyle = '';
- let arrowStyle = '';
- this.BoxStyle = `width:${w}px; left:-${button.left}px;z-index: ${
- this.index + this.sys_layer + 102
- }`;
- // 判断气泡在上面还是下面
- if (button.bottom < h / 2 || this.bottom) {
- // '下';
- contentStyle = contentStyle + `top:10px;`;
- arrowStyle = arrowStyle + `top:${-5}px;`;
- } else {
- // '上';
- contentStyle = contentStyle + `bottom:${button.height + 10}px;`;
- arrowStyle = arrowStyle + `bottom:${-5}px;`;
- }
- // 判断气泡箭头在左中右
- let btnCenter = button.right - button.width / 2;
- let contentCenter = content.right - content.width / 2;
- if (
- (btnCenter < w / 3 && content.width > btnCenter) ||
- (content.width > w / 2 && btnCenter < w / 2)
- ) {
- // '左';
- contentStyle = contentStyle + `left:10px;`;
- arrowStyle = arrowStyle + `left:${btnCenter - 17}px;`;
- } else if (
- (btnCenter > (w / 6) * 4 && content.width > w - btnCenter) ||
- (content.width > w / 2 && btnCenter > w / 2)
- ) {
- // '右';
- contentStyle = contentStyle + `right:10px;`;
- arrowStyle = arrowStyle + `right:${w - btnCenter - 17}px;`;
- } else {
- // '中';
- contentStyle =
- contentStyle + `left:${button.left - content.width / 2 + button.width / 2}px;`;
- arrowStyle = arrowStyle + `left:0px;right:0px;margin:auto;`;
- }
- this.arrowStyle = arrowStyle + `z-index:${this.index + this.sys_layer + 1};`;
- this.contentStyle = contentStyle + `z-index:${this.index + this.sys_layer + 2};`;
- } else {
- console.log('popover-content-' + this.elId + ' data error');
- }
- })
- .exec();
- },
- popoverClick() {
- if (this.isChange) {
- return false;
- }
- if (this.tips == '') {
- this.popover = !this.popover;
- } else {
- this.popover = true;
- }
- },
- mouseover() {
- if (this.hover && (this.tips != '' || this.content.height != 0)) {
- this.popover = true;
- }
- },
- mouseleave() {
- if (this.hover) {
- this.popover = false;
- }
- },
- },
- };
- </script>
- <style lang="scss">
- .ui-popover {
- position: relative;
- .ui-popover-button {
- position: relative;
- }
- .ui-popover-box {
- position: absolute;
- .ui-popover-content-box {
- position: absolute;
- .ui-popover-content {
- position: relative;
- }
- .ui-popover-arrow {
- position: absolute;
- height: 15px;
- width: 15px;
- border-radius: 2px;
- transform: rotate(45deg);
- }
- &::after {
- content: '';
- width: 100%;
- height: 110%;
- position: absolute;
- background-color: #000000;
- top: 5%;
- left: 0;
- filter: blur(15px);
- opacity: 0.15;
- }
- }
- }
- .ui-popover-mask {
- position: fixed;
- width: 100%;
- height: 100%;
- top: 0;
- left: 0;
- }
- &.show {
- .ui-popover-button {
- }
- .ui-popover-content-box {
- opacity: 1;
- pointer-events: auto;
- }
- .ui-popover-arrow {
- display: block;
- }
- .ui-popover-mask {
- display: block;
- }
- }
- &.hide {
- .ui-popover-button {
- }
- .ui-popover-content-box {
- opacity: 0;
- pointer-events: none;
- }
- .ui-popover-arrow {
- display: none;
- }
- .ui-popover-mask {
- display: none;
- }
- }
- }
- </style>
|