element-ui 封装页面步骤导航定位条

微信公众号:前端程序猿之路
关注可了解更多的前端知识,反馈问题或建议,请公众号留言。
如果你觉得公众号内容对你有帮助,欢迎关注并转载

element-ui 封装页面步骤导航定位条

最近在用element-ui组件开发项目,项目页面中,由于页面比较长,所以页面右侧设计了步骤导航定位条,滚动页面后,右侧步骤条跟着滚动,并且右侧同步显示页面滚动到哪个模块上,查看了element-ui组件库,发现并没有现成的组件,所以自己封装了一个,便于项目中其它页面使用。
在这里插入图片描述

  mounted() {
    window.addEventListener('scroll', this.getScrollId);
  },
  destroyed(){
    window.removeEventListener('scroll', this.getScrollId);
  },

组件中在进入页面的时候就开始监听滚动事件并调用getScrollId方法,在页面销毁以后去掉监听。

  stepId: {
      type: Array,
      default: ""
    },

props中,stepId是从父组件中传过来的每个模块的id,类似于锚点,给每个模块添加一个id,便于判断。

getScrollId(){
      let height = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
      let docHeight = [];
      this.stepId.forEach(data=>{
        let s = document.getElementById(data);
        let domHeight = s.offsetTop+60;
        let S = Math.abs(Number(height) - Number(domHeight));
        docHeight.push(S);
      })
      let minIndex = docHeight.indexOf(Math.min.apply(null, docHeight));
      let dom = this.stepId[minIndex];
      this.current = minIndex;
    },

height返回当前页面相对于窗口显示区左上角的 Y 位置,domHeight返回每个模块距离页面上方的距离+60px。
两者做减法然后取绝对值存进docHeight数组中,并且找到数组中最小值的索引,这样就可以拿到距离页面顶部最近的一个模块id值了。
另外,这里还用到了element-ui组件中steps步骤条组件

<el-steps :active="active" finish-status="success">
    <el-step title="步骤 1"></el-step>
    <el-step title="步骤 2"></el-step>
    <el-step title="步骤 3"></el-step>
</el-steps>

组件中的active属性,接受一个Number,表明步骤的 index,从 0 开始,这时我们把上面找到的最小值的索引赋值给active就可以设置那个是激活的步骤了。
完成滚动变化右侧步骤条以后,还有一个要求是点击右侧步骤条也跳转到相应的模块,这个就简单了就用锚点即可

 <span class="stepIndex" v-for="(item,index) in stepId" :key="item" @click="jump(item)" :class="'step'+index">&nbsp</span>

每点击一次就滚动到相应模块id位置,这样就完成了组件功能的实现。

 jump(domId){
      // 当前窗口正中心位置到指定dom位置的距离
      //页面滚动了的距离
      let height = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;      
      //指定dom到页面顶端的距离
      let dom = document.getElementById(domId);
      let domHeight = dom.offsetTop+60;      
      //滚动距离计算
      var S = Number(height) - Number(domHeight);
      //判断上滚还是下滚
      if(S<0){
        //下滚
        S = Math.abs(S);
        window.scrollBy({ top: S, behavior: "smooth" });
      }else if(S==0){
        //不滚
        window.scrollBy({ top: 0, behavior: "smooth" });
      }else{
        //上滚
        S = -S
        window.scrollBy({ top: S, behavior: "smooth" });
      }
    },

把组件封装之后放到工程专门放组件的位置,我是放到了工程componnets文件夹里面,起一个通俗易懂的名字即可。在这里插入图片描述
为了避免每个用到的页面都得引用组件的麻烦,我直接在全局引用了组件,这样项目里面的页面直接用即可。

import commonStep from "@/components/step/index.vue";

父组件中:
页面引用的时候只需

<!-- 右侧导航 -->
<common-step :title="stepTitle" :stepId="stepId"></common-step>

在父组件data里面定义一下用到的属性stepTitle是步骤条中文,stepId对应模块的id,两者是对应的

子组件(直接上完整代码):

<template>
  <el-aside width="160px">
    <div style="position:fixed" class="step" :title="title" :stepId="stepId">
      <div style="height: 300px;">
        <el-steps direction="vertical" :active="current" style="position: relative;">                
          <el-step :title="item"  v-for="item in title" :key="item"></el-step>
        </el-steps>
        <span class="stepIndex" v-for="(item,index) in stepId" :key="item" @click="jump(item)" :class="'step'+index">&nbsp</span>
      </div>
  </div>
  </el-aside>
</template>

<script>
export default {
  name: "common-step",
  props: {
    title: {
      type: Array,
      default: ""
    },
    stepId: {
      type: Array,
      default: ""
    },
  },
  data() {
    return {
      current: 0,
    };
  },
  watch: {
  },
  mounted() {
    window.addEventListener('scroll', this.getScrollId);
  },
  destroyed(){
    window.removeEventListener('scroll', this.getScrollId);
  },
  methods: {
    jump(domId){
      // 当前窗口正中心位置到指定dom位置的距离
      //页面滚动了的距离
      let height = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;      
      //指定dom到页面顶端的距离
      let dom = document.getElementById(domId);
      let domHeight = dom.offsetTop+60;      
      //滚动距离计算
      var S = Number(height) - Number(domHeight);
      //判断上滚还是下滚
      if(S<0){
        //下滚
        S = Math.abs(S);
        window.scrollBy({ top: S, behavior: "smooth" });
      }else if(S==0){
        //不滚
        window.scrollBy({ top: 0, behavior: "smooth" });
      }else{
        //上滚
        S = -S
        window.scrollBy({ top: S, behavior: "smooth" });
      }
    },
    getScrollId(){
      let height = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
      let docHeight = [];
      this.stepId.forEach(data=>{
        let s = document.getElementById(data);
        let domHeight = s.offsetTop+60;
        let S = Math.abs(Number(height) - Number(domHeight));
        docHeight.push(S);
      })
      let minIndex = docHeight.indexOf(Math.min.apply(null, docHeight));
      let dom = this.stepId[minIndex];
      this.current = minIndex;
    },
  }
};
</script>

<style lang="scss" scoped>
.hidden {
  ::v-deep .el-dialog__body {
    padding: 0;
  }
}
.btnColor{
  color: #1890ff;
  border-color: #badeff;
  background-color: #e8f4ff;
}
.stepIndex{
  position: absolute;
  z-index: 3;
  width: 100%;
  height: 28px;
}
>>> .el-step.is-vertical .el-step__title{
  line-height: 32px;
}
>>> .el-step.is-vertical .el-step__line{
  top: 6px;
}
>>> .el-step__main{
  height: 50px;
}
>>> .el-steps--vertical{
  height: 0;
}
.step0{
  top: 2px;
}
.step1{
  top: 53px;
}
.step2{
  top: 103px;
}
.step3{
  top: 152px;
}
.step4{
  top: 204px;
}
.step5{
  top: 253px;
}
</style>

上面步骤做完以后运行即可,是不是很简单
以上就是所有,文中部分内容进行了参考,下面有参考链接,如果写的有什么问题烦请各位大佬指正,我会虚心修改。
撤喽。。。。

参考链接:
https://www.w3school.com.cn/jsref/prop_style_lineheight.asp
https://blog.csdn.net/weixin_39327044/article/details/90545902
在这里插入图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值