vue 控制fixed弹窗在div的相对位置

vue yekong

vue 控制fixed弹窗在div的相对位置,因为div最外层组件使用了overflow,为了避免弹窗被overflow影响,这里的弹窗使用fixed定位,使用fixed定位的话,就需要动态获取div距离左侧和距离顶部的距离,以便于控制弹窗的位置。
vue 控制fixed弹窗在div的相对位置

/**
* @Author: 858834013@qq.com
* @Name: screening
* @Date: 2022-08-07
* @Desc:
*/
<template>
  <div class="shijianType" ref="searchBody">
    <div class="shijianTypeTop" @click="show=!show">
      <span v-if="list2.length==0">全部事件类型</span>
      <div v-else class="caidan">
        <div class="caidanItem" v-for="(item,index) in list2" :key="index">
          <span v-if="index<3">{{ item }}</span>
        </div>
        <span v-if="list2.length - 3>0">+{{ list2.length - 3 }}</span>
      </div>
      <img src="../../assets/detail/icon_down.png" alt="">
    </div>
    <div class="pops" v-if="show" @click="show=false"></div>
    <div class="screening scrollBar" v-if="show" :style="{'top':top+'px','left':left+'px'}">
      <div class="taglist">
        <div class="tagitem" :class="{active:item.selected}" @click="getSelected(index)"
             v-for="(item,index) in list" :key="index">
          <img v-if="item.selected" src="../../assets/home3/kuang2.png" alt="">
          <img v-else src="../../assets/home3/kuang1.png" alt="">
          {{ item.title }}
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {mapState, mapGetters, mapMutations} from 'vuex';
import axios from "axios";

export default {
  name: "screening",
  components: {},
  props: {
    id: {
      type: String,
      default() {
        return '';
      }
    }
  },
  data() {
    return {
      show: false,
      list: [],
      newTop: 0,
      newleft: 0
    }
  },
  watch: {},
  mounted() {
    this.getJson()
    this.getTop()
    this.getIsSelected()
  },
  computed: {
    ...mapGetters(['typeList']),
    top: function () {
      var getTop = this.newTop + 54
      return getTop
    },
    left: function () {
      var getTop = this.newleft + 0
      return getTop
    },
    list2: function () {
      var list = []
      this.list.forEach((type) => {
        if (type.selected) {
          list.push(type.title)
        }
      });
      console.log(list)
      return list
    }
  },
  methods: {
    getTop() {
      this.newTop = this.$refs.searchBody.getBoundingClientRect().top
      this.newleft = this.$refs.searchBody.getBoundingClientRect().left
    },
    getJson() {
      var that = this;
      axios.get('/eventType.json')
        .then(function (response) {
          // 处理成功情况
          console.log(response.data)
          that.list = response.data
        })
        .catch(function (error) {
          // 处理错误情况
          console.log(error);
        })
        .then(function () {
          // 总是会执行
        });
    },
    getIsSelected() {
      this.list.forEach((type, index) => {
        this.list[index].selected = false
      });
      this.typeListInner.forEach((type) => {
        this.list.forEach((type2, index) => {
          if (type2.id == type) {
            this.list[index].selected = true
          }
        });
      });
    },
    getSelected(index) {
      this.list[index].selected = !this.list[index].selected
      var list = []
      this.list.forEach((type) => {
        if (type.selected) {
          list.push(type.id)
        }
      });
      this.$store.commit('typeList', list);
      // this.$store.commit('typeListInner', list);
    },
  }
}
</script>

<style lang="scss" scoped>
.screening {
  margin: 0 auto;
  position: fixed;
  left: 0px;
  height: 180px;
  padding: 20px;
  top: 50px;
  width: 256px;
  z-index: 101;
  background: url("../../assets/home3/typebg.png") no-repeat;
  background-size: 100% 100%;
  overflow-y: scroll;
}

.taglist {
  display: flex;
  width: 100%;
  justify-content: flex-start;
  align-items: flex-start;
  flex-wrap: wrap;
  flex-direction: row;
  align-content: flex-start;

  .tagitem {
    font-size: 14px;
    font-family: MicrosoftYaHei;
    font-weight: 400;
    color: #00ACFF;
    width: 50%;
    height: 32px;
    border-radius: 4px;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    flex-wrap: nowrap;
    flex-direction: row;
    align-content: flex-start;
    margin-bottom: 10px;
    cursor: pointer;

    img {
      width: 11px;
      height: 11px;
      margin-right: 5px;
    }
  }

  .tagitem.active {

  }
}

.shijianType {
  position: relative;
  width: 100%;
}

.shijianTypeTop {
  min-width: 180px;
  height: 34px;
  //background: url("../../assets/detail/selectedbg.png") no-repeat;
  background-size: 100% 100%;
  border: 1px solid #1290ff;
  border-radius: 2px;
  display: flex;
  cursor: pointer;
  justify-content: space-between;
  align-items: center;
  flex-wrap: nowrap;
  flex-direction: row;
  align-content: flex-start;

  span {
    margin-left: 5px;
  }

  img {
    margin-right: 10px;
  }

  span {
    font-size: 16px;
    font-family: PingFang;
    font-weight: 400;
    color: #1290FF;
  }
}

.pops {
  width: 100%;
  height: 100%;
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 100;
}

.caidan {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: wrap;
  flex-direction: row;
  align-content: flex-start;
  margin-left: 5px;

  .caidanItem {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }

  img {
    width: 16px;
    margin-right: 10px;
    margin-left: 10px;
  }
}
</style>

喜欢