提交 9ecb851f 编写于 作者: Anne_LXM's avatar Anne_LXM

新增:web端宽屏适配(4.24版支持custom-tab-bar)

上级 1bd8e8e8
......@@ -83,4 +83,12 @@
<style>
/*每个页面公共css */
@import "./common/uni.css";
/* #ifdef WEB */
.uni-top-window uni-tabbar .uni-tabbar {
background-color: #fff !important;
}
.uni-app--showleftwindow .uni-page-head-btn {
display: none !important;
}
/* #endif */
</style>
......@@ -189,7 +189,7 @@
}
.text-disabled {
color: #a0a0a0;
color: #a0a0a0!important;
}
......@@ -246,6 +246,11 @@
font-weight: normal;
}
/* left-windows */
.left-win-active {
color: #007AFF!important;
}
/* --tab-bar-end-- */
/* #ifdef APP */
......
{
"leftWindow": {
"path": "windows/left-window.uvue",
"style": {
"width": "350px"
}
},
"topWindow": {
"path": "windows/top-window.uvue",
"style": {
"height": "60px"
}
},
"pages": [
{
"path": "pages/tabBar/component",
......
......@@ -3,23 +3,21 @@
<scroll-view style="flex: 1; background-color: #f8f8f8" enable-back-to-top="true">
<!-- #endif -->
<view class="uni-container">
<view class="uni-header-logo">
<view v-if="!hasLeftWin" class="uni-header-logo">
<image class="uni-header-image" src="/static/apiIndex.png"></image>
</view>
<view class="uni-text-box">
<view v-if="!hasLeftWin" class="uni-text-box">
<text class="hello-text">以下将演示uni-app接口能力,详细文档见:</text>
<u-link :href="'https://uniapp.dcloud.io/uni-app-x/api/'" :text="'https://uniapp.dcloud.io/uni-app-x/api/'"
:inWhiteList="true"></u-link>
</view>
<uni-collapse>
<uni-collapse-item v-for="menuItem in menu" :key="menuItem!.id" :title="menuItem.name"
<uni-collapse-item ref="category" v-for="menuItem in menu" :key="menuItem!.id" :title="menuItem.name"
class="item">
<view v-for="page in menuItem.pages" :key="page!.path" class="uni-navigate-item" hover-class="is--active"
@click="goPage(`/${page.path}`)">
<text class="uni-navigate-text">{{
page.style["navigationBarTitleText"]
}}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
<text class="uni-navigate-text" :class="{'left-win-active': leftWinActive === page.path && hasLeftWin}">{{page.style["navigationBarTitleText"]}}</text>
<image :src="arrowRightIcon" class="uni-icon-size" style="color: #898fdd;"></image>
</view>
<uni-collapse style="width: 100%" v-for="childMenu in menuItem.children" :key="childMenu!.id">
<uni-collapse-item :title="childMenu.name" class="item" style="margin-bottom: 0">
......@@ -34,21 +32,22 @@
</uni-collapse>
</uni-collapse-item>
</uni-collapse>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
<view ref="pop" @click="hidePop()" class="popup">
<view v-if="!hasLeftWin" ref="pop" @click="hidePop()" class="popup">
<view style="width: 90%; background-color: white" @click="stopClickPop">
<api-set-tabbar></api-set-tabbar>
</view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script lang="uts">
import { generateMenu } from './generateMenu.uts'
import { MenuItem } from './generateMenu.uts'
const menu = generateMenu('pages/API')
import { state } from '@/store/index.uts'
export default {
data() {
return {
......@@ -56,6 +55,14 @@
arrowRightIcon: '/static/icons/arrow-right.png',
}
},
computed: {
hasLeftWin(){
return !state.noMatchLeftWindow
},
leftWinActive(){
return state.leftWinActive.slice(1)
}
},
methods: {
goPage(url : string) {
if (url == '/set-tab-bar') {
......@@ -74,6 +81,23 @@
e.stopPropagation() //点击到pop的非灰色区域,拦截点击事件
}
},
// #ifdef WEB
watch:{
$route: {
immediate: true,
handler(newRoute) {
if (newRoute.matched.length) {
const activeCategoryIndex = this.menu.findIndex(menuItem => menuItem?.pages.some(page => this.leftWinActive && this.leftWinActive === page?.path))
if (activeCategoryIndex > -1) {
this.$nextTick(() => {
((this.$refs.category as ComponentPublicInstance[])[activeCategoryIndex])?.$callMethod('openCollapse', true)
})
}
}
}
}
},
// #endif
}
</script>
......
......@@ -3,20 +3,20 @@
<scroll-view style="flex: 1; background-color: #f8f8f8" enable-back-to-top="true">
<!-- #endif -->
<view class="uni-container">
<view class="uni-header-logo">
<view v-if="!hasLeftWin" class="uni-header-logo">
<image class="uni-header-image" src="/static/cssIndex.png"></image>
</view>
<view class="uni-text-box">
<view v-if="!hasLeftWin" class="uni-text-box">
<text class="hello-text">uni-app x目前已支持的CSS属性,展示样式仅供参考,文档详见:</text>
<u-link :href="'https://uniapp.dcloud.io/uni-app-x/css/'" :text="'https://uniapp.dcloud.io/uni-app-x/css/'"
:inWhiteList="true"></u-link>
</view>
<uni-collapse>
<uni-collapse-item v-for="menuItem in menu" :key="menuItem!.id" :title="menuItem.name"
<uni-collapse-item ref="category" v-for="menuItem in menu" :key="menuItem!.id" :title="menuItem.name"
class="item">
<view v-for="page in menuItem.pages" :key="page!.path" class="uni-navigate-item" hover-class="is--active"
@click="goPage(`/${page.path}`)">
<text class="uni-navigate-text">{{
<text class="uni-navigate-text" :class="{'left-win-active': leftWinActive === page.path && hasLeftWin}">{{
page.style["navigationBarTitleText"]
}}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
......@@ -44,6 +44,7 @@
import { generateMenu } from './generateMenu.uts'
import { MenuItem } from './generateMenu.uts'
const menu = generateMenu('pages/CSS')
import { state } from '@/store/index.uts'
export default {
data() {
return {
......@@ -51,11 +52,36 @@
arrowRightIcon: '/static/icons/arrow-right.png',
}
},
computed: {
hasLeftWin(){
return !state.noMatchLeftWindow
},
leftWinActive(){
return state.leftWinActive.slice(1)
}
},
methods: {
goPage(url : string) {
uni.navigateTo({ url })
},
},
// #ifdef WEB
watch:{
$route: {
immediate: true,
handler(newRoute) {
if (newRoute.matched.length) {
const activeCategoryIndex = this.menu.findIndex(menuItem => menuItem?.pages.some(page => this.leftWinActive && this.leftWinActive === page?.path))
if (activeCategoryIndex > -1) {
this.$nextTick(() => {
((this.$refs.category as ComponentPublicInstance[])[activeCategoryIndex]).$callMethod('openCollapse', true)
})
}
}
}
}
},
// #endif
}
</script>
......
......@@ -3,20 +3,20 @@
<scroll-view style="flex: 1; background-color: #f8f8f8" enable-back-to-top="true">
<!-- #endif -->
<view class="uni-container">
<view class="uni-header-logo">
<view v-if="!hasLeftWin" class="uni-header-logo">
<image class="uni-header-image" src="/static/componentIndex.png"></image>
</view>
<view class="uni-text-box">
<view v-if="!hasLeftWin" class="uni-text-box">
<text class="hello-text">uni-app内置组件,展示样式仅供参考,文档详见:</text>
<u-link :href="'https://uniapp.dcloud.io/uni-app-x/component/'"
:text="'https://uniapp.dcloud.io/uni-app-x/component/'" :inWhiteList="true"></u-link>
</view>
<uni-collapse>
<uni-collapse-item v-for="menuItem in menu" :key="menuItem!.id" :title="menuItem.name"
<uni-collapse-item ref="category" v-for="menuItem in menu" :key="menuItem!.id" :title="menuItem.name"
class="item">
<view v-for="page in menuItem.pages" :key="page!.path" class="uni-navigate-item" hover-class="is--active"
@click="goPage(`/${page.path}`)">
<text class="uni-navigate-text">{{
<text class="uni-navigate-text" :class="{'left-win-active': leftWinActive === page.path && hasLeftWin}">{{
page.style["navigationBarTitleText"]
}}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
......@@ -25,7 +25,7 @@
<uni-collapse-item :title="childMenu.name" class="item" style="margin-bottom: 0">
<view class="uni-navigate-item" hover-class="is--active" v-for="childPage in childMenu.pages"
:key="childPage!.path" @click="goPage(`/${childPage.path}`)">
<text class="uni-navigate-text">{{
<text class="uni-navigate-text" :class="{'left-win-active': leftWinActive === childPage.path && hasLeftWin}">{{
childPage.style["navigationBarTitleText"]
}}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
......@@ -51,7 +51,7 @@
// #ifdef UNI-APP-X && APP
import checkUpdate from '@/uni_modules/uni-upgrade-center-app/utils/check-update'
// #endif
import { state } from '@/store/index.uts'
export default {
data() {
return {
......@@ -60,6 +60,14 @@
pageHiden: false
}
},
computed: {
hasLeftWin(){
return !state.noMatchLeftWindow
},
leftWinActive(){
return state.leftWinActive.slice(1)
}
},
methods: {
goPage(url : string) {
uni.navigateTo({ url })
......@@ -77,6 +85,23 @@
}
// #endif
},
// #ifdef WEB
watch:{
$route: {
immediate: true,
handler(newRoute) {
if (newRoute.matched.length) {
const activeCategoryIndex = this.menu.findIndex(menuItem => menuItem?.pages.some(page => this.leftWinActive && this.leftWinActive === page?.path))
if (activeCategoryIndex > -1) {
this.$nextTick(() => {
((this.$refs.category as ComponentPublicInstance[])[activeCategoryIndex])?.$callMethod('openCollapse', true)
})
}
}
}
}
},
// #endif
onReady() {
// #ifdef UNI-APP-X && APP
checkUpdate(this.$refs['upgradePopup'] as UniUpgradeCenterAppComponentPublicInstance)
......
import { pages, groups } from '@/pages.json'
import { state } from '@/store/index.uts'
type Group = {
id : string,
name : string,
......@@ -141,7 +141,7 @@ function removeNullItem(arr : (MenuItem | null)[]) : (MenuItem | null)[] {
function addSetTabBarPage(menuItem : MenuItem) {
const { id, name } = menuItem
if (id == 'page' && name == '页面和路由') {
if (id == 'page' && name == '页面和路由' && !state.noMatchLeftWindow) {
menuItem.pages.push({
path: 'set-tab-bar',
style: {
......
......@@ -3,16 +3,16 @@
<scroll-view style="flex: 1; background-color: #f8f8f8" enable-back-to-top="true">
<!-- #endif -->
<view class="uni-container">
<view class="uni-header-logo">
<view v-if="!hasLeftWin" class="uni-header-logo">
<image class="uni-header-image" src="/static/templateIndex.png"></image>
</view>
<view class="uni-text-box">
<view v-if="!hasLeftWin" class="uni-text-box">
<text class="hello-text">以下是部分模板示例,更多模板见插件市场:</text>
<u-link href="https://ext.dcloud.net.cn" :text="'https://ext.dcloud.net.cn'" :inWhiteList="true"></u-link>
</view>
<view class="uni-panel" v-for="(item, index) in list" :key="item.id">
<view class="uni-panel-h" :class="item.open ? 'uni-panel-h-on' : ''" @click="triggerCollapse(index, item)">
<text class="uni-panel-text" :class="item.enable == false ? 'text-disabled' : ''">{{ item.name }}</text>
<view class="uni-panel-h" @click="triggerCollapse(index, item)">
<text class="uni-panel-text" :class="item.enable == false || item.open == true ? 'text-disabled' : '',item.url == leftWinActive && item.pages.length == 0 ? 'left-win-active' : ''">{{ item.name }}</text>
<image :src="
item.pages.length > 0
? item.open
......@@ -25,7 +25,7 @@
<view v-if="item.open">
<view class="uni-navigate-item" :hover-class="page.enable == false ? '' : 'is--active'"
v-for="(page, key) in item.pages" :key="key" @click="goDetailPage(page)">
<text class="uni-navigate-text" :class="page.enable == false ? 'text-disabled' : ''">{{ page.name }}</text>
<text class="uni-navigate-text" :class="{'left-win-active': leftWinActive === page.url && hasLeftWin,'text-disabled' : page.enable == false}">{{ page.name }}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
</view>
</view>
......@@ -51,6 +51,7 @@
url ?: string
enable ?: boolean
}
import { state } from '@/store/index.uts'
export default {
data() {
return {
......@@ -232,6 +233,14 @@
arrowRightIcon: '/static/icons/arrow-right.png',
}
},
computed: {
hasLeftWin(){
return !state.noMatchLeftWindow
},
leftWinActive(){
return state.leftWinActive.split('/')[3]
}
},
methods: {
triggerCollapse(index : number, item : ListItem) {
if (item.pages.length == 0) {
......@@ -268,5 +277,26 @@
})
},
},
// #ifdef WEB
watch: {
$route: {
immediate: true,
handler(newRoute) {
if (newRoute.matched.length) {
let path = newRoute.path.split('/')[3]
for (const item of this.list) {
if (Array.isArray(item.pages)) {
for (const page of item.pages) {
if (page.url && page.url === path) {
item.open = true
}
}
}
}
}
}
}
},
// #endif
}
</script>
......@@ -16,6 +16,11 @@ type State = {
devicePixelRatio : number
// 事件判断回调
eventCallbackNum: number
// 是否匹配左侧窗口
noMatchLeftWindow:boolean
// 当前激活的tab页
active: string
leftWinActive:string
}
export const state = reactive({
......@@ -23,6 +28,9 @@ export const state = reactive({
statusBarHeight: 0,
devicePixelRatio: 1,
eventCallbackNum: 0,
noMatchLeftWindow: true,
active: 'componentPage',
leftWinActive: '/pages/component/public-properties/public-properties',
safeArea: {
top: 0,
right: 0,
......@@ -53,3 +61,15 @@ export const setDevicePixelRatio = (devicePixelRatio : number) => {
state.devicePixelRatio = devicePixelRatio
}
export const setMatchLeftWindow = (matchLeftWindow:boolean) => {
state.noMatchLeftWindow = !matchLeftWindow
}
export const setActive = (tabPage:string) => {
state.active = tabPage
}
export const setLeftWinActive = (leftWinActive:string) => {
state.leftWinActive = leftWinActive
}
<template>
<view class="left-window-style">
<view class="second-menu">
<keep-alive>
<component :is="active" :hasLeftWin="hasLeftWin" :leftWinActive="leftWinActive"></component>
</keep-alive>
</view>
</view>
</template>
<script lang="uts">
import componentPage from '@/pages/tabBar/component.uvue'
import API from '@/pages/tabBar/API.uvue'
import CSS from '@/pages/tabBar/CSS.uvue'
import templatePage from '@/pages/tabBar/template.uvue'
import { state, setMatchLeftWindow, setActive, setLeftWinActive } from '@/store/index.uts'
let isPcObserver, isPhoneObserver
export default {
data() {
return {
nav: [
'component',
'API',
'CSS',
'template'
],
isPC: false
}
},
components: {
componentPage,
API,
CSS,
templatePage
},
computed: {
active(){
return state.active
},
hasLeftWin(){
return !state.noMatchLeftWindow
},
leftWinActive(){
return state.leftWinActive.split('/')[3]
}
},
mounted() {
isPcObserver = uni.createMediaQueryObserver(this)
isPhoneObserver = uni.createMediaQueryObserver(this)
isPcObserver.observe({
minWidth: 768
}, matched => {
this.isPC = matched
const pageUrl = this.$route.path
if (!pageUrl) return
const pageName = this.$route.path.split('/')[4]
if(pageUrl === '/'){
uni.reLaunch({
url: "/pages/component/public-properties/public-properties"
})
}else{
uni.reLaunch({
url: pageUrl
})
}
})
isPhoneObserver.observe({
maxWidth: 767
}, matched => {
this.isPC = !matched
if (matched) {
const pageUrl = this.$route.path
const tabbarName = this.$route.path.split('/')[2]
const tabbarUrl = tabbarName && (tabbarName === 'component' ? '/' : `/pages/tabBar/${tabbarName}`)
uni.switchTab({
url: tabbarUrl,
success(e) {
uni.navigateTo({
url: pageUrl
})
}
})
}
})
},
unmounted() {
isPcObserver.disconnect()
isPhoneObserver.disconnect()
},
watch: {
isPC: {
immediate: true,
handler(newMatches:boolean) {
setMatchLeftWindow(newMatches)
}
},
$route(newRoute) {
this.handlerRoute(newRoute)
}
},
methods: {
handlerRoute(newRoute) {
if (this.isPC) {
if (newRoute.path === '/') {
uni.redirectTo({
url: '/pages/component/public-properties/public-properties'
})
} else if (!newRoute.matched.length) {
uni.redirectTo({
url: '/pages/error/404'
})
} else {
setLeftWinActive(newRoute.path)
let active = newRoute.path.split('/')[2]
if (this.nav.includes(active)) {
if (active === 'component') {
active = 'componentPage'
}
if (active === 'template') {
active = 'templatePage'
}
setActive(active)
}
}
}
}
}
}
</script>
<style>
.left-window-style {
min-height: calc(100vh - var(--top-window-height));
background-color: #f8f8f8;
}
.second-menu {
width: 350px;
background-color: #F8F8F8;
}
</style>
<template>
<view class="top-window-header">
<view class="left-header">
<navigator class="left-header" open-type="reLaunch" url="/pages/component/public-properties/public-properties">
<image src="/static/logo.png" class="logo" mode="heightFix"></image>
<text>hello uni-app</text>
</navigator>
</view>
<custom-tab-bar class="tab-bar-flex" direction="horizontal" :show-icon="false" :selected="current"
@onTabItemTap="toSecondMenu" />
</view>
</template>
<script lang="uts">
type IndexPageItem = {
tabBar: string ;
index: string ;
}
export default {
data() {
return {
selected: {
component: 0,
API: 1,
CSS: 2,
template: 3
},
current: 0,
indexPage: [{
tabBar: '/pages/tabBar/component',
index: '/pages/component/public-properties/public-properties'
}, {
tabBar: '/pages/tabBar/API',
index: '/pages/API/get-app/get-app'
}, {
tabBar: '/pages/tabBar/CSS',
index: '/pages/CSS/layout/width'
}, {
tabBar: '/pages/tabBar/template',
index: '/pages/template/long-list/long-list'
}] as IndexPageItem[]
}
},
watch: {
$route: {
immediate: true,
handler(newRoute) {
const width = uni.getSystemInfoSync().screenWidth
if (width >= 768) {
let path = newRoute.path
let comp
if (path === '/') {
comp = 'component'
path = '/pages/component/public-properties/public-properties'
} else {
comp = path.split('/')[2]
}
this.current = this.selected[comp]
for (const item of this.indexPage) {
if (path === item.tabBar) {
uni.redirectTo({
url: item.index
})
}
}
}
}
}
},
methods: {
toSecondMenu(e) {
const activeTabBar = '/' + e.pagePath
for (const item of this.indexPage) {
if (activeTabBar === item.tabBar) {
uni.redirectTo({
url: item.index
})
}
}
}
}
}
</script>
<style>
.top-window-header {
height: 60px;
padding: 0 15px;
flex-direction: row;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
border-bottom: 1px solid #e1e1e1;
background-color: #FFFFFF;
}
.left-header {
flex-direction: row;
align-items: center;
flex: 1;
}
.logo{
height: 30px;
width: 30px;
margin-right: 8px;
}
.tab-bar-flex {
width: 360px;
}
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册