mirror of
https://github.com/XiaoDaiGua-Ray/ray-template.git
synced 2025-05-22 04:39:32 +08:00
细节补充
This commit is contained in:
parent
753b8e898a
commit
80d05792e8
@ -1,20 +0,0 @@
|
||||
@keyframes scaleScreenfull {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.3);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.tay-table-icon__screenfull {
|
||||
transition: transform 0.3s var(--r-bezier);
|
||||
|
||||
&:hover {
|
||||
animation: scaleScreenfull 0.3s linear;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
}
|
@ -61,7 +61,7 @@ const TableSetting = defineComponent({
|
||||
{{
|
||||
trigger: () => (
|
||||
<RayIcon
|
||||
customClassName={`draggable-item__icon ${
|
||||
customClassName={`draggable-item__icon ray-table-icon ${
|
||||
element[key] ? 'draggable-item__icon--actived' : ''
|
||||
}`}
|
||||
name={name}
|
||||
|
@ -1,4 +1,25 @@
|
||||
@keyframes scaleScreenfull {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.3);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.ray-table {
|
||||
& .ray-table-icon {
|
||||
transition: transform 0.3s var(--r-bezier);
|
||||
|
||||
&:hover {
|
||||
animation: scaleScreenfull 0.3s linear;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
}
|
||||
|
||||
& .ray-table__setting,
|
||||
& .ray-table-icon {
|
||||
cursor: pointer;
|
||||
|
@ -227,10 +227,6 @@ const RayTable = defineComponent({
|
||||
registerRayTableMethods(rayTableInstance.value as DataTableInst)
|
||||
})
|
||||
|
||||
// expose({
|
||||
// tableMethods: tableMethods.value,
|
||||
// })
|
||||
|
||||
return {
|
||||
tableUUID,
|
||||
rayTableUUID,
|
||||
|
@ -4,6 +4,8 @@ $menuTagWrapperWidth: 76px;
|
||||
.menu-tag {
|
||||
height: $layoutMenuHeight;
|
||||
border-bottom: solid 1px var(--n-border-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& .menu-tag-sapce {
|
||||
width: calc(100% - $space * 2);
|
||||
|
@ -16,6 +16,9 @@
|
||||
* - 关闭右侧: 关闭右侧所有标签, 如果选中标签页与当前激活页不一致并且激活页在右侧, 则会重定向至当前选中标签页
|
||||
* - 关闭左侧: 关闭左侧所有标签, 如果选中标签页与当前激活页不一致并且激活页在左侧, 则会重定向至当前选中标签页
|
||||
* - 关闭其他: 关闭其他所有标签, 如果选中标签页与当前激活页不一致并且激活页在其中, 则会重定向至当前选中标签页
|
||||
*
|
||||
* root path 标签不可被关闭, 所以不会显示关闭按钮
|
||||
* 页面刷新后, 仅会保留刷新前激活 key 的 tag 标签
|
||||
*/
|
||||
|
||||
import './index.scss'
|
||||
@ -51,7 +54,25 @@ const MenuTag = defineComponent({
|
||||
|
||||
const exclude = ['closeAll', 'closeRight', 'closeLeft', 'closeOther']
|
||||
let currentContentmenuIndex = -1 // 当前右键标签页索引位置
|
||||
const modelMenuTagOptions = computed(() => menuTagOptions.value)
|
||||
const modelMenuTagOptions = computed(() =>
|
||||
menuTagOptions.value.map((curr, _idx, currentArray) => {
|
||||
if (curr.key === menuKey.value && curr.key !== path) {
|
||||
curr.closeable = true
|
||||
} else {
|
||||
curr.closeable = false
|
||||
}
|
||||
|
||||
if (curr.key === path) {
|
||||
curr.closeable = false
|
||||
}
|
||||
|
||||
if (currentArray.length <= 1) {
|
||||
curr.closeable = false
|
||||
}
|
||||
|
||||
return curr
|
||||
}),
|
||||
)
|
||||
const moreOptions = ref([
|
||||
{
|
||||
label: '重新加载',
|
||||
@ -309,6 +330,20 @@ const MenuTag = defineComponent({
|
||||
setDisabledAccordionToIndex()
|
||||
}
|
||||
|
||||
/** 仅有 modelMenuTagOptions 长度大于 1 并且非 root path 时, 才激活关闭按钮 */
|
||||
const menuTagMouseenter = (option: MenuTagOptions) => {
|
||||
if (modelMenuTagOptions.value.length > 1 && option.key !== path) {
|
||||
option.closeable = true
|
||||
}
|
||||
}
|
||||
|
||||
/** 移出 MenuTag 时, 判断是否为当前已激活 key */
|
||||
const menuTagMouseleave = (option: MenuTagOptions) => {
|
||||
if (option.key !== menuKey.value) {
|
||||
option.closeable = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 如果有且只有一个标签页时, 禁止全部关闭操作 */
|
||||
watch(
|
||||
() => modelMenuTagOptions.value,
|
||||
@ -350,6 +385,8 @@ const MenuTag = defineComponent({
|
||||
actionState,
|
||||
handleContextMenu,
|
||||
setCurrentContentmenuIndex,
|
||||
menuTagMouseenter,
|
||||
menuTagMouseleave,
|
||||
}
|
||||
},
|
||||
render() {
|
||||
@ -389,6 +426,10 @@ const MenuTag = defineComponent({
|
||||
{...{
|
||||
id: this.scrollBarUUID,
|
||||
}}
|
||||
themeOverrides={{
|
||||
color: 'rgba(0, 0, 0, 0)',
|
||||
colorHover: 'rgba(0, 0, 0, 0)',
|
||||
}}
|
||||
>
|
||||
<NSpace
|
||||
class="menu-tag-wrapper"
|
||||
@ -398,16 +439,17 @@ const MenuTag = defineComponent({
|
||||
>
|
||||
{this.modelMenuTagOptions.map((curr, idx) => (
|
||||
<NTag
|
||||
closable={
|
||||
curr.key !== this.rootPath &&
|
||||
this.modelMenuTagOptions.length > 1
|
||||
}
|
||||
size="large"
|
||||
strong
|
||||
closable={curr.closeable}
|
||||
onClose={this.closeCurrentMenuTag.bind(this, idx)}
|
||||
type={curr.key === this.menuKey ? 'primary' : 'default'}
|
||||
bordered={false}
|
||||
{...{
|
||||
onClick: this.handleTagClick.bind(this, curr),
|
||||
onContextmenu: this.handleContextMenu.bind(this, idx),
|
||||
onMouseenter: this.menuTagMouseenter.bind(this, curr),
|
||||
onMouseleave: this.menuTagMouseleave.bind(this, curr),
|
||||
}}
|
||||
>
|
||||
{typeof curr.label === 'function'
|
||||
|
@ -19,7 +19,7 @@ import Breadcrumb from './components/Breadcrumb/index'
|
||||
import GlobalSeach from './components/GlobalSeach/index'
|
||||
import AppAvatar from '@/components/AppComponents/AppAvatar/index'
|
||||
|
||||
import { useSetting, useSignin } from '@/store'
|
||||
import { useSetting } from '@/store'
|
||||
import { LOCAL_OPTIONS } from '@/appConfig/localConfig'
|
||||
import { useAvatarOptions, avatarDropdownClick } from './hook'
|
||||
import { getCache } from '@/utils/cache'
|
||||
@ -38,13 +38,11 @@ import type { IconEventMapOptions, IconEventMap } from './type'
|
||||
|
||||
const SiderBar = defineComponent({
|
||||
name: 'SiderBar',
|
||||
setup() {
|
||||
setup(_, { expose }) {
|
||||
const settingStore = useSetting()
|
||||
const signinStore = useSignin()
|
||||
|
||||
const { t } = useI18n()
|
||||
const { updateLocale, changeSwitcher } = settingStore
|
||||
const { logout } = signinStore
|
||||
|
||||
const { drawerPlacement, breadcrumbSwitch } = storeToRefs(settingStore)
|
||||
const showSettings = ref(false)
|
||||
@ -126,6 +124,8 @@ const SiderBar = defineComponent({
|
||||
iconEventMap[key]?.()
|
||||
}
|
||||
|
||||
// expose({})
|
||||
|
||||
return {
|
||||
leftIconOptions,
|
||||
rightTooltipIconOptions,
|
||||
|
@ -5,6 +5,10 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
& .layout__view-container__layout .n-layout-scroll-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
& .layout-content__router-view {
|
||||
height: var(--layout-content-height);
|
||||
padding: calc($layoutRouterViewContainer / 2);
|
||||
|
@ -3,7 +3,10 @@
|
||||
* 页面布局入口文件
|
||||
*
|
||||
* 说明:
|
||||
* - rayLayoutContentWrapperScopeSelector: 页面切换时重置滚动条注入 id
|
||||
* - rayLayoutContentWrapperScopeSelector: 页面切换时重置滚动条注入 id(弃用)
|
||||
*
|
||||
* 该组件入口不做逻辑相关的处理, 仅做功能、组件、方法注入
|
||||
* 提供页面内 Layout 的一些注入(css vars 为主)
|
||||
*/
|
||||
|
||||
import './index.scss'
|
||||
@ -20,36 +23,31 @@ import {
|
||||
viewScrollContainerId,
|
||||
LAYOUT_CONTENT_REF,
|
||||
} from '@/appConfig/routerConfig'
|
||||
import { layoutHeaderCssVars } from '@/layout/layoutResize'
|
||||
|
||||
const Layout = defineComponent({
|
||||
name: 'RLayout',
|
||||
setup() {
|
||||
const layoutSiderBarRef = ref<HTMLElement>()
|
||||
const layoutMenuTagRef = ref<HTMLElement>()
|
||||
|
||||
const settingStore = useSetting()
|
||||
const menuStore = useMenu()
|
||||
|
||||
const { height: windowHeight } = useWindowSize()
|
||||
const { menuTagSwitch: modelMenuTagSwitch } = storeToRefs(settingStore)
|
||||
const { setupAppRoutes } = menuStore
|
||||
const cssVarsRef = computed(() => {
|
||||
let cssVar = {}
|
||||
|
||||
if (settingStore.menuTagSwitch) {
|
||||
cssVar = {
|
||||
'--layout-content-height': 'calc(100% - 111px)',
|
||||
}
|
||||
} else {
|
||||
cssVar = {
|
||||
'--layout-content-height': 'calc(100% - 64px)',
|
||||
}
|
||||
}
|
||||
|
||||
return cssVar
|
||||
})
|
||||
const isLock = useStorage('isLockScreen', false, sessionStorage, {
|
||||
mergeDefaults: true,
|
||||
})
|
||||
const cssVarsRef = layoutHeaderCssVars([
|
||||
layoutSiderBarRef,
|
||||
layoutMenuTagRef,
|
||||
])
|
||||
|
||||
nextTick().then(() => {
|
||||
setupAppRoutes()
|
||||
})
|
||||
|
||||
return {
|
||||
windowHeight,
|
||||
@ -57,6 +55,8 @@ const Layout = defineComponent({
|
||||
cssVarsRef,
|
||||
isLock,
|
||||
LAYOUT_CONTENT_REF,
|
||||
layoutSiderBarRef,
|
||||
layoutMenuTagRef,
|
||||
}
|
||||
},
|
||||
render() {
|
||||
@ -68,9 +68,13 @@ const Layout = defineComponent({
|
||||
{!this.isLock ? (
|
||||
<NLayout class="layout-full" hasSider>
|
||||
<Menu />
|
||||
<NLayout>
|
||||
<SiderBar />
|
||||
{this.modelMenuTagSwitch ? <MenuTag /> : ''}
|
||||
<NLayout class="layout__view-container__layout">
|
||||
<SiderBar ref="layoutSiderBarRef" />
|
||||
{this.modelMenuTagSwitch ? (
|
||||
<MenuTag ref="layoutMenuTagRef" />
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<NLayoutContent
|
||||
ref="LAYOUT_CONTENT_REF"
|
||||
class="layout-content__router-view"
|
||||
|
35
src/layout/layoutResize.ts
Normal file
35
src/layout/layoutResize.ts
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
*
|
||||
* @author Ray <https://github.com/XiaoDaiGua-Ray>
|
||||
*
|
||||
* @date 2023-06-02
|
||||
*
|
||||
* @workspace ray-template
|
||||
*
|
||||
* @remark 今天也是元气满满撸代码的一天
|
||||
*/
|
||||
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
/**
|
||||
*
|
||||
* 动态获取 SiderBar 和 MenuTag 高度, 用于 LayoutConetent 高度实时获取与渲染
|
||||
* 可以动态更改 MenuTag 样式后, 使得 LayoutConetent 也可以准确的获取高度
|
||||
*
|
||||
* 基于 vueuse useElementSize 方法实现
|
||||
* 不建议滥用该方法, 对页面渲染有一定的影响
|
||||
*/
|
||||
export const layoutHeaderCssVars = (
|
||||
element: Ref<HTMLElement | undefined>[],
|
||||
) => {
|
||||
const siderBar = useElementSize(element[0])
|
||||
const menuTag = useElementSize(element[1])
|
||||
|
||||
return computed(() => {
|
||||
return {
|
||||
'--layout-content-height': `calc(100% - ${siderBar.height.value}px - ${menuTag.height.value}px)`,
|
||||
'--layout-siderbar-height': `${siderBar.height.value}px`,
|
||||
'--layout-menutag-height': `${menuTag.height.value}px`,
|
||||
}
|
||||
})
|
||||
}
|
@ -45,10 +45,10 @@ export const useMenu = defineStore(
|
||||
const { t } = useI18n()
|
||||
const { setKeepAliveInclude } = useKeepAlive()
|
||||
|
||||
const { path } = ROOT_ROUTE
|
||||
const { path: rootPath } = ROOT_ROUTE
|
||||
|
||||
const cacheMenuKey =
|
||||
getCache('menuKey') === 'no' ? path : getCache('menuKey')
|
||||
getCache('menuKey') === 'no' ? rootPath : getCache('menuKey')
|
||||
|
||||
const menuState = reactive({
|
||||
menuKey: cacheMenuKey as MenuKey, // 当前菜单 `key`
|
||||
|
4
src/types/store.d.ts
vendored
4
src/types/store.d.ts
vendored
@ -18,7 +18,9 @@ declare global {
|
||||
noLocalTitle?: string | number
|
||||
}
|
||||
|
||||
declare interface MenuTagOptions extends IMenuOptions {}
|
||||
declare interface MenuTagOptions extends IMenuOptions {
|
||||
closeable?: boolean
|
||||
}
|
||||
|
||||
declare type MenuKey = null | string | number
|
||||
}
|
||||
|
@ -109,6 +109,22 @@ export const hasClass = (element: HTMLElement, className: string) => {
|
||||
*
|
||||
* @param el Target element dom
|
||||
* @param styles 所需绑定样式(如果为字符串, 则必须以分号结尾每个行内样式描述)
|
||||
*
|
||||
* style of string
|
||||
* ```
|
||||
* const styles = 'width: 100px; height: 100px; background: red;'
|
||||
*
|
||||
* addStyle(styles)
|
||||
* ```
|
||||
* style of object
|
||||
* ```
|
||||
* const styles = {
|
||||
* width: '100px',
|
||||
* height: '100px',
|
||||
* }
|
||||
*
|
||||
* addStyle(styles)
|
||||
* ```
|
||||
*/
|
||||
export const addStyle = (
|
||||
el: HTMLElement,
|
||||
|
Loading…
x
Reference in New Issue
Block a user