一、选项卡的添加
1、在router/index.js修改之前的动态添加二级路由的代码
router.addRoute("homeName",{
path:routeObj.path,
component:()=>import(`@/views${routeObj.permission}.vue`),
meta:{
name:routeObj.title
}
})
在vue-router这个路由插件中,route表示的是路由对象,route的常见属性
属性名 | 含义 |
---|---|
path | 路径 |
component | 路由对应的组件对象 |
name | 路由名称 |
children | 子路由配置 |
meta | 路由元信息(携带额外信息) |
这里我们使用路由元信息,将选项卡的名称携带到路由对象上
2、在components文件下创建MyTags.vue组件,该组件用于完成封装的功能
<template>
<div>
<el-tag v-for="(item,index) in historyAry" :key="index">
<router-link :to="item.path">{{item.meta.name}}</router-link>
</el-tag>
</div>
</template>
<script>
export default {
props:{
historyAry:{
type:Array,
default:()=>[]
}
}
}
</script>
<style>
</style>
在vue开发中,将组件按照功能分为页面组件和自定义组件
页面组件:用来构建页面的组件,每个项目中页面组件不同,主要作用是用来渲染信息的
自定义组件:用于复用的,可以在该项目中使用,也可以在其他的项目使用
按照如上思路,在封装自定义组件的时候有一个策略
-
只在自定义组件中布局结构
-
数据来源于外部组件(页面组件)
3、由于选项卡列表在多个页面中操作,这个数据要在多个组件中使用,所有使用状态机来操作
-
在store/modules文件夹下创建tabs.js
export default{
namespaced:true,
state:{},
mutations:{}
}
-
在strore/index.js将tabs模块引入
import tabs from './modules/tabs'
const store=new Vuex.Store({
modules:{tabs},
})
export default store
-
在modules/tabs.js中模拟选项卡的数据
export default{
namespaced:true,
state:{
//模拟数据
history:[
{
path:'/home/userList',
meta:{
name:'用户管理'
}
},
{
path:'/home/studentList',
meta:{
name:'学员管理'
}
}
]
},
mutations:{}
}
-
在Home.vue组件中获取状态机中的数据
<template>
<el-main>
<HistoryTags :historyAry="history"></HistoryTags>
<!-- 配置二级路由出口 -->
<router-view></router-view>
</el-main>
</template>
import {mapState,createNamespacedHelpers} from 'vuex'
const {mapState:mapTabsState}=createNamespacedHelpers('tabs')
export default{
computed:{
...mapTabsState(['history'])
},
}
4、在二级路由对应的组件中添加beforeRouteEneter的选项,用来监听进入组件的组件的行为
beforeRouteEnter(to,from,next){
next(vm=>{
vm.addTabs(to)
})
}
这里注意:在beforeRouteEnter中是不能访问this,因为此时组件还没有实例,如果要访问this,可以通过next(vm=>{})
的方式来访问
5、在store.js中的mutations中定义addTabs方法,用来添加路由
export default{
namespaced:true,
state:{
//模拟数据
history:[]
},
mutations:{
addTabs(state,payload){
state.history.push(payload)
}
}
}
如上操作会重复添加相同的选项卡,为了避免这个问题的出现,我们可以添加如下代码来进行限制
mutations:{
addTabs(state,payload){
const isHash=state.history.some(item=>{
return item.path==payload.path
})
if(!isHash){
state.history.push(payload)
}
}
}
6、配置默认的二级路由和选显卡
-
在router/config.js中为Home组件配置默认二级路由
{
path:'/home',
name:'homeName',
component:Home,
children:[
{
//配置默认二级路由
path:'',
redirect:'/home/workplace'
}
]
}
-
修改state/modules/tabs.js
state:{
//模拟数据
history:[
{
path:'/home/workplace',
meta:{name:'工作台'}
}
]
}
二、删除选项卡
-
在store/modules/tabs.js中为mutaitons添加删除的方法
mutations:{
removeTabs(state,payload){
state.history.splice(payload,1)
}
}
-
在自定义组件HistoryTabs.vue中为
e-tags
添加可以被删除的属性,以及绑定删除的时候触发的事件
<template>
<div>
<el-tag v-for="(item,index) in historyAry" :key="index" closable @close="closeTags(index)">
<router-link :to="item.path">{{item.meta.name}}</router-link>
</el-tag>
</div>
</template>
<script>
export default {
props:{
historyAry:{
type:Array,
default:()=>[]
}
},
methods:{
closeTags(index){
//$emit(参数1,参数2)
//参数1:自定义事件的名称,参数2:是传递的值
this.$emit('closeTagEvent',index)
}
}
}
</script>
<style>
</style>
-
在Home.vue中绑定自定义事件,来向状态机发送关闭的mutations方法
<HistoryTags :historyAry="history" @closeTagEvent="removeTagsByIndex"></HistoryTags>
<script>
import {mapState,createNamespacedHelpers} from 'vuex'
const {mapState:mapTabsState,mapMutations:mapTabsMutations}=createNamespacedHelpers('tabs')
export default{
methods:{
...mapTabsMutations(['removeTabs']),
removeTagsByIndex(index){
console.log('indexaaaaa',index);
this.removeTabs(index)
}
}
}
</script>
-
删除选项卡的时候有一个bug,就是只是删除了tag,但是路由没有进行跳转,具体做法是
removeTagsByIndex(index){
console.log('indexaaaaa',index);
this.removeTabs(index)
this.$router.push(this.history[this.history.length-1].path)
}
-
工作台这个选项卡式不能删除的
<el-tag v-for="(item,index) in historyAry" :key="index" :closable="index!=0?true:false" @close="closeTags(index)">
<router-link :to="item.path">{{item.meta.name}}</router-link>
</el-tag>
三、选中选项卡
<template>
<div>
<el-tag v-for="(item,index) in historyAry"
:key="index"
:closable="index!=0?true:false" @close="closeTags(index)"
@click="selectTags(index)"
:effect="curIndex==index?'dark':'light'">
<router-link :to="item.path">{{item.meta.name}}</router-link>
</el-tag>
</div>
</template>
<script>
export default {
data(){
return{
curIndex:0
}
},
props:{
historyAry:{
type:Array,
default:()=>[]
}
},
methods:{
closeTags(index){
//$emit(参数1,参数2)
//参数1:自定义事件的名称,参数2:是传递的值
this.$emit('closeTagEvent',index)
},
selectTags(index){
this.curIndex=index
}
}
}
</script>