index.vue 3.55 KB
<template>
  <div class="side-menu-container" ref="fixMenuRef">
    <ul class="clearfix fixed-menu-container">
      <li
        class="menu-item"
        :class="{
          active: activeMenu === item.value
        }"
        v-for="item in list"
        :key="item.value"
        :data-key="item.value"
      >
        <span class="item-text" :data-key="item.value">{{ item.label }}</span>
      </li>
    </ul>
    <div
      ref="popperWrapper"
      class="test"
      :style="{
        opacity: visible ? 1 : 0,
        zIndex: visible ? 1 : -9999,
        top: currItemPostion.y,
        left: currItemPostion.x
      }"
    >
      <el-input
        ref="searchRef"
        class="menu-child-search"
        suffix-icon="el-icon-search"
        v-model="input"
        placeholder="请输入"
      />
      <p class="clearfix menu-child-item">
        <span>南京吾悦广场</span>
      </p>
      <p class="clearfix menu-child-item">
        <span>南京吾悦广场</span>
      </p>
      <p class="clearfix menu-child-item">
        <span>南京吾悦广场</span>
      </p>
      <p class="clearfix menu-child-item">
        <span>南京吾悦广场</span>
      </p>
    </div>
  </div>
</template>

<script>
export default {
  name: 'FixedMenu',
  data() {
    return {
      list: [
        { label: '集团', value: 'account' },
        { label: '商场', value: 'mall' },
        { label: '楼层', value: 'floor' },
        { label: '店铺', value: 'zone' }
      ],
      activeMenu: 'account',
      currItemPostion: { x: 0, y: 0 },
      input: '',
      visible: true
    }
  },
  mounted() {
    document.addEventListener('click', this.onMenuClick, false)
  },
  beforeDestroy() {
    document.removeEventListener('click', this.onMenuClick, false)
  },
  methods: {
    onMenuClick(ev) {
      ev.stopPropagation()
      try {
        const panels = this.$refs.fixMenuRef
        const key = ev.target.dataset.key
        if (key === 'account') {
          this.visible = false
          return
        }
        if (!panels.contains(ev.target)) {
          this.visible = false
        } else {
          this.$refs.searchRef.focus()
          this.visible = true
        }
        // 计算点位 固定选择特殊属性值的元素
        const el = document.querySelector(`.menu-item[data-key="${key}"]`)
        if (el && this.$refs.popperWrapper) {
          const popperWrapperRect = this.$refs.popperWrapper.getBoundingClientRect()
          const { x, y } = el.getBoundingClientRect()
          this.currItemPostion = {
            x: x - popperWrapperRect.width - 3 + 'px',
            y: y + 'px'
          }
        }
      } catch (error) {
        this.visible = false
        console.log(error)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.fixed-menu-container {
  position: fixed;
  width: 50px;
  right: 5.6vw;
  top: 30vh;
  box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.5);
}

.menu-item {
  background: #fff;
  padding: 12px 0;
  color: #444;
  text-align: center;
  font-size: 14px;
  box-sizing: border-box;
  cursor: pointer;

  &.active {
    color: #fff;
    background: #06f;
  }

  &:hover {
    color: #fff;
    background: #06f;
  }
}

.test {
  position: fixed;
  padding: 5px 9px;
  box-sizing: border-box;
  background: #fff;
  box-shadow: 0 0 1px -4px #333;
}

.menu-child-search {
  margin-bottom: 5px;
}

.menu-child-item {
  text-align: left;
  font-size: 13px;
  color: #888;
  padding-left: 6px;
  padding-right: 6px;
  margin-bottom: 4px;
  box-sizing: border-box;
  cursor: pointer;

  &:hover {
    background: #0069ff;
    color: #fff;
  }
}
</style>