vue elment-ui 对navTab导航组件封装
图示
组件
代码
<template>
<div class="nav-tab-wrap">
<div class="nav-list">
<div
v-for="(item, index) in navList"
:key="item"
class="nav-item"
:class="{'active': currentTab === index}"
@click="handleCurrentTab(index)"
>{{ item }}</div>
<!-- 下拉菜单类型导航 -->
<el-dropdown
v-for="(item, index) in navDropList"
:key="item.title"
class="nav-item"
:class="{'active': isActive(index)}"
@command="handleCurrentTab($event, index)"
>
<!-- 菜单标题 -->
<span class="el-dropdown-link">
{{ isActive(index) ? list[currentTab] : item.title }}
<i class="el-icon-arrow-down el-icon--right" />
</span>
<!-- 菜单项 -->
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="(v, i) in item.list"
:key="v"
:command="i + navList.length"
>{{ v }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
// 其他代码......
</div>
</template>
<script>
export default {
props: {
// 当前的tab
currentTab: {
type: Number,
default: 0
},
// 导航标签
navList: {
type: Array,
default: () => []
},
// 下拉菜单
navDropList: {
type: Array,
default: () => []
}
},
data() {
return {
list: this.navList
}
},
created() {
// 合并标题
this.navDropList.forEach(v => {
this.list = [...this.list, ...v.list]
})
},
methods: {
// 改变当前tab
handleCurrentTab(index, step) {
let value = index
for (let i = 0; i < step; i++) {
value += this.navDropList[i].list.length
}
this.$emit('handleCurrentTab', value)
},
// 是否选中菜单标题
isActive(step) {
let minLen = 0
let maxLen = this.navList.length
for (let i = 0; i < step + 1; i++) {
minLen = maxLen
maxLen += this.navDropList[i].list.length
}
return this.currentTab >= minLen && this.currentTab < maxLen
}
}
}
</script>
<style lang="less" scoped>
@import '~assets/less/variable.less';
.nav-tab-wrap{
height: 62px;
margin: 0 24px;
padding: 0 24px;
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 0 0 4px 4px;
background-color: #fff;
.nav-list{
flex: 1;
display: flex;
.nav-item{
color: @fontColor2;
font-size: 16px;
cursor: pointer;
& + .nav-item{
margin-left: 40px;
}
&:hover,
&.active{
color: @themeColor;
}
}
}
}
</style>
使用
父组件代码
<template>
<div class="my-tab-wrap">
<nav-tab
:current-tab="currentTab"
:nav-list="navList"
:nav-drop-list="navDropList"
@handleCurrentTab="handleCurrentTab"
/>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
import navTab from '../components/navTab'
export default {
components: {
navTab
},
data() {
return {
navList: ['标题1', '标题2', '标题3', '标题4'],
navDropList: [{
title: '菜单1',
list: ['菜单标题1', '菜单标题2', '菜单标题3']
}, {
title: '菜单2',
list: ['菜单标题1', '菜单标题2']
}]
}
},
computed: {
...mapState({
currentTab: state => state.myResource.currentTab
})
},
methods: {
...mapMutations('myResource', ['handleCurrentTab'])
}
}
</script>
<style lang="less" scoped>
</style>
vuex
myResource 模块下
const state = {
// 当前tab下标
currentTab: 2
}
const mutations = {
// 改变当前tab下标
handleCurrentTab(state, index) {
state.currentTab = index
}
}
const actions = {
}
export default {
namespaced: true,
state,
mutations,
actions
}
补充 另一种传参方式
// 通用组件-tab导航
<template>
<div class="nav-tab-wrap">
<!-- 普通导航 -->
<ul class="nav-list">
<li
v-for="(item) in navList"
:key="item.code"
class="nav-item"
>
<!-- 普通类型标签 -->
<span
v-if="!item.children"
class="nav-tab"
:class="{'active': item.code === currentCode}"
@click="handleCurrentTab(item)"
>{{ item.name }}</span>
<!-- 下拉类型标签 -->
<el-dropdown
v-else
class="nav-tab"
:class="{'active': item.code === parentCode}"
@command="handleCurrentTab($event, item.code)"
>
<span>
{{ item.code === parentCode ? currentName : item.name }}
<i class="el-icon-arrow-down el-icon--right" />
</span>
<!-- 下拉菜单 -->
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="child in item.children"
:key="child.code"
:command="child"
>{{ child.name }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
// 导航标签
navList: {
type: Array,
default: () => [{
code: '01',
name: '课件'
}, {
code: '02',
name: '导学案'
}, {
code: '03',
name: '试卷',
children: [{
code: '04',
name: '同步试卷'
}, {
code: '05',
name: '专题试卷'
}]
}, {
code: '06',
name: '哈哈'
}, {
code: '07',
name: '试卷aa',
children: [{
code: '08',
name: '同步试卷'
}]
}]
}
},
data() {
return {
currentCode: '01', // 当前选中的的导航code
currentName: '', // 当前选中的的导航name(主要用于下拉菜单的名称显示)
parentCode: '' // 下拉菜单导航的父级code(主要用于显示选中状态)
}
},
methods: {
// 切换导航时触发
handleCurrentTab({ code, name }, parentCode) {
this.currentCode = code
this.parentCode = parentCode || ''
this.currentName = name || ''
}
}
}
</script>
<style lang="less" scoped>
@import '~assets/less/variable.less';
.nav-tab-wrap{
height: 62px;
margin: 0 24px;
padding: 0 24px;
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 0 0 4px 4px;
background-color: #fff;
.nav-list{
flex: 1;
display: flex;
.nav-item{
margin-right: 40px;
.nav-tab{
color: @fontColor2;
font-size: 16px;
cursor: pointer;
&:hover,
&.active{
color: @themeColor;
}
}
}
}
}
</style>
完结~