提交 0838634f 编写于 作者: Q qiang

feat(h5): topWindow, leftWindow, rightWindow

上级 da1d0bd7
......@@ -38,7 +38,7 @@
"node": ">=10.0.0"
},
"devDependencies": {
"@dcloudio/types": "^2.2.5",
"@dcloudio/types": "^2.2.6",
"@microsoft/api-extractor": "^7.13.2",
"@rollup/plugin-alias": "^3.1.1",
"@rollup/plugin-commonjs": "^17.0.0",
......
......@@ -19,6 +19,7 @@ declare namespace UniApp {
minWidth?: number
}
style?: Record<string, any>
component: any
}
interface UniConfig {
......
......@@ -451,6 +451,19 @@ function normalizePageMeta(pageMeta) {
}
return pageMeta;
}
const screen = window.screen;
const documentElement = document.documentElement;
function checkMinWidth(minWidth) {
const sizes = [
window.outerWidth,
window.outerHeight,
screen.width,
screen.height,
documentElement.clientWidth,
documentElement.clientHeight
];
return Math.max.apply(null, sizes) > minWidth;
}
function getStateId() {
{
return 1;
......@@ -4324,7 +4337,7 @@ const props$i = {
default: ""
}
};
function useState$1(props2) {
function useState$2(props2) {
const value = vue.reactive([...props2.value]);
const state = vue.reactive({
value,
......@@ -4352,7 +4365,7 @@ var PickerView = /* @__PURE__ */ defineBuiltInComponent({
}) {
const rootRef = vue.ref(null);
const trigger = useCustomEvent(rootRef, emit2);
const state = useState$1(props2);
const state = useState$2(props2);
const resizeSensorRef = vue.ref(null);
let columnVNodes = [];
function getItemIndex(vnode) {
......@@ -6337,7 +6350,7 @@ function upx2pxStr(val) {
}
return val || "";
}
function useState(props2) {
function useState$1(props2) {
const interval = vue.computed(() => {
const interval2 = Number(props2.interval);
return isNaN(interval2) ? 5e3 : interval2;
......@@ -6660,7 +6673,7 @@ var index$f = /* @__PURE__ */ defineBuiltInComponent({
const trigger = useCustomEvent(rootRef, emit2);
const slidesWrapperRef = vue.ref(null);
const slideFrameRef = vue.ref(null);
const state = useState(props2);
const state = useState$1(props2);
const slidesStyle = vue.computed(() => {
let style = {};
if (props2.nextMargin || props2.previousMargin) {
......@@ -10563,16 +10576,23 @@ var LayoutComponent = /* @__PURE__ */ defineSystemComponent({
setup(_props, {
emit: emit2
}) {
const rootRef = vue.ref(null);
const keepAliveRoute = __UNI_FEATURE_PAGES__ && useKeepAliveRoute();
__UNI_FEATURE_TOPWINDOW__ && useTopWindow();
__UNI_FEATURE_LEFTWINDOW__ && useLeftWindow();
__UNI_FEATURE_RIGHTWINDOW__ && useRightWindow();
const {
layoutState,
windowState
} = useState();
useMaxWidth(layoutState, rootRef);
const topWindow = __UNI_FEATURE_TOPWINDOW__ && useTopWindow(layoutState);
const leftWindow = __UNI_FEATURE_LEFTWINDOW__ && useLeftWindow(layoutState);
const rightWindow = __UNI_FEATURE_RIGHTWINDOW__ && useRightWindow(layoutState);
const showTabBar = __UNI_FEATURE_TABBAR__ && useShowTabBar();
const clazz2 = useAppClass(showTabBar);
return () => {
const layoutTsx = createLayoutTsx(keepAliveRoute);
const layoutTsx = createLayoutTsx(keepAliveRoute, layoutState, windowState, topWindow, leftWindow, rightWindow);
const tabBarTsx = __UNI_FEATURE_TABBAR__ && createTabBarTsx(showTabBar);
return vue.createVNode("uni-app", {
"ref": rootRef,
"class": clazz2.value
}, [layoutTsx, tabBarTsx], 2);
};
......@@ -10587,14 +10607,119 @@ function useAppClass(showTabBar) {
};
});
}
function createLayoutTsx(keepAliveRoute, topWindow, leftWindow, rightWindow) {
function initMediaQuery(minWidth, callback) {
const mediaQueryList = window.matchMedia("(min-width: " + minWidth + "px)");
if (mediaQueryList.addEventListener) {
mediaQueryList.addEventListener("change", callback);
} else {
mediaQueryList.addListener(callback);
}
return mediaQueryList.matches;
}
function useMaxWidth(layoutState, rootRef) {
const route = vueRouter.useRoute();
function checkMaxWidth() {
const windowWidth = document.body.clientWidth;
const maxWidth = parseInt(String(route.meta.maxWidth || 1190));
let showMaxWidth = false;
if (windowWidth > maxWidth) {
showMaxWidth = true;
} else {
showMaxWidth = false;
}
if (showMaxWidth && maxWidth) {
layoutState.marginWidth = (windowWidth - maxWidth) / 2;
vue.nextTick(() => {
const rootEl = rootRef.value;
if (rootEl) {
rootEl.setAttribute("style", "max-width:" + maxWidth + "px;margin:0 auto;");
}
});
} else {
layoutState.marginWidth = 0;
vue.nextTick(() => {
const rootEl = rootRef.value;
if (rootEl) {
rootEl.removeAttribute("style");
}
});
}
}
vue.watch([() => route.path], checkMaxWidth);
window.addEventListener("resize", checkMaxWidth);
}
function useState() {
const topWindowMediaQuery = vue.ref(false);
const leftWindowMediaQuery = vue.ref(false);
const rightWindowMediaQuery = vue.ref(false);
const showTopWindow = vue.computed(() => __UNI_FEATURE_TOPWINDOW__ && topWindowMediaQuery.value);
const showLeftWindow = vue.computed(() => __UNI_FEATURE_LEFTWINDOW__ && leftWindowMediaQuery.value);
const showRightWindow = vue.computed(() => __UNI_FEATURE_RIGHTWINDOW__ && rightWindowMediaQuery.value);
const layoutState = vue.reactive({
topWindowMediaQuery,
showTopWindow,
apiShowTopWindow: false,
leftWindowMediaQuery,
showLeftWindow,
apiShowLeftWindow: false,
rightWindowMediaQuery,
showRightWindow,
apiShowRightWindow: false,
topWindowHeight: 0,
marginWidth: 0,
leftWindowWidth: 0,
rightWindowWidth: 0,
topWindowStyle: {},
leftWindowStyle: {},
rightWindowStyle: {}
});
const props2 = ["topWindow", "leftWindow", "rightWindow"];
props2.forEach((prop) => {
var _a;
const matchMedia = (_a = __uniConfig[prop]) == null ? void 0 : _a.matchMedia;
let topWindowMinWidth = uniShared.RESPONSIVE_MIN_WIDTH;
if (matchMedia && shared.hasOwn(matchMedia, "minWidth")) {
const minWidth = matchMedia.minWidth;
topWindowMinWidth = checkMinWidth(minWidth) ? minWidth : topWindowMinWidth;
}
const matches = initMediaQuery(topWindowMinWidth, (ev) => {
layoutState[`${prop}MediaQuery`] = ev.matches;
});
layoutState[`${prop}MediaQuery`] = matches;
});
vue.watch(() => layoutState.topWindowHeight, (value) => updateCssVar({
"--top-window-height": value + "px"
}));
vue.watch(() => layoutState.marginWidth, (value) => updateCssVar({
"--window-margin": value + "px"
}));
vue.watch(() => layoutState.leftWindowWidth + layoutState.marginWidth, (value) => updateCssVar({
"--window-left": value + "px"
}));
vue.watch(() => layoutState.rightWindowWidth + layoutState.marginWidth, (value) => updateCssVar({
"--window-right": value + "px"
}));
const windowState = vue.reactive({
matchTopWindow: layoutState.topWindowMediaQuery,
showTopWindow: layoutState.showTopWindow || layoutState.apiShowTopWindow,
matchLeftWindow: layoutState.leftWindowMediaQuery,
showLeftWindow: layoutState.showLeftWindow || layoutState.apiShowLeftWindow,
matchRightWindow: layoutState.rightWindowMediaQuery,
showRightWindow: layoutState.showRightWindow || layoutState.apiShowRightWindow
});
return {
layoutState,
windowState
};
}
function createLayoutTsx(keepAliveRoute, layoutState, windowState, topWindow, leftWindow, rightWindow) {
const routerVNode = __UNI_FEATURE_PAGES__ ? createRouterViewVNode(keepAliveRoute) : createPageVNode();
if (!__UNI_FEATURE_RESPONSIVE__) {
return routerVNode;
}
const topWindowTsx = __UNI_FEATURE_TOPWINDOW__ ? createTopWindowTsx() : null;
const leftWindowTsx = __UNI_FEATURE_LEFTWINDOW__ ? createLeftWindowTsx() : null;
const rightWindowTsx = __UNI_FEATURE_RIGHTWINDOW__ ? createRightWindowTsx() : null;
const topWindowTsx = __UNI_FEATURE_TOPWINDOW__ ? createTopWindowTsx(topWindow, layoutState, windowState) : null;
const leftWindowTsx = __UNI_FEATURE_LEFTWINDOW__ ? createLeftWindowTsx(leftWindow, layoutState, windowState) : null;
const rightWindowTsx = __UNI_FEATURE_RIGHTWINDOW__ ? createRightWindowTsx(rightWindow, layoutState, windowState) : null;
return vue.createVNode("uni-layout", null, [topWindowTsx, vue.createVNode("uni-content", null, [vue.createVNode("uni-main", null, [routerVNode]), leftWindowTsx, rightWindowTsx])]);
}
function useShowTabBar(emit2) {
......@@ -10627,36 +10752,119 @@ function createRouterViewVNode({
_: 1
});
}
function useTopWindow() {
const component = vue.resolveComponent("VUniTopWindow");
function useTopWindow(layoutState) {
const {
component,
style
} = __uniConfig.topWindow;
const windowRef = vue.ref(null);
function updateWindow() {
const instalce = windowRef.value;
const el = instalce.$el;
const height = el.getBoundingClientRect().height;
layoutState.topWindowHeight = height;
}
vue.watch(() => layoutState.showTopWindow || layoutState.apiShowTopWindow, () => vue.nextTick(updateWindow));
layoutState.topWindowStyle = style;
return {
component,
style: component.style,
height: 0,
show: false
windowRef
};
}
function useLeftWindow() {
const component = vue.resolveComponent("VUniLeftWindow");
function useLeftWindow(layoutState) {
const {
component,
style
} = __uniConfig.leftWindow;
const windowRef = vue.ref(null);
function updateWindow() {
const instalce = windowRef.value;
const el = instalce.$el;
const width = el.getBoundingClientRect().width;
layoutState.leftWindowWidth = width;
}
vue.watch(() => layoutState.showLeftWindow || layoutState.apiShowLeftWindow, () => vue.nextTick(updateWindow));
layoutState.leftWindowStyle = style;
return {
component,
style: component.style,
height: 0
windowRef
};
}
function useRightWindow() {
const component = vue.resolveComponent("VUniRightWindow");
function useRightWindow(layoutState) {
const {
component,
style
} = __uniConfig.rightWindow;
const windowRef = vue.ref(null);
function updateWindow() {
const instalce = windowRef.value;
const el = instalce.$el;
const width = el.getBoundingClientRect().width;
layoutState.rightWindowWidth = width;
}
vue.watch(() => layoutState.showRightWindow || layoutState.apiShowRightWindow, () => vue.nextTick(updateWindow));
layoutState.rightWindowStyle = style;
return {
component,
style: component.style,
height: 0
windowRef
};
}
function createTopWindowTsx(topWindow) {
}
function createLeftWindowTsx(leftWindow) {
}
function createRightWindowTsx(leftWindow) {
function createTopWindowTsx(topWindow, layoutState, windowState) {
if (topWindow) {
const {
component: TopWindow,
windowRef
} = topWindow;
return vue.withDirectives(vue.createVNode("uni-top-window", null, [vue.createVNode("div", {
"class": "uni-top-window",
"style": layoutState.topWindowStyle
}, [vue.createVNode(TopWindow, vue.mergeProps({
"ref": windowRef
}, windowState), null, 16)], 4), vue.createVNode("div", {
"class": "uni-top-window--placeholder",
"style": {
height: layoutState.topWindowHeight + "px"
}
}, null, 4)], 512), [[vue.vShow, layoutState.showTopWindow || layoutState.apiShowTopWindow]]);
}
}
function createLeftWindowTsx(leftWindow, layoutState, windowState) {
if (leftWindow) {
const {
component: LeftWindow,
windowRef
} = leftWindow;
return vue.withDirectives(vue.createVNode("uni-left-window", {
"data-show": layoutState.apiShowLeftWindow || void 0,
"style": layoutState.leftWindowStyle
}, [vue.withDirectives(vue.createVNode("div", {
"class": "uni-mask",
"onClick": () => layoutState.apiShowLeftWindow = false
}, null, 8, ["onClick"]), [[vue.vShow, layoutState.apiShowLeftWindow]]), vue.createVNode("div", {
"class": "uni-left-window"
}, [vue.createVNode(LeftWindow, vue.mergeProps({
"ref": windowRef
}, windowState), null, 16)])], 12, ["data-show"]), [[vue.vShow, layoutState.showLeftWindow || layoutState.apiShowLeftWindow]]);
}
}
function createRightWindowTsx(rightWindow, layoutState, windowState) {
if (rightWindow) {
const {
component: RightWindow,
windowRef
} = rightWindow;
return vue.withDirectives(vue.createVNode("uni-right-window", {
"data-show": layoutState.apiShowRightWindow || void 0,
"style": layoutState.rightWindowStyle
}, [vue.withDirectives(vue.createVNode("div", {
"class": "uni-mask",
"onClick": () => layoutState.apiShowRightWindow = false
}, null, 8, ["onClick"]), [[vue.vShow, layoutState.apiShowRightWindow]]), vue.createVNode("div", {
"class": "uni-right-window"
}, [vue.createVNode(RightWindow, vue.mergeProps({
"ref": windowRef
}, windowState), null, 16)])], 12, ["data-show"]), [[vue.vShow, layoutState.showRightWindow || layoutState.apiShowRightWindow]]);
}
}
function hexToRgba(hex) {
let r;
......
此差异已折叠。
......@@ -8,9 +8,14 @@ import {
createBlock,
createVNode,
SetupContext,
resolveComponent,
ConcreteComponent,
resolveDynamicComponent,
defineComponent,
reactive,
onMounted,
ComponentPublicInstance,
Ref,
watch,
nextTick,
} from 'vue'
import { RouterView, useRoute } from 'vue-router'
......@@ -19,6 +24,9 @@ import { defineSystemComponent } from '@dcloudio/uni-components'
import { updateCssVar } from '@dcloudio/uni-core'
import { useTabBar } from '../../setup/state'
import { useKeepAliveRoute } from '../../setup/page'
import { RESPONSIVE_MIN_WIDTH } from '@dcloudio/uni-shared'
import { checkMinWidth } from '../../../helpers/dom'
import { hasOwn } from '@vue/shared'
import TabBar from './tabBar'
......@@ -26,28 +34,40 @@ type KeepAliveRoute = ReturnType<typeof useKeepAliveRoute>
const DEFAULT_CSS_VAR_VALUE = '0px'
let globalLayoutState: LayoutState
export function getLayoutState() {
return globalLayoutState
}
export default /*#__PURE__*/ defineSystemComponent({
name: 'Layout',
setup(_props, { emit }) {
const rootRef: Ref<HTMLElement | null> = ref(null)
!__NODE_JS__ && initCssVar()
const keepAliveRoute = (__UNI_FEATURE_PAGES__ &&
useKeepAliveRoute()) as KeepAliveRoute
const topWindow = __UNI_FEATURE_TOPWINDOW__ && useTopWindow()
const leftWindow = __UNI_FEATURE_LEFTWINDOW__ && useLeftWindow()
const rightWindow = __UNI_FEATURE_RIGHTWINDOW__ && useRightWindow()
const { layoutState, windowState } = useState()
useMaxWidth(layoutState, rootRef)
const topWindow = __UNI_FEATURE_TOPWINDOW__ && useTopWindow(layoutState)
const leftWindow = __UNI_FEATURE_LEFTWINDOW__ && useLeftWindow(layoutState)
const rightWindow =
__UNI_FEATURE_RIGHTWINDOW__ && useRightWindow(layoutState)
const showTabBar = (__UNI_FEATURE_TABBAR__ &&
useShowTabBar(emit)) as ComputedRef<boolean>
const clazz = useAppClass(showTabBar)
globalLayoutState = layoutState
return () => {
const layoutTsx = createLayoutTsx(
keepAliveRoute,
layoutState,
windowState,
topWindow,
leftWindow,
rightWindow
)
const tabBarTsx = __UNI_FEATURE_TABBAR__ && createTabBarTsx(showTabBar)
return (
<uni-app class={clazz.value}>
<uni-app ref={rootRef} class={clazz.value}>
{layoutTsx}
{tabBarTsx}
</uni-app>
......@@ -76,9 +96,173 @@ function initCssVar() {
'--tab-bar-height': DEFAULT_CSS_VAR_VALUE,
})
}
interface LayoutState {
topWindowMediaQuery: boolean
showTopWindow: boolean
apiShowTopWindow: boolean
leftWindowMediaQuery: boolean
showLeftWindow: boolean
apiShowLeftWindow: boolean
rightWindowMediaQuery: boolean
showRightWindow: boolean
apiShowRightWindow: boolean
topWindowHeight: number
marginWidth: number
leftWindowWidth: number
rightWindowWidth: number
topWindowStyle: unknown
leftWindowStyle: unknown
rightWindowStyle: unknown
}
interface WindowState {
matchTopWindow?: boolean
showTopWindow?: boolean
matchLeftWindow?: boolean
showLeftWindow?: boolean
matchRightWindow?: boolean
showRightWindow?: boolean
}
function initMediaQuery(
minWidth: number,
callback: (ev: MediaQueryListEvent) => void
) {
const mediaQueryList = window.matchMedia('(min-width: ' + minWidth + 'px)')
if (mediaQueryList.addEventListener) {
mediaQueryList.addEventListener('change', callback)
} else {
mediaQueryList.addListener(callback)
}
return mediaQueryList.matches
}
function useMaxWidth(
layoutState: LayoutState,
rootRef: Ref<HTMLElement | null>
) {
const route = useRoute()
function checkMaxWidth() {
const windowWidth = document.body.clientWidth
const maxWidth = parseInt(String(route.meta.maxWidth || 1190))
let showMaxWidth = false
if (windowWidth > maxWidth) {
showMaxWidth = true
} else {
showMaxWidth = false
}
if (showMaxWidth && maxWidth) {
layoutState.marginWidth = (windowWidth - maxWidth) / 2
nextTick(() => {
const rootEl = rootRef.value
if (rootEl) {
rootEl.setAttribute(
'style',
'max-width:' + maxWidth + 'px;margin:0 auto;'
)
}
})
} else {
layoutState.marginWidth = 0
nextTick(() => {
const rootEl = rootRef.value
if (rootEl) {
rootEl.removeAttribute('style')
}
})
}
}
watch([() => route.path], checkMaxWidth)
onMounted(checkMaxWidth)
window.addEventListener('resize', checkMaxWidth)
}
function useState() {
const topWindowMediaQuery = ref(false)
const leftWindowMediaQuery = ref(false)
const rightWindowMediaQuery = ref(false)
const showTopWindow = computed(
() => __UNI_FEATURE_TOPWINDOW__ && topWindowMediaQuery.value
)
const showLeftWindow = computed(
() => __UNI_FEATURE_LEFTWINDOW__ && leftWindowMediaQuery.value
)
const showRightWindow = computed(
() => __UNI_FEATURE_RIGHTWINDOW__ && rightWindowMediaQuery.value
)
const layoutState: LayoutState = reactive({
topWindowMediaQuery,
showTopWindow,
apiShowTopWindow: false,
leftWindowMediaQuery,
showLeftWindow,
apiShowLeftWindow: false,
rightWindowMediaQuery,
showRightWindow,
apiShowRightWindow: false,
topWindowHeight: 0,
marginWidth: 0,
leftWindowWidth: 0,
rightWindowWidth: 0,
topWindowStyle: {},
leftWindowStyle: {},
rightWindowStyle: {},
})
const props: Array<'topWindow' | 'leftWindow' | 'rightWindow'> = [
'topWindow',
'leftWindow',
'rightWindow',
]
type StateProps =
| 'topWindowMediaQuery'
| 'leftWindowMediaQuery'
| 'rightWindowMediaQuery'
props.forEach((prop) => {
const matchMedia = __uniConfig[prop]?.matchMedia
let topWindowMinWidth = RESPONSIVE_MIN_WIDTH
if (matchMedia && hasOwn(matchMedia, 'minWidth')) {
const minWidth = matchMedia.minWidth!
topWindowMinWidth = checkMinWidth(minWidth) ? minWidth : topWindowMinWidth
}
const matches = initMediaQuery(topWindowMinWidth, (ev) => {
layoutState[`${prop}MediaQuery` as StateProps] = ev.matches
})
layoutState[`${prop}MediaQuery` as StateProps] = matches
})
watch(
() => layoutState.topWindowHeight,
(value) => updateCssVar({ '--top-window-height': value + 'px' })
)
watch(
() => layoutState.marginWidth,
(value) => updateCssVar({ '--window-margin': value + 'px' })
)
watch(
() => layoutState.leftWindowWidth + layoutState.marginWidth,
(value) => updateCssVar({ '--window-left': value + 'px' })
)
watch(
() => layoutState.rightWindowWidth + layoutState.marginWidth,
(value) => updateCssVar({ '--window-right': value + 'px' })
)
const windowState: WindowState = reactive({
matchTopWindow: layoutState.topWindowMediaQuery,
showTopWindow: layoutState.showTopWindow || layoutState.apiShowTopWindow,
matchLeftWindow: layoutState.leftWindowMediaQuery,
showLeftWindow: layoutState.showLeftWindow || layoutState.apiShowLeftWindow,
matchRightWindow: layoutState.rightWindowMediaQuery,
showRightWindow:
layoutState.showRightWindow || layoutState.apiShowRightWindow,
})
return {
layoutState,
windowState,
}
}
function createLayoutTsx(
keepAliveRoute: KeepAliveRoute,
layoutState: LayoutState,
windowState: WindowState,
topWindow?: unknown,
leftWindow?: unknown,
rightWindow?: unknown
......@@ -91,13 +275,13 @@ function createLayoutTsx(
return routerVNode
}
const topWindowTsx = __UNI_FEATURE_TOPWINDOW__
? createTopWindowTsx(topWindow)
? createTopWindowTsx(topWindow, layoutState, windowState)
: null
const leftWindowTsx = __UNI_FEATURE_LEFTWINDOW__
? createLeftWindowTsx(leftWindow)
? createLeftWindowTsx(leftWindow, layoutState, windowState)
: null
const rightWindowTsx = __UNI_FEATURE_RIGHTWINDOW__
? createRightWindowTsx(rightWindow)
? createRightWindowTsx(rightWindow, layoutState, windowState)
: null
return (
<uni-layout>
......@@ -157,32 +341,143 @@ function createRouterViewVNode({
})
}
function useTopWindow() {
const component = resolveComponent('VUniTopWindow') as ConcreteComponent
interface WindowComponentInfo {
component: ReturnType<typeof defineComponent>
windowRef: Ref<ComponentPublicInstance | null>
}
function useTopWindow(layoutState: LayoutState): WindowComponentInfo {
const { component, style } = __uniConfig.topWindow!
const windowRef: Ref<ComponentPublicInstance | null> = ref(null)
function updateWindow() {
const instalce = windowRef.value as ComponentPublicInstance
const el: HTMLElement = instalce.$el
const height = el.getBoundingClientRect().height
layoutState.topWindowHeight = height
}
onMounted(updateWindow)
watch(
() => layoutState.showTopWindow || layoutState.apiShowTopWindow,
() => nextTick(updateWindow)
)
layoutState.topWindowStyle = style
return {
component,
style: (component as any).style,
height: 0,
show: false,
windowRef,
}
}
function useLeftWindow() {
const component = resolveComponent('VUniLeftWindow') as ConcreteComponent
function useLeftWindow(layoutState: LayoutState): WindowComponentInfo {
const { component, style } = __uniConfig.leftWindow!
const windowRef: Ref<ComponentPublicInstance | null> = ref(null)
function updateWindow() {
const instalce = windowRef.value as ComponentPublicInstance
const el: HTMLElement = instalce.$el
const width = el.getBoundingClientRect().width
layoutState.leftWindowWidth = width
}
onMounted(updateWindow)
watch(
() => layoutState.showLeftWindow || layoutState.apiShowLeftWindow,
() => nextTick(updateWindow)
)
layoutState.leftWindowStyle = style
return {
component,
style: (component as any).style,
height: 0,
windowRef,
}
}
function useRightWindow() {
const component = resolveComponent('VUniRightWindow') as ConcreteComponent
function useRightWindow(layoutState: LayoutState): WindowComponentInfo {
const { component, style } = __uniConfig.rightWindow!
const windowRef: Ref<ComponentPublicInstance | null> = ref(null)
function updateWindow() {
const instalce = windowRef.value as ComponentPublicInstance
const el: HTMLElement = instalce.$el
const width = el.getBoundingClientRect().width
layoutState.rightWindowWidth = width
}
onMounted(updateWindow)
watch(
() => layoutState.showRightWindow || layoutState.apiShowRightWindow,
() => nextTick(updateWindow)
)
layoutState.rightWindowStyle = style
return {
component,
style: (component as any).style,
height: 0,
windowRef,
}
}
function createTopWindowTsx(topWindow: unknown) {}
function createLeftWindowTsx(leftWindow: unknown) {}
function createRightWindowTsx(leftWindow: unknown) {}
function createTopWindowTsx(
topWindow: unknown,
layoutState: LayoutState,
windowState: WindowState
) {
if (topWindow) {
const { component: TopWindow, windowRef } = topWindow as WindowComponentInfo
return (
<uni-top-window
v-show={layoutState.showTopWindow || layoutState.apiShowTopWindow}
>
<div class="uni-top-window" style={layoutState.topWindowStyle as any}>
<TopWindow ref={windowRef} {...windowState} />
</div>
<div
class="uni-top-window--placeholder"
style={{ height: layoutState.topWindowHeight + 'px' }}
/>
</uni-top-window>
)
}
}
function createLeftWindowTsx(
leftWindow: unknown,
layoutState: LayoutState,
windowState: WindowState
) {
if (leftWindow) {
const { component: LeftWindow, windowRef } =
leftWindow as WindowComponentInfo
return (
<uni-left-window
v-show={layoutState.showLeftWindow || layoutState.apiShowLeftWindow}
data-show={layoutState.apiShowLeftWindow || undefined}
style={layoutState.leftWindowStyle as any}
>
<div
v-show={layoutState.apiShowLeftWindow}
class="uni-mask"
onClick={() => (layoutState.apiShowLeftWindow = false)}
/>
<div class="uni-left-window">
<LeftWindow ref={windowRef} {...windowState} />
</div>
</uni-left-window>
)
}
}
function createRightWindowTsx(
rightWindow: unknown,
layoutState: LayoutState,
windowState: WindowState
) {
if (rightWindow) {
const { component: RightWindow, windowRef } =
rightWindow as WindowComponentInfo
return (
<uni-right-window
v-show={layoutState.showRightWindow || layoutState.apiShowRightWindow}
data-show={layoutState.apiShowRightWindow || undefined}
style={layoutState.rightWindowStyle as any}
>
<div
v-show={layoutState.apiShowRightWindow}
class="uni-mask"
onClick={() => (layoutState.apiShowRightWindow = false)}
/>
<div class="uni-right-window">
<RightWindow ref={windowRef} {...windowState} />
</div>
</uni-right-window>
)
}
}
import { nextTick } from 'vue'
import {
API_ON_WINDOW_RESIZE,
API_TYPE_ON_WINDOW_RESIZE,
......@@ -5,7 +6,10 @@ import {
API_TYPE_OFF_WINDOW_RESIZE,
defineOnApi,
defineOffApi,
defineAsyncApi,
defineSyncApi,
} from '@dcloudio/uni-api'
import { getLayoutState } from '../../../framework/components/layout'
var tasks: number[] = []
......@@ -57,3 +61,117 @@ export const offWindowResize = defineOffApi<API_TYPE_OFF_WINDOW_RESIZE>(
window.removeEventListener('resize', onResize)
}
)
export const showTopWindow = <typeof uni.showTopWindow>(
defineAsyncApi('showTopWindow', (_, { resolve, reject }) => {
const state = getLayoutState()
if (!state) {
reject()
return
}
state.apiShowTopWindow = true
nextTick(resolve)
})
)
export const hideTopWindow = <typeof uni.hideTopWindow>(
defineAsyncApi('hideTopWindow', (_, { resolve, reject }) => {
const state = getLayoutState()
if (!state) {
reject()
return
}
state.apiShowTopWindow = false
nextTick(resolve)
})
)
export const showLeftWindow = <typeof uni.showLeftWindow>(
defineAsyncApi('showLeftWindow', (_, { resolve, reject }) => {
const state = getLayoutState()
if (!state) {
reject()
return
}
state.apiShowLeftWindow = true
nextTick(resolve)
})
)
export const hideLeftWindow = <typeof uni.hideLeftWindow>(
defineAsyncApi('hideLeftWindow', (_, { resolve, reject }) => {
const state = getLayoutState()
if (!state) {
reject()
return
}
state.apiShowLeftWindow = false
nextTick(resolve)
})
)
export const showRightWindow = <typeof uni.showRightWindow>(
defineAsyncApi('showRightWindow', (_, { resolve, reject }) => {
const state = getLayoutState()
if (!state) {
reject()
return
}
state.apiShowRightWindow = true
nextTick(resolve)
})
)
export const hideRightWindow = <typeof uni.hideRightWindow>(
defineAsyncApi('hideRightWindow', (_, { resolve, reject }) => {
const state = getLayoutState()
if (!state) {
reject()
return
}
state.apiShowRightWindow = false
nextTick(resolve)
})
)
export const getTopWindowStyle = <typeof uni.getTopWindowStyle>(
defineSyncApi('getTopWindowStyle', () => {
const state = getLayoutState()
return Object.assign({}, state.topWindowStyle)
})
)
export const setTopWindowStyle = <typeof uni.setTopWindowStyle>(
defineSyncApi('setTopWindowStyle', (style) => {
const state = getLayoutState()
state.topWindowStyle = style
})
)
export const getLeftWindowStyle = <typeof uni.getLeftWindowStyle>(
defineSyncApi('getLeftWindowStyle', () => {
const state = getLayoutState()
return Object.assign({}, state.leftWindowStyle)
})
)
export const setLeftWindowStyle = <typeof uni.setLeftWindowStyle>(
defineSyncApi('setLeftWindowStyle', (style) => {
const state = getLayoutState()
state.leftWindowStyle = style
})
)
export const getRightWindowStyle = <typeof uni.getRightWindowStyle>(
defineSyncApi('getRightWindowStyle', () => {
const state = getLayoutState()
return Object.assign({}, state.rightWindowStyle)
})
)
export const setRightWindowStyle = <typeof uni.setRightWindowStyle>(
defineSyncApi('setRightWindowStyle', (style) => {
const state = getLayoutState()
state.rightWindowStyle = style
})
)
......@@ -7,5 +7,6 @@ declare module 'vue-router' {
topWindow?: boolean
leftWindow?: boolean
rightWindow?: boolean
maxWidth?: string | number
}
}
......@@ -65,6 +65,8 @@ function generatePagesJsonCode(
options.inputDir,
options.platform
)
const { importLayoutComponentsCode, defineLayoutComponentsCode } =
generateLayoutComponentsCode(globalName, pagesJson)
const definePagesCode = generatePagesDefineCode(pagesJson, config)
const uniRoutesCode = generateRoutes(globalName, pagesJson, config, options)
const uniConfigCode = generateConfig(globalName, pagesJson, options)
......@@ -77,9 +79,11 @@ function generatePagesJsonCode(
import { defineAsyncComponent, resolveComponent, createVNode, withCtx, openBlock, createBlock } from 'vue'
import { PageComponent, AsyncLoadingComponent, AsyncErrorComponent } from '@dcloudio/uni-h5'
import { appid, debug, networkTimeout, router, async, sdkConfigs, qqMapKey, nvue } from '${manifestJsonPath}'
${importLayoutComponentsCode}
const extend = Object.assign
${cssCode}
${uniConfigCode}
${defineLayoutComponentsCode}
${definePagesCode}
${uniRoutesCode}
${options.command === 'serve' ? hmrCode : ''}
......@@ -160,6 +164,31 @@ function generateCssCode(
return cssFiles.map((file) => `import '${file}'`).join('\n')
}
function generateLayoutComponentsCode(
globalName: string,
pagesJson: UniApp.PagesJson
) {
const windowNames: Array<'topWindow' | 'leftWindow' | 'rightWindow'> = [
'topWindow',
'leftWindow',
'rightWindow',
]
let importLayoutComponentsCode = ''
let defineLayoutComponentsCode = `${globalName}.__uniLayout = ${globalName}.__uniLayout || {}\n`
windowNames.forEach((name) => {
const windowConfig = pagesJson[name]
if (windowConfig && windowConfig.path) {
importLayoutComponentsCode += `import ${name} from './${windowConfig.path}'\n`
defineLayoutComponentsCode += `${globalName}.__uniConfig.${name}.component = ${name}\n`
}
})
return {
importLayoutComponentsCode,
defineLayoutComponentsCode,
}
}
function generatePageDefineCode(pageOptions: UniApp.PagesJsonPageOptions) {
const pageIdent = normalizePageIdentifier(pageOptions.path)
return `const ${pageIdent}Loader = ()=>import('./${pageOptions.path}?mpType=page')
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册