feat: refreshSlotStatus

This commit is contained in:
FairyEver 2021-12-11 13:08:28 +08:00
parent c51130cff9
commit 353d0601e4
7 changed files with 123 additions and 68 deletions

View File

@ -8,91 +8,83 @@
<slot/> <slot/>
</div> </div>
</d2-scroll> </d2-scroll>
<d2-size-sensor class="body__header container__blur" @resize="onHeaderResize"> <d2-size-sensor v-if="headerActive" class="body__header container__blur" @resize="onHeaderResize">
{{ cssVar }}
<slot name="header"/> <slot name="header"/>
</d2-size-sensor> </d2-size-sensor>
<d2-size-sensor class="body__footer container__blur" @resize="onFooterResize"> <d2-size-sensor v-if="footerActive" class="body__footer container__blur" @resize="onFooterResize">
<slot name="footer"/> <slot name="footer"/>
</d2-size-sensor> </d2-size-sensor>
</template> </template>
<script> <script>
import { computed, ref } from 'vue' import { computed, onMounted, onUpdated, ref, unref, watchPostEffect } from 'vue'
import { makeNameByUrl } from 'd2/utils/component.js' import { makeNameByUrl } from 'd2/utils/component.js'
import { px } from 'd2/utils/css.js' import { px, getStyle, convertCssUnit } from 'd2/utils/css.js'
import { useCssVar } from 'd2/use/css-var.js' import { useCssVar } from '@vueuse/core'
export default { export default {
name: makeNameByUrl(import.meta.url), name: makeNameByUrl(import.meta.url),
setup (props, { slots }) { setup (props, { slots }) {
const cssVarHeaderHeight = computed(() => convertCssUnit(useCssVar('--d2-admin-layout-dashboard-header-height')))
const cssVarHeaderBorderWidth = computed(() => convertCssUnit(useCssVar('--d2-admin-layout-dashboard-header-border-width')))
const cssVarBodyMainPaddingY = computed(() => convertCssUnit(useCssVar('--d2-admin-layout-dashboard-body-main-padding-y')))
const scrollbar = ref(null) const scrollbar = ref(null)
const header = ref(null) const bodyHeaderHeight = ref(0)
const footer = ref(null) const bodyFooterHeight = ref(0)
const headerHeight = ref(0) const headerActive = ref(false)
const footerHeight = ref(0) const footerActive = ref(false)
const cssVar = useCssVar('--d2-admin-layout-dashboard-body-padding') const bodyTopBase = computed(() => unref(cssVarHeaderHeight) + unref(cssVarHeaderBorderWidth))
const scrollbarVerticalTop = computed(() => px(unref(bodyTopBase) + unref(bodyHeaderHeight)))
const scrollInnerStyle = computed(() => ({ const scrollInnerStyle = computed(() => ({
paddingTop: px(headerHeight), paddingTop: px(bodyHeaderHeight),
paddingBottom: px(footerHeight) paddingBottom: px(bodyFooterHeight)
})) }))
function onHeaderResize ({ style }) { function onHeaderResize (element) {
const { offsetHeight } = style bodyHeaderHeight.value = element.offsetHeight
headerHeight.value = offsetHeight
} }
function onFooterResize ({ style }) { function onFooterResize (element) {
const { offsetHeight } = style bodyFooterHeight.value = element.offsetHeight
footerHeight.value = offsetHeight
} }
function getScrollbarVertical () { function getScrollbarVertical () {
return scrollbar.value.$el.getElementsByClassName('os-scrollbar-vertical')[0] return scrollbar.value.$el.getElementsByClassName('os-scrollbar-vertical')[0]
} }
function updateScrollbarVerticalMarginTop () { function refreshSlotStatus () {
const scrollbarVertical = getScrollbarVertical() headerActive.value = !!slots.header
scrollbarVertical.style.top = px(value) footerActive.value = !!slots.footer
bodyHeaderHeight.value = 0
bodyFooterHeight.value = 0
} }
function updateScrollbarVerticalMarginBottom () { refreshSlotStatus()
const scrollbarVertical = getScrollbarVertical() onUpdated(() => {
scrollbarVertical.style.bottom = px(value) refreshSlotStatus()
} })
// onMounted(() => { onMounted(() => {
// console.log(slots.default) watchPostEffect(() => {
// console.log(slots.header) getScrollbarVertical().style.top = unref(scrollbarVerticalTop)
// console.log(slots.footer) })
// bind(header.value, element => { watchPostEffect(() => {
// headerHeight.value = element.offsetHeight getScrollbarVertical().style.bottom = px(bodyFooterHeight)
// const scrollbarElement = scrollbar.value.$el })
// const scrollbarVertical = scrollbarElement.getElementsByClassName('os-scrollbar-vertical')[0] })
// const scrollInner = document.getElementsByClassName('main__inner')[0]
// let scrollInnerMarginTop = getStyle(scrollInner, 'marginTop')
// scrollbarVertical.style.top = px(Number(scrollInnerMarginTop.replace('px', '')) + element.offsetHeight)
// })
// bind(footer.value, element => {
// footerHeight.value = element.offsetHeight
// const scrollbarElement = scrollbar.value.$el
// const scrollbarVertical = scrollbarElement.getElementsByClassName('os-scrollbar-vertical')[0]
// scrollbarVertical.style.bottom = px(element.offsetHeight)
// })
// })
return { return {
cssVar,
scrollbar, scrollbar,
header,
footer,
scrollInnerStyle, scrollInnerStyle,
onHeaderResize, onHeaderResize,
onFooterResize onFooterResize,
headerActive,
footerActive
} }
} }
} }

View File

@ -1,7 +1,6 @@
import { defineComponent, getCurrentInstance, onBeforeUnmount, onMounted } from 'vue' import { defineComponent, getCurrentInstance, onBeforeUnmount, onMounted } from 'vue'
import { bind } from 'size-sensor' import { bind } from 'size-sensor'
import { makeName } from 'd2/utils/component.js' import { makeName } from 'd2/utils/component.js'
import { getStyle } from 'd2/utils/css.js'
const name = 'size-sensor' const name = 'size-sensor'
@ -23,11 +22,7 @@ export default defineComponent({
function init () { function init () {
const targetElement = ctx.$el const targetElement = ctx.$el
unbind = bind(targetElement, element => { unbind = bind(targetElement, element => {
const style = getStyle(element) emit('resize', element)
emit('resize', {
element,
style
})
}) })
} }

View File

@ -38,6 +38,16 @@ html, body, #app {
} }
>.body__main { >.body__main {
@apply absolute inset-0; @apply absolute inset-0;
&.body__main--with-header {
>.os-scrollbar-vertical {
padding-top: 0px;
}
}
&.body__main--with-footer {
>.os-scrollbar-vertical {
padding-bottom: 0px;
}
}
>.os-scrollbar-vertical { >.os-scrollbar-vertical {
top: calc(#{--var('header-height')} + #{--var('header-border-width')}); top: calc(#{--var('header-height')} + #{--var('header-border-width')});
} }

View File

@ -1,12 +0,0 @@
import { ref, onMounted } from 'vue'
import { getCssVar } from 'd2/utils/css.js'
export function useCssVar (name = '', defaultValue) {
const cssVarValue = ref(defaultValue)
onMounted(() => {
cssVarValue.value = getCssVar(name)
})
return cssVarValue
}

View File

@ -41,6 +41,7 @@ export function getCssVar (name) {
* @return {*} * @return {*}
*/ */
export function convertCssUnit (cssValue, target) { export function convertCssUnit (cssValue, target) {
cssValue = unref(cssValue)
target = target || document.body target = target || document.body
const units = { const units = {
// Absolute sizes // Absolute sizes

68
package-lock.json generated
View File

@ -5,11 +5,13 @@
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "d2-admin",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@iconify/iconify": "^2.0.3", "@iconify/iconify": "^2.0.3",
"@popperjs/core": "^2.9.3", "@popperjs/core": "^2.9.3",
"@vue/shared": "^3.2.6", "@vue/shared": "^3.2.6",
"@vueuse/core": "^7.2.2",
"ant-design-vue": "^2.2.8", "ant-design-vue": "^2.2.8",
"axios": "^0.21.1", "axios": "^0.21.1",
"classnames": "^2.3.1", "classnames": "^2.3.1",
@ -895,6 +897,53 @@
"integrity": "sha1-U3RpYfcxqOpmbjMWJx6UQjjcMds=", "integrity": "sha1-U3RpYfcxqOpmbjMWJx6UQjjcMds=",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vueuse/core": {
"version": "7.2.2",
"resolved": "https://registry.npmmirror.com/@vueuse/core/download/@vueuse/core-7.2.2.tgz",
"integrity": "sha512-T9oksrPflNhsgG/Y/7IeCSmITPZ0VKDnTpK8y7SQl4ZIdLIL8L7fJyhJEgSMWyo497j/XK3RKFkOTh4GFTVeIQ==",
"dependencies": {
"@vueuse/shared": "7.2.2",
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.1.0",
"vue": "^2.6.0 || ^3.2.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
},
"vue": {
"optional": true
}
}
},
"node_modules/@vueuse/core/node_modules/@vueuse/shared": {
"version": "7.2.2",
"resolved": "https://registry.npmmirror.com/@vueuse/shared/download/@vueuse/shared-7.2.2.tgz",
"integrity": "sha512-9vevEvvQgx4snSrDfZ5BFd7FmlIl9rwTtr8ySzPZhZQslx6lbcsXK3Q97I06Fv8S2TedR//X9fn2QbNtbFmdog==",
"dependencies": {
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.1.0",
"vue": "^2.6.0 || ^3.2.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
},
"vue": {
"optional": true
}
}
},
"node_modules/acorn": { "node_modules/acorn": {
"version": "7.4.1", "version": "7.4.1",
"resolved": "https://registry.nlark.com/acorn/download/acorn-7.4.1.tgz?cache=0&sync_timestamp=1630916517167&other_urls=https%3A%2F%2Fregistry.nlark.com%2Facorn%2Fdownload%2Facorn-7.4.1.tgz", "resolved": "https://registry.nlark.com/acorn/download/acorn-7.4.1.tgz?cache=0&sync_timestamp=1630916517167&other_urls=https%3A%2F%2Fregistry.nlark.com%2Facorn%2Fdownload%2Facorn-7.4.1.tgz",
@ -7074,6 +7123,25 @@
"resolved": "https://registry.npmmirror.com/@vue/shared/download/@vue/shared-3.2.20.tgz?cache=0&sync_timestamp=1633712765807&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40vue%2Fshared%2Fdownload%2F%40vue%2Fshared-3.2.20.tgz", "resolved": "https://registry.npmmirror.com/@vue/shared/download/@vue/shared-3.2.20.tgz?cache=0&sync_timestamp=1633712765807&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40vue%2Fshared%2Fdownload%2F%40vue%2Fshared-3.2.20.tgz",
"integrity": "sha1-U3RpYfcxqOpmbjMWJx6UQjjcMds=" "integrity": "sha1-U3RpYfcxqOpmbjMWJx6UQjjcMds="
}, },
"@vueuse/core": {
"version": "7.2.2",
"resolved": "https://registry.npmmirror.com/@vueuse/core/download/@vueuse/core-7.2.2.tgz",
"integrity": "sha512-T9oksrPflNhsgG/Y/7IeCSmITPZ0VKDnTpK8y7SQl4ZIdLIL8L7fJyhJEgSMWyo497j/XK3RKFkOTh4GFTVeIQ==",
"requires": {
"@vueuse/shared": "7.2.2",
"vue-demi": "*"
},
"dependencies": {
"@vueuse/shared": {
"version": "7.2.2",
"resolved": "https://registry.npmmirror.com/@vueuse/shared/download/@vueuse/shared-7.2.2.tgz",
"integrity": "sha512-9vevEvvQgx4snSrDfZ5BFd7FmlIl9rwTtr8ySzPZhZQslx6lbcsXK3Q97I06Fv8S2TedR//X9fn2QbNtbFmdog==",
"requires": {
"vue-demi": "*"
}
}
}
},
"acorn": { "acorn": {
"version": "7.4.1", "version": "7.4.1",
"resolved": "https://registry.nlark.com/acorn/download/acorn-7.4.1.tgz?cache=0&sync_timestamp=1630916517167&other_urls=https%3A%2F%2Fregistry.nlark.com%2Facorn%2Fdownload%2Facorn-7.4.1.tgz", "resolved": "https://registry.nlark.com/acorn/download/acorn-7.4.1.tgz?cache=0&sync_timestamp=1630916517167&other_urls=https%3A%2F%2Fregistry.nlark.com%2Facorn%2Fdownload%2Facorn-7.4.1.tgz",

View File

@ -10,6 +10,7 @@
"@iconify/iconify": "^2.0.3", "@iconify/iconify": "^2.0.3",
"@popperjs/core": "^2.9.3", "@popperjs/core": "^2.9.3",
"@vue/shared": "^3.2.6", "@vue/shared": "^3.2.6",
"@vueuse/core": "^7.2.2",
"ant-design-vue": "^2.2.8", "ant-design-vue": "^2.2.8",
"axios": "^0.21.1", "axios": "^0.21.1",
"classnames": "^2.3.1", "classnames": "^2.3.1",