洪海涛 4 年之前
父节点
当前提交
e68535588d

+ 1 - 0
src/components/affix/affix.vue

@@ -84,6 +84,7 @@ export default {
           }
         )
       })
+      this.lazyUpdatePosition()
     },
     // @ts-ignore TS6133
     prepareMeasure() {

+ 119 - 11
src/views/monthlyReport/childrenPage/editReport/index.vue

@@ -1,30 +1,138 @@
 <template>
-  <div class="page-wrapper">
+  <div ref="pageWrapper" class="page-wrapper" @click="setInit">
+    <!--    :target="() => $refs.pageWrapper"-->
+    <!--    <Affix :offset-top="30" :target="() => $refs.pageWrapper.parentNode">-->
+    <!--      <el-button type="danger" size="small">测试</el-button>-->
+    <!--    </Affix>-->
     <!--  header  -->
     <headerCom title="月报" sub-title="新建月报" />
+
     <!--  content  -->
-    <div class="content-wrapper">
-      <el-button size="small">默认按钮</el-button>
-      <el-button type="primary" size="small">主要按钮</el-button>
-      <el-button type="success" size="small">成功按钮</el-button>
-      <el-button type="info" size="small">信息按钮</el-button>
-      <el-button type="warning" size="small">警告按钮</el-button>
-      <el-button type="danger" size="small"> 危险按钮</el-button>
-    </div>
+    <el-row class="content-wrapper" :gutter="20">
+      <el-col :span="20">
+        <el-button size="small">默认按钮</el-button>
+        <el-button type="primary" size="small">主要按钮</el-button>
+        <el-button type="success" size="small">成功按钮</el-button>
+        <el-button type="info" size="small">信息按钮</el-button>
+        <el-button type="warning" size="small">警告按钮</el-button>
+        <el-button type="danger" size="small"> 危险按钮</el-button>
+        <div v-for="i in 70" :key="i">
+          <el-button type="danger" size="small">测试</el-button>
+        </div>
+        <div id="user_2_2_0">user_2_2_0</div>
+        <div v-for="i in 70" :key="`${i}btn`">
+          <el-button size="small">默认按钮</el-button>
+          <el-button type="primary" size="small">主要按钮</el-button>
+          <el-button type="success" size="small">成功按钮</el-button>
+          <el-button type="info" size="small">信息按钮</el-button>
+          <el-button type="warning" size="small">警告按钮</el-button>
+        </div>
+      </el-col>
+      <el-col :span="4" style="padding-right: 0">
+        <Affix :offset-top="103" :target="() => $refs.pageWrapper.parentNode">
+          <Anchor
+            :list="list"
+            :active="anchorActive"
+            @change="anchorChange"
+            @openMenu="openMenu"
+          />
+          <Menu ref="menu" :menu-data="menuData">
+            <div>测试线上</div>
+          </Menu>
+        </Affix>
+      </el-col>
+    </el-row>
   </div>
 </template>
 
 <script type="text/javascript">
 import headerCom from '../../components/header'
+import Affix from '@/components/affix/affix'
+import Anchor from '../../components/anchor'
+import Menu from '../../components/menu'
 
 export default {
   name: '',
   components: {
-    headerCom
+    headerCom,
+    Affix,
+    Anchor,
+    Menu
   },
   data() {
-    return {}
+    return {
+      list: [
+        {
+          name: '上月问题跟进',
+          key: 'user_0'
+        },
+        { name: '本月重点问题', key: 'user_1' },
+        {
+          name: '本月详情',
+          key: 'user_2',
+          children: [
+            {
+              name: '一、线上问题',
+              key: 'user_2_0'
+            },
+            {
+              name: '二、质量流程&研发效率',
+              key: 'user_2_1',
+              children: [
+                {
+                  name: '1、延期',
+                  key: 'user_2_1_0'
+                },
+                {
+                  name: '2、线下问题',
+                  key: 'user_2_1_1'
+                }
+              ]
+            },
+            {
+              name: '三、发布质量',
+              key: 'user_2_2',
+              children: [
+                {
+                  name: '1、发布&回滚',
+                  key: 'user_2_2_0'
+                }
+              ]
+            }
+          ]
+        },
+        { name: '本月优秀', key: 'user_3' }
+      ],
+      anchorActive: '',
+      menuData: null
+    }
+  },
+  methods: {
+    anchorChange(item) {
+      this.anchorActive = item.key
+      const anchor = document.getElementById(`${item.key}`) // 参数为要跳转到的元素id
+      if (!anchor) {
+        return (this.$el.parentNode.scrollTop = 0)
+      }
+      this.$el.parentNode.scrollTop = anchor.offsetTop + 83 // chrome
+      // this.$el.scrollTop = anchor.offsetTop // firefox
+    },
+    openMenu({ event, item }) {
+      this.menuData = { event, item }
+      // console.log(event, item)
+    },
+    setInit() {
+      // window.addEventListener('click', () => {
+      //   this.$refs.menu.show = true
+      //   console.log(127)
+      // })
+    }
   }
+  // destroyed() {
+  //   window.removeEventListener('click', () => {
+  //     this.$refs.menu.show = true
+  //   })
+  // }
 }
 </script>
 <style scoped lang="less">

+ 148 - 0
src/views/monthlyReport/components/anchor.vue

@@ -0,0 +1,148 @@
+<template>
+  <div v-if="list.length" class="anchor-wrapper">
+    <div v-if="list.length > 1" class="line" />
+    <div v-for="(item, index) in list" :key="item.key" class="title-wrapper">
+      <div
+        v-if="index === 0 || index === list.length - 1"
+        class="radius"
+        :class="{
+          down: list.length > 1 && index === list.length - 1,
+          center: list.length === 1
+        }"
+      />
+
+      <div
+        class="mi"
+        @contextmenu.prevent="openMenu($event, item)"
+        @click="change(item)"
+        @mousemove="mouseMoveItem({ event: $event, item })"
+      >
+        <span class="title"> {{ item.name }}</span>
+      </div>
+
+      <span v-if="item.children && item.children.length">
+        <Anchor
+          :active="active"
+          :list="item.children"
+          @change="(item) => change(item)"
+          @mouseMoveItem="mouseMoveItem"
+          @openMenu="(val) => openMenu(val.event, val.item)"
+        />
+      </span>
+    </div>
+  </div>
+</template>
+
+<script>
+// import _ from 'lodash'
+
+export default {
+  name: 'Anchor',
+  props: {
+    list: {
+      type: Array,
+      require: false,
+      default: () => []
+    },
+    active: {
+      type: String,
+      require: false,
+      default: () => ''
+    }
+  },
+  data() {
+    return {
+      tooltipValue: false
+    }
+  },
+  methods: {
+    mouseMoveItem(event, item) {
+      // console.log(event, item, 66)
+      this.$emit('mouseMoveItem', { event, item })
+    },
+    change(item) {
+      this.$emit('change', item)
+    },
+    openMenu(event, item) {
+      this.tooltipValue = false
+      this.hide = false
+      this.$emit('openMenu', { event, item })
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+.anchor-wrapper {
+  background-color: #ffffff;
+  position: relative;
+  padding: 5px 0;
+  overflow: hidden;
+
+  .title-wrapper {
+    margin-top: 5px;
+    margin-left: 10px;
+    padding-left: 10px;
+    position: relative;
+
+    .title {
+      cursor: pointer;
+      //display: inline-block;
+      &:hover,
+      &.active {
+        color: #409eff;
+      }
+
+      &.hide,
+      &.hide:hover {
+        color: #999999;
+      }
+    }
+
+    .title.hide,
+    .title.hide:hover {
+      color: #999999;
+    }
+  }
+
+  .radius {
+    position: absolute;
+    left: -5px;
+    top: -5px;
+    width: 7px;
+    height: 7px;
+    background: #ffffff;
+    border: 1px solid #409eff;
+    border-radius: 50%;
+    opacity: 1;
+
+    &.center {
+      top: 7px;
+    }
+
+    &.down {
+      bottom: -5px;
+      top: auto;
+    }
+  }
+
+  .line {
+    position: absolute;
+    width: 0px;
+    top: 14px;
+    left: 8px;
+    //height: -webkit-fill-available;
+    height: calc(100% - 23px);
+    //border: 1px solid #e9e9e9;
+    border-left: 0.5px solid #e9e9e9;
+    opacity: 1;
+  }
+
+  .mi {
+    width: 100%;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+}
+</style>

+ 73 - 0
src/views/monthlyReport/components/menu.vue

@@ -0,0 +1,73 @@
+<template>
+  <!--  左侧菜单  -->
+  <div
+    v-clickoutside="closeMenu"
+    class="left-menu-wrapper"
+    :class="{ hide: show }"
+    :style="menuStyle"
+  >
+    <slot />
+  </div>
+</template>
+
+<script>
+import Clickoutside from 'element-ui/src/utils/clickoutside'
+
+export default {
+  name: 'Menu',
+  directives: { Clickoutside },
+  props: {
+    menuData: {
+      type: Object,
+      require: false,
+      default: () => {}
+    }
+  },
+  data() {
+    return {
+      show: true,
+      timeout: null,
+      menuStyle: {}
+    }
+  },
+  watch: {
+    menuData: {
+      handler() {
+        this.init()
+      },
+      deep: true
+    }
+  },
+  methods: {
+    init() {
+      this.show = false
+      this.menuStyle = {
+        left: `${this.menuData.event.clientX + 10}px`,
+        top: `${this.menuData.event.clientY + 15}px`
+      }
+    },
+    closeMenu() {
+      clearTimeout(this.timeout)
+      this.timeout = setTimeout(() => {
+        // this.show = true
+      }, 0)
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+.left-menu-wrapper {
+  position: fixed;
+  z-index: 1000;
+  background: #ffffff;
+  box-shadow: 0px 0px 33px rgba(74, 81, 100, 0.12);
+
+  width: 100px;
+  height: 100px;
+
+  &.hide {
+    display: none;
+  }
+}
+</style>

+ 3 - 2
src/views/monthlyReport/style.less

@@ -1,5 +1,5 @@
 .page-wrapper {
-  background-color: #F2F3F6;
+  background-color: #f2f3f6;
   min-height: calc(100vh - 80px);
   padding: 0 10px;
 }
@@ -9,6 +9,7 @@
   min-height: calc(100vh - 93px);
   box-shadow: 0 0 11px #eef0f5;
   border-radius: 6px;
-  margin-bottom: 10px;
   padding: 20px 30px;
+  width: 100%;
+  margin: 0 auto 10px;
 }