inleft
2022-02-15 d734432a8bbbf863dc3de305f56e831c56ac767a
commit | author | age
9bcb19 1 <script>
I 2 import events from './events'
3
4 export default {
5   name: 'MultiTab',
6   data () {
7     return {
8       fullPathList: [],
9       pages: [],
10       activeKey: '',
11       newTabIndex: 0
12     }
13   },
14   created () {
15     // bind event
16     events.$on('open', val => {
17       if (!val) {
18         throw new Error(`multi-tab: open tab ${val} err`)
19       }
20       this.activeKey = val
21     }).$on('close', val => {
22       if (!val) {
23         this.closeThat(this.activeKey)
24         return
25       }
26       this.closeThat(val)
27     }).$on('rename', ({ key, name }) => {
28       console.log('rename', key, name)
29       try {
30         const item = this.pages.find(item => item.path === key)
31         item.meta.customTitle = name
32         this.$forceUpdate()
33       } catch (e) {
34       }
35     })
36
37     this.pages.push(this.$route)
38     this.fullPathList.push(this.$route.fullPath)
39     this.selectedLastPath()
40   },
41   methods: {
42     onEdit (targetKey, action) {
43       this[action](targetKey)
44     },
45     remove (targetKey) {
46       this.pages = this.pages.filter(page => page.fullPath !== targetKey)
47       this.fullPathList = this.fullPathList.filter(path => path !== targetKey)
48       // 判断当前标签是否关闭,若关闭则跳转到最后一个还存在的标签页
49       if (!this.fullPathList.includes(this.activeKey)) {
50         this.selectedLastPath()
51       }
52     },
53     selectedLastPath () {
54       this.activeKey = this.fullPathList[this.fullPathList.length - 1]
55     },
56
57     // content menu
58     closeThat (e) {
59       // 判断是否为最后一个标签页,如果是最后一个,则无法被关闭
60       if (this.fullPathList.length > 1) {
61         this.remove(e)
62       } else {
63         this.$message.info('这是最后一个标签了, 无法被关闭')
64       }
65     },
66     closeLeft (e) {
67       const currentIndex = this.fullPathList.indexOf(e)
68       if (currentIndex > 0) {
69         this.fullPathList.forEach((item, index) => {
70           if (index < currentIndex) {
71             this.remove(item)
72           }
73         })
74       } else {
75         this.$message.info('左侧没有标签')
76       }
77     },
78     closeRight (e) {
79       const currentIndex = this.fullPathList.indexOf(e)
80       if (currentIndex < (this.fullPathList.length - 1)) {
81         this.fullPathList.forEach((item, index) => {
82           if (index > currentIndex) {
83             this.remove(item)
84           }
85         })
86       } else {
87         this.$message.info('右侧没有标签')
88       }
89     },
90     closeAll (e) {
91       const currentIndex = this.fullPathList.indexOf(e)
92       this.fullPathList.forEach((item, index) => {
93         if (index !== currentIndex) {
94           this.remove(item)
95         }
96       })
97     },
98     closeMenuClick (key, route) {
99       this[key](route)
100     },
101     renderTabPaneMenu (e) {
102       return (
103         <a-menu {...{ on: { click: ({ key, item, domEvent }) => { this.closeMenuClick(key, e) } } }}>
104           <a-menu-item key="closeThat">关闭当前标签</a-menu-item>
105           <a-menu-item key="closeRight">关闭右侧</a-menu-item>
106           <a-menu-item key="closeLeft">关闭左侧</a-menu-item>
107           <a-menu-item key="closeAll">关闭全部</a-menu-item>
108         </a-menu>
109       )
110     },
111     // render
112     renderTabPane (title, keyPath) {
113       const menu = this.renderTabPaneMenu(keyPath)
114
115       return (
116         <a-dropdown overlay={menu} trigger={['contextmenu']}>
117           <span style={{ userSelect: 'none' }}>{ title }</span>
118         </a-dropdown>
119       )
120     }
121   },
122   watch: {
123     '$route': function (newVal) {
124       this.activeKey = newVal.fullPath
125       if (this.fullPathList.indexOf(newVal.fullPath) < 0) {
126         this.fullPathList.push(newVal.fullPath)
127         this.pages.push(newVal)
128       }
129     },
130     activeKey: function (newPathKey) {
131       this.$router.push({ path: newPathKey })
132     }
133   },
134   render () {
135     const { onEdit, $data: { pages } } = this
136     const panes = pages.map(page => {
137       return (
138         <a-tab-pane
139           style={{ height: 0, background: '#8999ee', color: '#899ee' }}
140           tab={this.renderTabPane(page.meta.customTitle || page.meta.title, page.fullPath)}
141           key={page.fullPath} closable={pages.length > 1}
142         >
143         </a-tab-pane>)
144     })
145
146     return (
147       <div class="ant-pro-multi-tab">
148         <div class="ant-pro-multi-tab-wrapper">
149           <a-tabs
150             hideAdd
151             tabBarGutter={-1}
152             type={'editable-card'}
153             v-model={this.activeKey}
154             tabBarStyle={{ background: '#FFF', margin: 0, paddingLeft: '0px', paddingTop: '0px' }}
155             {...{ on: { edit: onEdit } }}>
156             {panes}
157           </a-tabs>
158         </div>
159       </div>
160     )
161   }
162 }
163 </script>