166 lines
4.8 KiB
Vue
166 lines
4.8 KiB
Vue
<template>
|
|
<a-layout-content>
|
|
<div class="yo-tab-external-mount">
|
|
<a-tabs @change="onChange" @edit="onClose" hide-add type="editable-card" v-model="actived">
|
|
<a-tab-pane
|
|
:closable="pane.closable"
|
|
:force-render="true"
|
|
:key="pane.key"
|
|
v-for="pane in panes"
|
|
>
|
|
<a-dropdown :trigger="['contextmenu']" slot="tab">
|
|
<div @click.middle="() => pane.closable && $emit('close', pane.key)">
|
|
<a-icon :type="pane.icon" v-if="pane.icon" />
|
|
{{ pane.title }}
|
|
<a-tooltip :title="pane.subTitle" placement="bottom" v-if="pane.subTitle">
|
|
<span class="yo-layout-tab-subtitle">{{`- ${pane.subTitle}`}}</span>
|
|
</a-tooltip>
|
|
</div>
|
|
<a-menu slot="overlay">
|
|
<template v-if="mode === 'development'">
|
|
<a-menu-item @click="onCopyComponent(pane)" key="-1">
|
|
复制组件地址
|
|
<a-tag color="red">dev</a-tag>
|
|
</a-menu-item>
|
|
<a-menu-divider />
|
|
</template>
|
|
<a-menu-item @click="onLoadContentWindow(pane.key)" key="0">重新加载</a-menu-item>
|
|
<a-menu-divider />
|
|
<a-menu-item
|
|
:disabled="!pane.closable"
|
|
@click="() => pane.closable && $emit('close', pane.key)"
|
|
key="1"
|
|
>关闭</a-menu-item>
|
|
<a-menu-item
|
|
:disabled="!hasOther(pane)"
|
|
@click="$emit('close-other', pane.key)"
|
|
key="2"
|
|
>关闭其他标签页</a-menu-item>
|
|
<a-menu-item
|
|
:disabled="!hasRight(pane)"
|
|
@click="$emit('close-right', pane.key)"
|
|
key="3"
|
|
>关闭右侧标签页</a-menu-item>
|
|
</a-menu>
|
|
</a-dropdown>
|
|
<!-- <component
|
|
:is="pane.component"
|
|
:key="pane.key"
|
|
:param="pane.param"
|
|
ref="panes"
|
|
v-if="pane.loaded"
|
|
/>-->
|
|
</a-tab-pane>
|
|
</a-tabs>
|
|
|
|
<div class="yo-tab-external-mount-content">
|
|
<div
|
|
:class="pane.key === actived ? 'yo-tab-external-tabpane-active' : 'yo-tab-external-tabpane-inactive'"
|
|
:key="pane.key"
|
|
class="yo-tab-external-tabpane"
|
|
v-for="pane in panes"
|
|
>
|
|
<component
|
|
:id="pane.key"
|
|
:is="pane.component"
|
|
:key="pane.key"
|
|
:param="pane.param"
|
|
ref="panes"
|
|
v-if="pane.loaded"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</a-layout-content>
|
|
</template>
|
|
<script>
|
|
import NProgress from 'nprogress';
|
|
import 'nprogress/nprogress.css';
|
|
|
|
NProgress.configure({ parent: '.ant-layout-content > .yo-tab-external-mount > .yo-tab-external-mount-content' });
|
|
|
|
export default {
|
|
props: {
|
|
panes: {
|
|
type: Array,
|
|
},
|
|
tabActived: {
|
|
type: [String, Number],
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
mode: process.env.VUE_APP_NODE_ENV,
|
|
actived: '',
|
|
};
|
|
},
|
|
watch: {
|
|
tabActived() {
|
|
if (this.tabActived !== this.actived) {
|
|
this.actived = this.tabActived;
|
|
}
|
|
},
|
|
},
|
|
created() {
|
|
this.actived = this.tabActived;
|
|
},
|
|
methods: {
|
|
onLoadContentWindow(key) {
|
|
NProgress.start();
|
|
const pane = this.panes.find((p) => p.key === key);
|
|
|
|
// 打开之前先销毁
|
|
// 销毁后重新生成的组件会放置到$refs.panes的最后,所以这里直接根据索引取是错误的
|
|
// const index = this.panes.indexOf(pane);
|
|
// const component = this.$refs.panes && this.$refs.panes[index];
|
|
// if (component) {
|
|
// component.$destroy();
|
|
// }
|
|
|
|
const i = import(`@/pages${pane.path}`);
|
|
pane.component = () => i;
|
|
pane.loaded = false;
|
|
i.then(() => {})
|
|
.catch(() => {
|
|
pane.component = () => import('@/views/error/404');
|
|
})
|
|
.finally(() => {
|
|
pane.loaded = true;
|
|
NProgress.done();
|
|
});
|
|
},
|
|
onClose(targetKey, action) {
|
|
if (action === 'remove') {
|
|
this.$emit('close', targetKey);
|
|
}
|
|
},
|
|
onChange(activeKey) {
|
|
this.$emit('change', activeKey);
|
|
},
|
|
|
|
onCopyComponent(pane) {
|
|
try {
|
|
const copy = document.createElement('textarea');
|
|
document.body.append(copy);
|
|
copy.value = `/pages${pane.path}`;
|
|
copy.select();
|
|
setTimeout(() => {
|
|
document.execCommand('copy');
|
|
copy.remove();
|
|
this.$message.success('已复制到剪切板');
|
|
});
|
|
} catch {
|
|
this.$message.error('复制错误');
|
|
}
|
|
},
|
|
|
|
hasOther(pane) {
|
|
return this.panes.filter((p) => p.key !== pane.key && p.closable).length > 0;
|
|
},
|
|
|
|
hasRight(pane) {
|
|
return this.panes.length > this.panes.indexOf(pane) + 1;
|
|
},
|
|
},
|
|
};
|
|
</script> |