Skip to content

基于ElementUI的电梯导航

Posted on:2021年7月23日 at 11:56

MIXINS

elevator.js

import Velocity from "velocity-animate";
import { on, off, isInContainer } from "element-ui/src/utils/dom";
import _ from "lodash";

export default {
  computed: {
    rollWrapper: vm => {
      const { rollWrapper } = vm.$refs;
      return rollWrapper.$el ? rollWrapper.$el : rollWrapper;
    },
    lazyHandler: vm => _.throttle(vm.handleScrolling, 200),
  },
  data() {
    return {
      isScroll: false,
    };
  },
  mounted() {
    on(this.rollWrapper, "scroll", this.lazyHandler);
    this.$once(
      "hook:hook:beforeDestroy",
      off.bind(this, this.rollWrapper, "scroll", this.lazyHandler)
    );
  },
  methods: {
    handleNavChange(v) {
      this.isScroll = true;
      const { name } = v;
      const { rollWrapper } = this;
      const offset = rollWrapper.offsetTop;
      const sourceNode = this.$refs[name];
      const target = sourceNode.$el ? sourceNode.$el : sourceNode;
      Velocity(target, "scroll", {
        container: rollWrapper,
        duration: 500,
        offset: -offset,
        complete: () => (this.isScroll = false),
      });
    },
    handleScrolling() {
      if (this.isScroll) return;
      const { nav } = this;
      for (let i = 0; i < nav.length; i++) {
        const { name } = nav[i];
        const sourceNode = this.$refs[name];
        if (!sourceNode) continue;
        const target = sourceNode.$el ? sourceNode.$el : sourceNode;
        if (isInContainer(target, this.rollWrapper))
          return (this.activeModule = name);
      }
    },
  },
};

Usage

in components script

import elevator from "@/mixins/elevator";
  mixins: [elevator],
  computed: {
    nav: () => [
      {name: 'itemBaseInfo', label: '基础信息'},
      {name: 'itemSort', label: '分类属性'},
      {name: 'itemSpec', label: 'SKU&价格'},
      {name: 'itemPic', label: '产品图片'},
      {name: 'payAndLimit', label: '支付&限购'},
      {name: 'shipAndDelivery', label: '运费&发货'},
      {name: 'shopOtherConfig', label: '客服&售后&资质'}
    ]
  },
  data() {
      return {
                activeModule: 'itemBaseInfo'
              }
  }

in components template container

<div ref="rollWrapper" class="overflow-y">
  <section ref="itemBaseInfo"></section>
  <section ref="itemSort"></section>
  <section ref="itemSpec"></section>
  <section ref="itemPic"></section>
  <section ref="payAndLimit"></section>
  <section ref="shipAndDelivery"></section>
  <section ref="shopOtherConfig"></section>
</div>

in components template nav

<el-tabs v-model="activeModule" stretch @tab-click="handleNavChange">
  <el-tab-pane
    v-for="item in nav"
    :key="item.name"
    :label="item.label"
    :name="item.name"
  />
</el-tabs>