Default Changelist

feature/qzw
秦泽旺 8 months ago
parent 9fbe2efbb6
commit 52954f1563

@ -24,43 +24,58 @@
</div> </div>
</template> </template>
--> -->
<script> <script>
export default { export default {
//
name: 'MultiTab', name: 'MultiTab',
//
data () { data () {
return { return {
fullPathList: [], fullPathList: [], //
pages: [], pages: [], // Vue
activeKey: '', activeKey: '', // key
newTabIndex: 0 newTabIndex: 0 // 使
} }
}, },
//
created () { created () {
// pagesfullPathList
this.pages.push(this.$route) this.pages.push(this.$route)
this.fullPathList.push(this.$route.fullPath) this.fullPathList.push(this.$route.fullPath)
//
this.selectedLastPath() this.selectedLastPath()
}, },
methods: { methods: {
// action
onEdit (targetKey, action) { onEdit (targetKey, action) {
this[action](targetKey) this[action](targetKey)
}, },
// pagesfullPathList
remove (targetKey) { remove (targetKey) {
//
this.pages = this.pages.filter(page => page.fullPath !== targetKey) this.pages = this.pages.filter(page => page.fullPath !== targetKey)
this.fullPathList = this.fullPathList.filter(path => path !== targetKey) this.fullPathList = this.fullPathList.filter(path => path !== targetKey)
// //
if (!this.fullPathList.includes(this.activeKey)) { if (!this.fullPathList.includes(this.activeKey)) {
this.selectedLastPath() this.selectedLastPath()
} }
}, },
//
selectedLastPath () { selectedLastPath () {
this.activeKey = this.fullPathList[this.fullPathList.length - 1] this.activeKey = this.fullPathList[this.fullPathList.length - 1]
}, },
// content menu //
closeThat (e) { closeThat (e) {
this.remove(e) this.remove(e)
}, },
//
closeLeft (e) { closeLeft (e) {
const currentIndex = this.fullPathList.indexOf(e) const currentIndex = this.fullPathList.indexOf(e)
if (currentIndex > 0) { if (currentIndex > 0) {
@ -73,6 +88,8 @@ export default {
this.$message.info('左侧没有标签') this.$message.info('左侧没有标签')
} }
}, },
//
closeRight (e) { closeRight (e) {
const currentIndex = this.fullPathList.indexOf(e) const currentIndex = this.fullPathList.indexOf(e)
if (currentIndex < (this.fullPathList.length - 1)) { if (currentIndex < (this.fullPathList.length - 1)) {
@ -85,6 +102,8 @@ export default {
this.$message.info('右侧没有标签') this.$message.info('右侧没有标签')
} }
}, },
//
closeAll (e) { closeAll (e) {
const currentIndex = this.fullPathList.indexOf(e) const currentIndex = this.fullPathList.indexOf(e)
this.fullPathList.forEach((item, index) => { this.fullPathList.forEach((item, index) => {
@ -93,6 +112,8 @@ export default {
} }
}) })
}, },
//
closeMenuClick ({ key, item, domEvent }) { closeMenuClick ({ key, item, domEvent }) {
const vkey = domEvent.target.getAttribute('data-vkey') const vkey = domEvent.target.getAttribute('data-vkey')
switch (key) { switch (key) {
@ -111,6 +132,8 @@ export default {
break break
} }
}, },
//
renderTabPaneMenu (e) { renderTabPaneMenu (e) {
return ( return (
<a-menu {...{ on: { click: this.closeMenuClick } }}> <a-menu {...{ on: { click: this.closeMenuClick } }}>
@ -121,7 +144,8 @@ export default {
</a-menu> </a-menu>
) )
}, },
// render
//
renderTabPane (title, keyPath) { renderTabPane (title, keyPath) {
const menu = this.renderTabPaneMenu(keyPath) const menu = this.renderTabPaneMenu(keyPath)
@ -132,18 +156,26 @@ export default {
) )
} }
}, },
//
watch: { watch: {
'$route': function (newVal) { '$route': function (newVal) {
//
this.activeKey = newVal.fullPath this.activeKey = newVal.fullPath
// fullPathList
if (this.fullPathList.indexOf(newVal.fullPath) < 0) { if (this.fullPathList.indexOf(newVal.fullPath) < 0) {
this.fullPathList.push(newVal.fullPath) this.fullPathList.push(newVal.fullPath)
this.pages.push(newVal) this.pages.push(newVal)
} }
}, },
// activeKey
activeKey: function (newPathKey) { activeKey: function (newPathKey) {
this.$router.push({ path: newPathKey }) this.$router.push({ path: newPathKey })
} }
}, },
//
render () { render () {
const { onEdit, $data: { pages } } = this const { onEdit, $data: { pages } } = this
const panes = pages.map(page => { const panes = pages.map(page => {
@ -160,16 +192,16 @@ export default {
<div class="ant-pro-multi-tab"> <div class="ant-pro-multi-tab">
<div class="ant-pro-multi-tab-wrapper"> <div class="ant-pro-multi-tab-wrapper">
<a-tabs <a-tabs
hideAdd hideAdd //
type={'editable-card'} type={'editable-card'} //
v-model={this.activeKey} v-model={this.activeKey} //
tabBarStyle={{ background: '#FFF', margin: 0, paddingLeft: '16px', paddingTop: '1px' }} tabBarStyle={{ background: '#FFF', margin: 0, paddingLeft: '16px', paddingTop: '1px' }} //
{...{ on: { edit: onEdit } }}> {...{ on: { edit: onEdit } }}> //
{panes} {panes} //
</a-tabs> </a-tabs>
</div> </div>
</div> </div>
) )
} }
} }
</script> </script>

@ -1,4 +1,9 @@
import MultiTab from './MultiTab' // 导入名为 MultiTab 的Vue组件该组件定义在当前目录下的 MultiTab.vue 文件中
import './index.less' import MultiTab from './MultiTab';
export default MultiTab // 导入index.less样式表文件用于为MultiTab组件提供样式定义
import './index.less';
// 将导入的 MultiTab 组件设置为默认导出
// 这样其他文件就可以通过 import MultiTab 来使用这个组件
export default MultiTab;

@ -1,25 +1,34 @@
// 导入外部样式表,可能是包含通用样式或变量定义的文件
@import '../index'; @import '../index';
// 定义多标签组件的前缀类用于构建CSS选择器
@multi-tab-prefix-cls: ~"@{ant-pro-prefix}-multi-tab"; @multi-tab-prefix-cls: ~"@{ant-pro-prefix}-multi-tab";
@multi-tab-wrapper-prefix-cls: ~"@{ant-pro-prefix}-multi-tab-wrapper"; @multi-tab-wrapper-prefix-cls: ~"@{ant-pro-prefix}-multi-tab-wrapper";
/* /*
* 定义多标签组件在.topmenu类下的样式
* 设置最大宽度为1200px
* 设置左右边距,左边距为-23px右边距为24px自动居中
*/
.topmenu .@{multi-tab-prefix-cls} { .topmenu .@{multi-tab-prefix-cls} {
max-width: 1200px; max-width: 1200px;
margin: -23px auto 24px auto; margin: -23px auto 24px auto;
} }
*/
// 为多标签组件设置通用样式
.@{multi-tab-prefix-cls} { .@{multi-tab-prefix-cls} {
margin: -23px -24px 24px -24px; margin: -23px -24px 24px -24px; // 设置四个方向的边距
background: #fff; background: #fff; // 背景颜色为白色
} }
// 定义多标签组件在.topmenu类下的多标签包装器的样式
.topmenu .@{multi-tab-wrapper-prefix-cls} { .topmenu .@{multi-tab-wrapper-prefix-cls} {
max-width: 1200px; max-width: 1200px; // 最大宽度为1200px
margin: 0 auto; margin: 0 auto; // 水平居中对齐
} }
// 当内容宽度是流体布局时设置多标签包装器的最大宽度为100%
.topmenu.content-width-Fluid .@{multi-tab-wrapper-prefix-cls} { .topmenu.content-width-Fluid .@{multi-tab-wrapper-prefix-cls} {
max-width: 100%; max-width: 100%; // 最大宽度为100%
margin: 0 auto; margin: 0 auto; // 水平居中对齐
} }

@ -1,4 +1,5 @@
<template> <template>
<!-- 使用 a-popover 组件创建一个弹出框以下是对其配置属性的设置 -->
<a-popover <a-popover
v-model="visible" v-model="visible"
trigger="click" trigger="click"
@ -8,13 +9,21 @@
:arrowPointAtCenter="true" :arrowPointAtCenter="true"
:overlayStyle="{ width: '300px', top: '50px' }" :overlayStyle="{ width: '300px', top: '50px' }"
> >
<!-- 定义弹出框内容的插槽 -->
<template slot="content"> <template slot="content">
<!-- 使用 a-spin 组件根据 loadding 变量的值来显示加载状态 -->
<a-spin :spinning="loadding"> <a-spin :spinning="loadding">
<!-- 使用 a-tabs 组件创建选项卡 -->
<a-tabs> <a-tabs>
<!-- 第一个选项卡通知的配置 -->
<a-tab-pane tab="通知" key="1"> <a-tab-pane tab="通知" key="1">
<!-- 使用 a-list 组件创建列表 -->
<a-list> <a-list>
<!-- 列表中的一个列表项 -->
<a-list-item> <a-list-item>
<!-- a-list-item-meta 用于展示列表项中的元信息如标题描述等 -->
<a-list-item-meta title="你收到了 14 份新周报" description="一年前"> <a-list-item-meta title="你收到了 14 份新周报" description="一年前">
<!-- 使用 a-avatar 组件展示头像设置了背景色和头像图片来源 -->
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png"/> <a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png"/>
</a-list-item-meta> </a-list-item-meta>
</a-list-item> </a-list-item>
@ -30,17 +39,22 @@
</a-list-item> </a-list-item>
</a-list> </a-list>
</a-tab-pane> </a-tab-pane>
<!-- 第二个选项卡消息的配置内容暂时为简单文本123 -->
<a-tab-pane tab="消息" key="2"> <a-tab-pane tab="消息" key="2">
123 123
</a-tab-pane> </a-tab-pane>
<!-- 第三个选项卡待办的配置内容暂时为简单文本123 -->
<a-tab-pane tab="待办" key="3"> <a-tab-pane tab="待办" key="3">
123 123
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
</a-spin> </a-spin>
</template> </template>
<!-- 点击此元素会触发 fetchNotice 方法同时添加了 header-notice 类名 -->
<span @click="fetchNotice" class="header-notice"> <span @click="fetchNotice" class="header-notice">
<!-- 使用 a-badge 组件展示一个带有数字的徽标这里数字为 12 -->
<a-badge count="12"> <a-badge count="12">
<!-- 使用 a-icon 组件展示一个铃铛图标设置了字体大小和内边距 -->
<a-icon style="font-size: 16px; padding: 4px" type="bell" /> <a-icon style="font-size: 16px; padding: 4px" type="bell" />
</a-badge> </a-badge>
</span> </span>
@ -52,38 +66,48 @@ export default {
name: 'HeaderNotice', name: 'HeaderNotice',
data () { data () {
return { return {
// loadding false
loadding: false, loadding: false,
// visible a-popover false
visible: false visible: false
} }
}, },
methods: { methods: {
fetchNotice () { fetchNotice() {
//
if (!this.visible) { if (!this.visible) {
this.loadding = true // loadding true
this.loadding = true;
// loadding false
setTimeout(() => { setTimeout(() => {
this.loadding = false this.loadding = false;
}, 2000) }, 2000);
} else { } else {
this.loadding = false // loadding false
this.loadding = false;
} }
this.visible = !this.visible //
this.visible = !this.visible;
} }
} }
} }
</script> </script>
<style lang="css"> <style lang="css">
.header-notice-wrapper { /* 针对类名为 header-notice-wrapper 的元素设置样式,强制将 top 值设为 50px覆盖可能存在的其他样式 */
top: 50px !important; .header-notice-wrapper {
} top: 50px !important;
}
</style> </style>
<style lang="less" scoped> <style lang="less" scoped>
.header-notice{ /* 对类名为 header-notice 的元素设置样式,使其显示为内联块元素,并设置过渡效果 */
display: inline-block; .header-notice {
transition: all 0.3s; display: inline-block;
transition: all 0.3s;
span { span {
vertical-align: initial; // span
} vertical-align: initial;
} }
</style> }
</style>

@ -1,2 +1,10 @@
// 从当前目录下的'./NoticeIcon'文件中导入名为NoticeIcon的模块或组件。
// './NoticeIcon'指的是与当前文件同一目录下的NoticeIcon文件可能是一个React组件
// 这里的导入路径是相对于当前文件的相对路径。
import NoticeIcon from './NoticeIcon' import NoticeIcon from './NoticeIcon'
export default NoticeIcon
// 导出NoticeIcon模块或组件使得其他文件可以通过import语句来引用它。
// 使用export default语法表示默认导出这意味着在导入时不需要使用花括号{}。
// 这使得其他文件可以通过类似import SomeName from './path/to/this/file'的方式导入NoticeIcon
// 其中SomeName可以是任意名称但导入的内容将是这里导出的NoticeIcon。
export default NoticeIcon

@ -1,27 +1,41 @@
<template> <template>
<!-- 创建一个带有 page-header 类名的 div 容器作为页面头部的外层包裹元素 -->
<div class="page-header"> <div class="page-header">
<!-- 创建一个带有 page-header-index-wide 类名的 div 容器可能用于页面头部的特定布局或样式控制 -->
<div class="page-header-index-wide"> <div class="page-header-index-wide">
<!-- 使用 s-breadcrumb 组件可能用于展示面包屑导航具体功能取决于该组件的实现 -->
<s-breadcrumb /> <s-breadcrumb />
<!-- 创建一个名为 detail div 容器用于放置页面头部更详细的内容 -->
<div class="detail"> <div class="detail">
<!-- 条件判断如果路由元信息中的 hiddenHeaderContent false则展示以下内容 -->
<div class="main" v-if="!$route.meta.hiddenHeaderContent"> <div class="main" v-if="!$route.meta.hiddenHeaderContent">
<!-- 创建一个 row 类名的 div 容器可能用于布局类似行的概念 -->
<div class="row"> <div class="row">
<!-- 如果 logo 属性有值则展示对应的图片图片的源地址由 logo 属性绑定并且添加 logo 类名用于样式控制 -->
<img v-if="logo" :src="logo" class="logo"/> <img v-if="logo" :src="logo" class="logo"/>
<!-- 如果 title 属性有值则展示对应的标题内容使用双大括号进行数据绑定展示 title 属性的值并添加 title 类名用于样式控制 -->
<h1 v-if="title" class="title">{{ title }}</h1> <h1 v-if="title" class="title">{{ title }}</h1>
<!-- 创建一个名为 action div 容器用于放置具名插槽内容可能是一些操作按钮之类的元素 -->
<div class="action"> <div class="action">
<slot name="action"></slot> <slot name="action"></slot>
</div> </div>
</div> </div>
<!-- 再创建一个 row 类名的 div 容器继续放置页面头部的其他元素 -->
<div class="row"> <div class="row">
<!-- 如果 avatar 属性有值则展示对应的头像元素使用 a-avatar 组件展示图片源地址由 avatar 属性绑定 -->
<div v-if="avatar" class="avatar"> <div v-if="avatar" class="avatar">
<a-avatar :src="avatar" /> <a-avatar :src="avatar" />
</div> </div>
<!-- 如果有名为 content 的插槽内容则展示对应的插槽内容并添加 headerContent 类名用于样式控制 -->
<div v-if="this.$slots.content" class="headerContent"> <div v-if="this.$slots.content" class="headerContent">
<slot name="content"></slot> <slot name="content"></slot>
</div> </div>
<!-- 如果有名为 extra 的插槽内容则展示对应的插槽内容并添加 extra 类名用于样式控制 -->
<div v-if="this.$slots.extra" class="extra"> <div v-if="this.$slots.extra" class="extra">
<slot name="extra"></slot> <slot name="extra"></slot>
</div> </div>
</div> </div>
<!-- 放置一个用于名为 pageMenu 的插槽内容的容器可能用于展示页面相关的菜单选项等 -->
<div> <div>
<slot name="pageMenu"></slot> <slot name="pageMenu"></slot>
</div> </div>
@ -32,24 +46,29 @@
</template> </template>
<script> <script>
// '../../components/tools/Breadcrumb' Breadcrumb
import Breadcrumb from '../../components/tools/Breadcrumb' import Breadcrumb from '../../components/tools/Breadcrumb'
export default { export default {
name: 'PageHeader', name: 'PageHeader',
components: { components: {
// Breadcrumb s-breadcrumb 便使
's-breadcrumb': Breadcrumb 's-breadcrumb': Breadcrumb
}, },
props: { props: {
// title true
title: { title: {
type: [String, Boolean], type: [String, Boolean],
default: true, default: true,
required: false required: false
}, },
// logo
logo: { logo: {
type: String, type: String,
default: '', default: '',
required: false required: false
}, },
// avatar
avatar: { avatar: {
type: String, type: String,
default: '', default: '',
@ -63,89 +82,131 @@ export default {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
// page-header
.page-header { .page-header {
//
background: #fff; background: #fff;
// 16px 32px 0
padding: 16px 32px 0; padding: 16px 32px 0;
// 1px#e8e8e8
border-bottom: 1px solid #e8e8e8; border-bottom: 1px solid #e8e8e8;
.breadcrumb { .breadcrumb {
// 16px
margin-bottom: 16px; margin-bottom: 16px;
} }
.detail { .detail {
// 便
display: flex; display: flex;
/*margin-bottom: 16px;*/ /*margin-bottom: 16px;*/
.avatar { .avatar {
// 72px
flex: 0 1 72px; flex: 0 1 72px;
// 24px 8px
margin: 0 24px 8px 0; margin: 0 24px 8px 0;
& > span { & > span {
// 72px使
border-radius: 72px; border-radius: 72px;
//
display: block; display: block;
// 72px
width: 72px; width: 72px;
// 72px
height: 72px; height: 72px;
} }
} }
.main { .main {
//
width: 100%; width: 100%;
//
flex: 0 1 auto; flex: 0 1 auto;
.row { .row {
// 便
display: flex; display: flex;
//
width: 100%; width: 100%;
.avatar { .avatar {
// 16px
margin-bottom: 16px; margin-bottom: 16px;
} }
} }
.title { .title {
// 20px
font-size: 20px; font-size: 20px;
// 500
font-weight: 500; font-weight: 500;
font-size: 20px; font-size: 20px;
line-height: 28px; line-height: 28px;
font-weight: 500; font-weight: 500;
// rgba
color: rgba(0, 0, 0, 0.85); color: rgba(0, 0, 0, 0.85);
// 16px
margin-bottom: 16px; margin-bottom: 16px;
//
flex: auto; flex: auto;
} }
.logo { .logo {
// 28px
width: 28px; width: 28px;
// 28px
height: 28px; height: 28px;
// 4px
border-radius: 4px; border-radius: 4px;
// 16px
margin-right: 16px; margin-right: 16px;
} }
.content, .content,
.headerContent { .headerContent {
//
flex: auto; flex: auto;
// rgba
color: rgba(0, 0, 0, 0.45); color: rgba(0, 0, 0, 0.45);
// 22px
line-height: 22px; line-height: 22px;
.link { .link {
// 16px
margin-top: 16px; margin-top: 16px;
// 24px
line-height: 24px; line-height: 24px;
a { a {
// 14px
font-size: 14px; font-size: 14px;
// 32px
margin-right: 32px; margin-right: 32px;
} }
} }
} }
.extra { .extra {
//
flex: 0 1 auto; flex: 0 1 auto;
// 88px
margin-left: 88px; margin-left: 88px;
// 242px
min-width: 242px; min-width: 242px;
//
text-align: right; text-align: right;
} }
.action { .action {
// 56px
margin-left: 56px; margin-left: 56px;
// 266px
min-width: 266px; min-width: 266px;
//
flex: 0 1 auto; flex: 0 1 auto;
//
text-align: right; text-align: right;
&:empty { &:empty {
//
display: none; display: none;
} }
} }
@ -153,50 +214,69 @@ export default {
} }
} }
.mobile .page-header { // mobile page-header
.mobile.page-header {
.main { .main {
.row { .row {
//
flex-wrap: wrap; flex-wrap: wrap;
.avatar { .avatar {
//
flex: 0 1 25%; flex: 0 1 25%;
// 2% 8px
margin: 0 2% 8px 0; margin: 0 2% 8px 0;
} }
.content, .content,
.headerContent { .headerContent {
//
flex: 0 1 70%; flex: 0 1 70%;
.link { .link {
// 16px
margin-top: 16px; margin-top: 16px;
// 24px
line-height: 24px; line-height: 24px;
a { a {
// 14px
font-size: 14px; font-size: 14px;
// 10px
margin-right: 10px; margin-right: 10px;
} }
} }
} }
.extra { .extra {
// 使
flex: 1 1 auto; flex: 1 1 auto;
//
margin-left: 0; margin-left: 0;
// 0
min-width: 0; min-width: 0;
//
text-align: right; text-align: right;
} }
.action { .action {
//
margin-left: unset; margin-left: unset;
// 266px
min-width: 266px; min-width: 266px;
//
flex: 0 1 auto; flex: 0 1 auto;
//
text-align: left; text-align: left;
// 12px
margin-bottom: 12px; margin-bottom: 12px;
&:empty { &:empty {
//
display: none; display: none;
} }
} }
} }
} }
} }
</style> </style>

@ -1,2 +1,5 @@
import PageHeader from './PageHeader' // 从当前目录下的 PageHeader 文件(通常是.js、.vue等相关的模块文件具体取决于项目配置中导入 PageHeader 模块(可能是一个组件、函数或者类等,具体要看 PageHeader 文件中导出的内容是什么)
export default PageHeader import PageHeader from './PageHeader';
// 将导入的 PageHeader 模块原样导出,这样在其他模块中可以通过相应的导入语句引入这个 PageHeader方便复用该模块所代表的功能或组件等内容
export default PageHeader;
Loading…
Cancel
Save