学生管理系统-05封装选项卡

一、选项卡的添加

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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值