Vue 基于elementUI的电梯导航
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
}
}
}
}
USE
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>
为之则易,不为则难。