提交 2f1cf321 编写于 作者: fxy060608's avatar fxy060608

chore: sync h5 components

上级 39f24354
......@@ -23,12 +23,17 @@ declare var __VUE_OPTIONS_API__: boolean
declare var __UNI_FEATURE_WX__: boolean
declare var __UNI_FEATURE_WXS__: boolean
declare var __UNI_FEATURE_PROMISE__: boolean
declare var __UNI_FEATURE_LONGPRESS__: boolean
declare var __UNI_FEATURE_ROUTER_MODE__: 'hash' | 'history'
declare var __UNI_FEATURE_PAGES__: boolean
declare var __UNI_FEATURE_TABBAR__: boolean
declare var __UNI_FEATURE_TOPWINDOW__: boolean
declare var __UNI_FEATURE_LEFTWINDOW__: boolean
declare var __UNI_FEATURE_RIGHTWINDOW__: boolean
declare var __UNI_FEATURE_RESPONSIVE__: boolean
// TODO
declare var __uniRoutes: any
declare var __uniConfig: any
declare var __uniConfig: UniApp.UniConfig
declare var UniViewJSBridge: any
declare var UniServiceJSBridge: any
declare namespace UniApp {
interface LayoutWindowOptions {
matchMedia?: {
minWidth?: number
}
style?: Record<string, any>
}
interface UniConfig {
router: {
strict: boolean
}
topWindow?: LayoutWindowOptions
leftWindow?: LayoutWindowOptions
rightWindow?: LayoutWindowOptions
}
interface PagesJsonPageOptions {
path: string
style?: Record<string, any>
}
interface PagesJsonSubpackagesOptions {
root: string
pages: PagesJsonPageOptions[]
}
interface PagesJson {
pages: PagesJsonPageOptions[]
subpackages?: PagesJsonSubpackagesOptions[]
subPackages?: PagesJsonSubpackagesOptions[]
globalStyle?: {}
tabBar?: {
list: []
}
}
}
export function getRealRoute(fromRoute: string, toRoute: string): string {
if (!toRoute) {
toRoute = fromRoute
if (toRoute.indexOf('/') === 0) {
return toRoute
}
const pages = getCurrentPages()
if (pages.length) {
fromRoute = (pages[pages.length - 1] as any).$page.route
} else {
fromRoute = ''
}
} else {
if (toRoute.indexOf('/') === 0) {
return toRoute
}
}
if (toRoute.indexOf('./') === 0) {
return getRealRoute(fromRoute, toRoute.substr(2))
}
const toRouteArray = toRoute.split('/')
const toRouteLength = toRouteArray.length
let i = 0
for (; i < toRouteLength && toRouteArray[i] === '..'; i++) {
// noop
}
toRouteArray.splice(0, i)
toRoute = toRouteArray.join('/')
const fromRouteArray = fromRoute.length > 0 ? fromRoute.split('/') : []
fromRouteArray.splice(fromRouteArray.length - i - 1, i + 1)
return '/' + fromRouteArray.concat(toRouteArray).join('/')
}
export * from './util'
export * from './getRealRoute'
export function PolySymbol(name: string) {
return Symbol(__DEV__ ? '[uni-app]: ' + name : name)
}
export * from './view'
export * from './service'
export * from './helpers'
......@@ -4,7 +4,9 @@ import { initLongPress } from './longPress'
import { initAppConfig } from './appConfig'
export function initView(app: App) {
initLongPress()
if (__UNI_FEATURE_LONGPRESS__) {
initLongPress()
}
initAppConfig(app._context.config)
// TODO wxs,behaviors
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
import TabBar from './tabBar.vue'
import Components from './popup'
export default {
TabBar,
...Components
}
<template>
<uni-tabbar
v-if="hasTabBar"
v-show="showTabBar"
>
<div
:style="{'flex-direction':direction==='vertical'?'column':'row',backgroundColor:tabBarOptions.backgroundColor}"
class="uni-tabbar"
>
<div
v-for="(item,index) in tabBarOptions.list"
:key="item.pagePath"
class="uni-tabbar__item"
@click="_switchTab(item,index)"
>
<div class="uni-tabbar__bd">
<div
v-if="showIcon && item.iconPath"
:class="{'uni-tabbar__icon__diff':!item.text}"
class="uni-tabbar__icon"
>
<img :src="_getRealPath(selectedIndex===index?item.selectedIconPath:item.iconPath)">
<div
v-if="item.redDot"
:class="{'uni-tabbar__badge':!!item.badge}"
class="uni-tabbar__reddot"
>
{{ item.badge }}
</div>
</div>
<div
v-if="item.text"
:style="{color:selectedIndex===index?tabBarOptions.selectedColor:tabBarOptions.color,fontSize:showIcon&&item.iconPath?'10px':'14px'}"
class="uni-tabbar__label"
>
{{ item.text }}
<div
v-if="item.redDot&&(!showIcon || !item.iconPath)"
:class="{'uni-tabbar__badge':!!item.badge}"
class="uni-tabbar__reddot"
>
{{ item.badge }}
</div>
</div>
</div>
</div>
</div>
</uni-tabbar>
</template>
<script>
import getRealPath from 'uni-platform/helpers/get-real-path'
import {
tabBar
} from './observable'
export default {
name: 'CustomTabBar',
props: {
selected: {
type: Number,
default: 0
},
showIcon: {
type: Boolean,
default: true
},
direction: {
type: String,
default: 'horizontal'
}
},
data () {
return {
selectedIndex: this.selected
}
},
computed: {
tabBarOptions () {
return tabBar
},
hasTabBar () {
return tabBar.list && tabBar.list.length
},
showTabBar () {
const app = getApp()
if (app) {
return !app.$children[0].hideTabBar
}
return true
}
},
watch: {
selected (val) {
this.selectedIndex = val
// 同步至内置tabBar
const tabBar = getApp().$children[0].$refs.tabBar
if (tabBar) {
tabBar.selectedIndex = val
}
},
'$route' (to, from) {
if (to.meta.isTabBar) {
const index = tabBar.list.findIndex(item => to.meta.pagePath === item.pagePath)
if (index > -1) {
this.selectedIndex = index
}
}
}
},
methods: {
_getRealPath (filePath) {
const SCHEME_RE = /^([a-z-]+:)?\/\//i
const DATA_RE = /^data:.*,.*/
if (!(SCHEME_RE.test(filePath) || DATA_RE.test(filePath)) && filePath.indexOf('/') !== 0) {
filePath = '/' + filePath
}
return getRealPath(filePath)
},
_switchTab ({
text,
pagePath
}, index) {
this.selectedIndex = index
let url = '/' + pagePath
if (url === __uniRoutes[0].alias) {
url = '/'
}
const detail = {
index,
text,
pagePath
}
this.$emit('onTabItemTap', detail)
if (this.$route.path === url) {
UniServiceJSBridge.emit('onTabItemTap', detail)
}
}
}
}
</script>
<style>
</style>
* {
margin: 0;
-webkit-tap-highlight-color: transparent;
}
@font-face {
font-weight: normal;
font-style: normal;
font-family: "uni";
src: url('data:application/octet-stream;base64,AAEAAAALAIAAAwAwR1NVQrD+s+0AAAE4AAAAQk9TLzJAKEx+AAABfAAAAFZjbWFw65cFHQAAAhwAAAJQZ2x5ZvCRR/EAAASUAAAKtGhlYWQLKIN9AAAA4AAAADZoaGVhCCwD+gAAALwAAAAkaG10eEJo//8AAAHUAAAASGxvY2EYqhW6AAAEbAAAACZtYXhwASEAVQAAARgAAAAgbmFtZeNcHtgAAA9IAAAB5nBvc3T6bLhLAAARMAAAAOYAAQAAA+gAAABaA+j/////A+kAAQAAAAAAAAAAAAAAAAAAABIAAQAAAAEAACkCj3dfDzz1AAsD6AAAAADUER9XAAAAANQRH1f//wAAA+kD6gAAAAgAAgAAAAAAAAABAAAAEgBJAAUAAAAAAAIAAAAKAAoAAAD/AAAAAAAAAAEAAAAKAB4ALAABREZMVAAIAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAAAAQOwAZAABQAIAnoCvAAAAIwCegK8AAAB4AAxAQIAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA6gHqEQPoAAAAWgPqAAAAAAABAAAAAAAAAAAAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+j//wPoAAAD6AAAAAAABQAAAAMAAAAsAAAABAAAAXQAAQAAAAAAbgADAAEAAAAsAAMACgAAAXQABABCAAAABAAEAAEAAOoR//8AAOoB//8AAAABAAQAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAAAEGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAANwAAAAAAAAAEQAA6gEAAOoBAAAAAQAA6gIAAOoCAAAAAgAA6gMAAOoDAAAAAwAA6gQAAOoEAAAABAAA6gUAAOoFAAAABQAA6gYAAOoGAAAABgAA6gcAAOoHAAAABwAA6ggAAOoIAAAACAAA6gkAAOoJAAAACQAA6goAAOoKAAAACgAA6gsAAOoLAAAACwAA6gwAAOoMAAAADAAA6g0AAOoNAAAADQAA6g4AAOoOAAAADgAA6g8AAOoPAAAADwAA6hAAAOoQAAAAEAAA6hEAAOoRAAAAEQAAAAAARgCMANIBJgF4AcQCMgJgAqgC/ANIA6YD/gROBKAE9AVaAAAAAgAAAAADrwOtABQAKQAAASIHBgcGFBcWFxYyNzY3NjQnJicmAyInJicmNDc2NzYyFxYXFhQHBgcGAfV4Z2Q7PDw7ZGfwZmQ7PDw7ZGZ4bl5bNjc3Nlte215bNjc3NlteA608O2Rn8GdjOzw8O2Nn8GdkOzz8rzc1W17bXlw1Nzc1XF7bXls1NwAAAAACAAAAAAOzA7MAFwAtAAABIgcGBwYVFBcWFxYzMjc2NzY1NCcmJyYTBwYiLwEmNjsBETQ2OwEyFhURMzIWAe52Z2Q7PT07ZGd2fGpmOz4+O2ZpIXYOKA52Dg0XXQsHJgcLXRcNA7M+O2ZqfHZnZDs9PTtkZ3Z9aWY7Pv3wmhISmhIaARcICwsI/ukaAAMAAAAAA+UD5QAXACMALAAAASIHBgcGFRQXFhcWMzI3Njc2NTQnJicmAxQrASI1AzQ7ATIHJyImNDYyFhQGAe6Ecm9BRERBb3KEiXZxQkREQnF1aQIxAwgCQgMBIxIZGSQZGQPkREJxdomEcm9BRERBb3KEinVxQkT9HQICAWICAjEZIxkZIxkAAAAAAwAAAAADsQPkABsAKgAzAAABBgcGBwYHBjcRFBcWFxYXNjc2NzY1ESQXJicmBzMyFhUDFAYrASInAzQ2EyImNDYyFhQGAfVBQTg7LDt/IEc+bF5sbF1tPUj+2KhQQVVvNAQGDAMCJgUBCwYeDxYWHhUVA+QPEg4SDhIpCv6tj3VkST4dHT5JZHWPAVNeNRkSGPwGBP7GAgMFAToEBv5AFR8VFR8VAAAAAgAAAAADsQPkABkALgAAAQYHBgc2BREUFxYXFhc2NzY3NjURJBcmJyYTAQYvASY/ATYyHwEWNjclNjIfARYB9VVVQk+v/tFHPmxebGxdbT1I/tGvT0JVo/7VBASKAwMSAQUBcQEFAgESAgUBEQQD4xMYEhk3YP6sjnVlSD8cHD9IZXWOAVRgNxkSGP62/tkDA48EBBkCAVYCAQHlAQIQBAAAAAACAAAAAAPkA+QAFwAtAAABIgcGBwYVFBcWFxYzMjc2NzY1NCcmJyYTAQYiLwEmPwE2Mh8BFjI3ATYyHwEWAe6Ecm9BQ0NCbnODiXVxQkREQnF1kf6gAQUBowMDFgEFAYUCBQEBQwIFARUEA+NEQnF1iYNzbkJDQ0FvcoSJdXFCRP6j/qUBAagEBR4CAWYBAQENAgIVBAAAAAQAAAAAA68DrQAUACkAPwBDAAABIgcGBwYUFxYXFjI3Njc2NCcmJyYDIicmJyY0NzY3NjIXFhcWFAcGBwYTBQ4BLwEmBg8BBhYfARYyNwE+ASYiFzAfAQH1eGdkOzw8O2Rn8GZkOzw8O2RmeG5eWzY3NzZbXtteWzY3NzZbXmn+9gYSBmAGDwUDBQEGfQUQBgElBQELEBUBAQOtPDtkZ/BnYzs8PDtjZ/BnZDs8/K83NVte215cNTc3NVxe215bNTcCJt0FAQVJBQIGBAcRBoAGBQEhBQ8LBAEBAAABAAAAAAO7AzoAFwAAEy4BPwE+AR8BFjY3ATYWFycWFAcBBiInPQoGBwUHGgzLDCELAh0LHwsNCgr9uQoeCgGzCyEOCw0HCZMJAQoBvgkCCg0LHQv9sQsKAAAAAAIAAAAAA+UD5gAXACwAAAEiBwYHBhUUFxYXFjMyNzY3NjU0JyYnJhMHBi8BJicmNRM0NjsBMhYVExceAQHvhHJvQUNDQm5zg4l1cUJEREJxdVcQAwT6AwIEEAMCKwIDDsUCAQPlREJxdYmDc25CQ0NBb3KEiXVxQkT9VhwEAncCAgMGAXoCAwMC/q2FAgQAAAQAAAAAA68DrQADABgALQAzAAABMB8BAyIHBgcGFBcWFxYyNzY3NjQnJicmAyInJicmNDc2NzYyFxYXFhQHBgcGAyMVMzUjAuUBAfJ4Z2Q7PDw7ZGfwZmQ7PDw7ZGZ4bl5bNjc3Nlte215bNjc3NltemyT92QKDAQEBLDw7ZGfwZ2M7PDw7Y2fwZ2Q7PPyvNzVbXtteXDU3NzVcXtteWzU3AjH9JAAAAAMAAAAAA+QD5AAXACcAMAAAASIHBgcGFRQXFhcWMzI3Njc2NTQnJicmAzMyFhUDFAYrASImNQM0NhMiJjQ2MhYUBgHuhHJvQUNDQm5zg4l1cUJEREJxdZ42BAYMAwInAwMMBh8PFhYeFhYD40RCcXWJg3NuQkNDQW9yhIl1cUJE/vYGBf7AAgMDAgFABQb+NhYfFhYfFgAABAAAAAADwAPAAAgAEgAoAD0AAAEyNjQmIgYUFhcjFTMRIxUzNSMDIgcGBwYVFBYXFjMyNzY3NjU0Jy4BAyInJicmNDc2NzYyFxYXFhQHBgcGAfQYISEwISFRjzk5yTorhG5rPT99am+DdmhlPD4+PMyFbV5bNTc3NVte2l5bNTc3NVteAqAiLyIiLyI5Hf7EHBwCsT89a26Ed8w8Pj48ZWh2g29qffyjNzVbXtpeWzU3NzVbXtpeWzU3AAADAAAAAAOoA6gACwAgADUAAAEHJwcXBxc3FzcnNwMiBwYHBhQXFhcWMjc2NzY0JyYnJgMiJyYnJjQ3Njc2MhcWFxYUBwYHBgKOmpocmpocmpocmpq2dmZiOjs7OmJm7GZiOjs7OmJmdmtdWTQ2NjRZXdZdWTQ2NjRZXQKqmpocmpocmpocmpoBGTs6YmbsZmI6Ozs6YmbsZmI6O/zCNjRZXdZdWTQ2NjRZXdZdWTQ2AAMAAAAAA+kD6gAaAC8AMAAAAQYHBiMiJyYnJjQ3Njc2MhcWFxYVFAcGBwEHATI3Njc2NCcmJyYiBwYHBhQXFhcWMwKONUBCR21dWjU3NzVaXdpdWzU2GBcrASM5/eBXS0grKysrSEuuSkkqLCwqSUpXASMrFxg2NVtd2l1aNTc3NVpdbUdCQDX+3jkBGSsrSEuuSkkqLCwqSUquS0grKwAC//8AAAPoA+gAFAAwAAABIgcGBwYQFxYXFiA3Njc2ECcmJyYTFg4BIi8BBwYuATQ/AScmPgEWHwE3Nh4BBg8BAfSIdHFDRERDcXQBEHRxQ0REQ3F0SQoBFBsKoqgKGxMKqKIKARQbCqKoChsUAQqoA+hEQ3F0/vB0cUNERENxdAEQdHFDRP1jChsTCqiiCgEUGwqiqAobFAEKqKIKARQbCqIAAAIAAAAAA+QD5AAXADQAAAEiBwYHBhUUFxYXFjMyNzY3NjU0JyYnJhMUBiMFFxYUDwEGLwEuAT8BNh8BFhQPAQUyFh0BAe6Ecm9BQ0NCbnODiXVxQkREQnF1fwQC/pGDAQEVAwTsAgEC7AQEFAIBhAFwAgMD40RCcXWJg3NuQkNDQW9yhIl1cUJE/fYCAwuVAgQCFAQE0AIFAtEEBBQCBQGVCwMDJwAAAAUAAAAAA9QD0wAjACcANwBHAEgAAAERFAYjISImNREjIiY9ATQ2MyE1NDYzITIWHQEhMhYdARQGIyERIREHIgYVERQWOwEyNjURNCYjISIGFREUFjsBMjY1ETQmKwEDeyYb/XYbJkMJDQ0JAQYZEgEvExkBBgkNDQn9CQJc0QkNDQktCQ0NCf7sCQ0NCS0JDQ0JLQMi/TQbJiYbAswMCiwJDS4SGRkSLg0JLAoM/UwCtGsNCf5NCQ0NCQGzCQ0NCf5NCQ0NCQGzCQ0AAAAAEADGAAEAAAAAAAEABAAAAAEAAAAAAAIABwAEAAEAAAAAAAMABAALAAEAAAAAAAQABAAPAAEAAAAAAAUACwATAAEAAAAAAAYABAAeAAEAAAAAAAoAKwAiAAEAAAAAAAsAEwBNAAMAAQQJAAEACABgAAMAAQQJAAIADgBoAAMAAQQJAAMACAB2AAMAAQQJAAQACAB+AAMAAQQJAAUAFgCGAAMAAQQJAAYACACcAAMAAQQJAAoAVgCkAAMAAQQJAAsAJgD6d2V1aVJlZ3VsYXJ3ZXVpd2V1aVZlcnNpb24gMS4wd2V1aUdlbmVyYXRlZCBieSBzdmcydHRmIGZyb20gRm9udGVsbG8gcHJvamVjdC5odHRwOi8vZm9udGVsbG8uY29tAHcAZQB1AGkAUgBlAGcAdQBsAGEAcgB3AGUAdQBpAHcAZQB1AGkAVgBlAHIAcwBpAG8AbgAgADEALgAwAHcAZQB1AGkARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABzAHYAZwAyAHQAdABmACAAZgByAG8AbQAgAEYAbwBuAHQAZQBsAGwAbwAgAHAAcgBvAGoAZQBjAHQALgBoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAAAAAgAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETAAZjaXJjbGUIZG93bmxvYWQEaW5mbwxzYWZlX3N1Y2Nlc3MJc2FmZV93YXJuB3N1Y2Nlc3MOc3VjY2Vzcy1jaXJjbGURc3VjY2Vzcy1uby1jaXJjbGUHd2FpdGluZw53YWl0aW5nLWNpcmNsZQR3YXJuC2luZm8tY2lyY2xlBmNhbmNlbAZzZWFyY2gFY2xlYXIEYmFjawZkZWxldGUAAAAA') format('truetype');
}
@font-face {
font-weight: normal;
font-style: normal;
font-family: "unibtn";
src: url('data:application/octet-stream;base64,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') format('truetype')
}
html,
body {
-webkit-user-select: none;
user-select: none;
width: 100%;
height: 100%;
}
/* html {
height: 100%
} */
body {
overflow-x: hidden;
}
[class^="uni-icon-"],
[class*=" uni-icon-"] {
display: inline-block;
vertical-align: middle;
font: normal normal normal 14px/1 "uni";
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
}
[class^="uni-btn-icon"],
[class*=" uni-btn-icon"] {
display: inline-block;
font: normal normal normal 14px/1 "unibtn";
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
}
[class^="uni-btn-icon"]:before,
[class*=" uni-btn-icon"]:before {
margin: 0;
box-sizing: border-box;
}
.uni-icon-success-no-circle:before {
content: "\EA08";
}
.uni-loading,
uni-button[loading]:before {
background: transparent url("data:image/svg+xml;base64, PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=") no-repeat;
}
.uni-loading {
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
animation: uni-loading 1s steps(12, end) infinite;
background-size: 100%;
}
@keyframes uni-loading {
0% {
transform: rotate3d(0, 0, 1, 0deg);
}
100% {
transform: rotate3d(0, 0, 1, 360deg);
}
}
/*
html,
body,
uni-app,
uni-page {
height: 100%;
} */
.uni-mask {
position: fixed;
z-index: 999;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
}
.uni-fade-enter-active,
.uni-fade-leave-active {
transition-duration: 0.25s;
transition-property: opacity;
transition-timing-function: ease;
}
.uni-fade-enter,
.uni-fade-leave-active {
opacity: 0
}
[nvue] uni-view,
[nvue] uni-swiper-item,
[nvue] uni-scroll-view {
display: flex;
flex-shrink: 0;
flex-grow: 0;
flex-basis: auto;
align-items: stretch;
align-content: flex-start;
}
[nvue-dir-row] uni-view,
[nvue-dir-row] uni-swiper-item {
flex-direction: row;
}
[nvue-dir-column] uni-view,
[nvue-dir-column] uni-swiper-item {
flex-direction: column;
}
[nvue-dir-row-reverse] uni-view,
[nvue-dir-row-reverse] uni-swiper-item {
flex-direction: row-reverse;
}
[nvue-dir-column-reverse] uni-view,
[nvue-dir-column-reverse] uni-swiper-item {
flex-direction: column-reverse;
}
[nvue] uni-view,
[nvue] uni-image,
[nvue] uni-input,
[nvue] uni-scroll-view,
[nvue] uni-swiper,
[nvue] uni-swiper-item,
[nvue] uni-text,
[nvue] uni-textarea,
[nvue] uni-video {
position: relative;
border: 0px solid #000000;
box-sizing: border-box;
}
[nvue] uni-swiper-item {
position: absolute;
}
import {
ref,
onMounted,
computed,
openBlock,
createBlock,
createVNode,
defineComponent,
} from 'vue'
import Layout from './layout'
import { updateCssVar } from '../../../helpers/dom'
const CSS_VARS = [
'--status-bar-height',
'--top-window-height',
'--window-left',
'--window-right',
'--window-margin',
]
export default defineComponent({
name: 'App',
setup() {
useCssVar()
useAppLifecycle()
const { appClass, onLayoutChange } = useAppClass()
return () => (
openBlock(),
createBlock(
'uni-app',
{
class: appClass.value,
},
[
createVNode(
Layout,
{
onChange: onLayoutChange,
},
null,
8 /* PROPS */,
['onChange']
),
],
2 /* CLASS */
)
)
},
})
function useCssVar() {
CSS_VARS.forEach((name) => updateCssVar(name, '0px'))
}
function useAppLifecycle() {
onMounted(() => {
document.addEventListener('visibilitychange', function () {
if (document.visibilityState === 'visible') {
UniServiceJSBridge.emit('onAppEnterForeground')
} else {
UniServiceJSBridge.emit('onAppEnterBackground')
}
})
})
}
function useAppClass() {
const showTabBar = ref(false)
const showMaxWidth = ref(false)
function onLayoutChange(type: string, value: boolean) {
if (type === 'showTabBar') {
showTabBar.value = value
} else if (type === 'showMaxWidth') {
showMaxWidth.value = value
}
}
const appClass = computed(() => {
return {
'uni-app--showtabbar': showTabBar.value,
'uni-app--maxwidth': showMaxWidth.value,
}
})
return {
appClass,
onLayoutChange,
}
}
<template>
<uni-app :class="{ 'uni-app--showtabbar': showTabBar }">
<!-- <transition :name="transitionName"> -->
<!-- TODO -->
<router-view v-slot="{ Component }">
<keep-alive :cache="routeCache">
<component :is="Component" :key="routeKey" />
</keep-alive>
</router-view>
<!-- </transition> -->
<tab-bar v-if="hasTabBar" v-show="showTabBar" v-bind="tabBar" />
</uni-app>
</template>
<script>
import { isPlainObject } from '@vue/shared'
import { TABBAR_HEIGHT } from '@dcloudio/uni-shared'
import components from './components'
import mixins from './popup/mixins'
import { canIUse } from '../../../service/api'
import { useKeepAliveRoute } from '../../plugin/page'
export default {
name: 'App',
components,
mixins,
data() {
return {
transitionName: 'fade',
hideTabBar: false,
tabBar: __uniConfig.tabBar || {},
sysComponents: this.$sysComponents,
}
},
computed: {
key() {
return this.$route.path + '-' + (history.state.__id__ || 0)
},
hasTabBar() {
return (
__uniConfig.tabBar &&
__uniConfig.tabBar.list &&
__uniConfig.tabBar.list.length
)
},
showTabBar() {
return this.$route.meta.isTabBar && !this.hideTabBar
},
},
watch: {
$route(newRoute, oldRoute) {
UniServiceJSBridge.emit('onHidePopup')
},
hideTabBar(newVal, oldVal) {
// TODO 不支持 css 变量时
if (canIUse('css.var')) {
const windowBottomValue = !newVal ? TABBAR_HEIGHT : 0
const envMethod = canIUse('css.env')
? 'env'
: canIUse('css.constant')
? 'constant'
: ''
const windowBottom =
windowBottomValue && envMethod
? `calc(${windowBottomValue}px + ${envMethod}(safe-area-inset-bottom))`
: `${windowBottomValue}px`
document.documentElement.style.setProperty(
'--window-bottom',
windowBottom
)
console.debug(
`uni.${
windowBottom ? 'showTabBar' : 'hideTabBar'
}:--window-bottom=${windowBottom}`
)
}
// 触发 resize 事件
window.dispatchEvent(new CustomEvent('resize'))
},
},
setup() {
const { routeKey, routeCache } = useKeepAliveRoute()
return {
routeKey,
routeCache,
}
},
created() {
if (canIUse('css.var')) {
document.documentElement.style.setProperty('--status-bar-height', '0px')
}
},
mounted() {
window.addEventListener('message', function (evt) {
if (
isPlainObject(evt.data) &&
evt.data.type === 'WEB_INVOKE_APPSERVICE'
) {
UniServiceJSBridge.emit(
'onWebInvokeAppService',
evt.data.data,
evt.data.pageId
)
}
})
document.addEventListener('visibilitychange', function () {
if (document.visibilityState === 'visible') {
UniServiceJSBridge.emit('onAppEnterForeground')
} else {
UniServiceJSBridge.emit('onAppEnterBackground')
}
})
},
}
</script>
import {
vShow,
withCtx,
Fragment,
KeepAlive,
openBlock,
mergeProps,
createBlock,
createVNode,
withDirectives,
defineComponent,
resolveComponent,
ConcreteComponent,
createCommentVNode,
resolveDynamicComponent,
} from 'vue'
import { RouteLocationNormalizedLoaded, RouterView, useRoute } from 'vue-router'
import TabBar from '../tabBar'
import { useKeepAliveRoute } from '../../../plugin/page'
type KeepAliveRoute = ReturnType<typeof useKeepAliveRoute>
export default defineComponent({
name: 'Layout',
emits: ['change'],
setup() {
const route = __UNI_FEATURE_TABBAR__ ? useRoute() : null
const keepAliveRoute = __UNI_FEATURE_PAGES__ ? useKeepAliveRoute() : null
const topWindow = __UNI_FEATURE_TOPWINDOW__ ? useTopWindow() : null
const leftWindow = __UNI_FEATURE_LEFTWINDOW__ ? useLeftWindow() : null
const rightWindow = __UNI_FEATURE_RIGHTWINDOW__ ? useRightWindow() : null
return () => {
return (
openBlock(),
createBlock(
Fragment,
null,
[
createLayoutVNode(
keepAliveRoute,
topWindow,
leftWindow,
rightWindow
),
createTabBarVNode(route),
],
64 /* STABLE_FRAGMENT */
)
)
}
},
})
function createLayoutVNode(
keepAliveRoute: KeepAliveRoute | null,
topWindow: unknown,
leftWindow: unknown,
rightWindow: unknown
) {
const routerVNode = __UNI_FEATURE_PAGES__
? createRouterViewVNode(keepAliveRoute!)
: createPageVNode()
// 非响应式
if (!__UNI_FEATURE_RESPONSIVE__) {
return routerVNode
}
const topWindowVNode = __UNI_FEATURE_TOPWINDOW__
? createTopWindowVNode(topWindow)
: createCommentVNode('', true)
const leftWindowVNode = __UNI_FEATURE_LEFTWINDOW__
? createLeftWindowVNode(leftWindow)
: createCommentVNode('', true)
const rightWindowVNode = __UNI_FEATURE_RIGHTWINDOW__
? createRightWindowVNode(rightWindow)
: createCommentVNode('', true)
return createVNode('uni-layout', null, [
topWindowVNode,
createVNode('uni-content', null, [
createVNode('uni-main', null, [routerVNode]),
leftWindowVNode,
rightWindowVNode,
]),
])
}
function createTabBarVNode(route: RouteLocationNormalizedLoaded | null) {
return __UNI_FEATURE_TABBAR__
? withDirectives(createVNode(TabBar, null, null, 512 /* NEED_PATCH */), [
[vShow, route!.meta.isTabBar], // TODO mediaQuery and api
])
: createCommentVNode('', true)
}
function createPageVNode() {
return createVNode(__uniRoutes[1].component)
}
function createRouterViewVNode(
keepAliveRoute: ReturnType<typeof useKeepAliveRoute>
) {
return createVNode(RouterView, null, {
default: withCtx(({ Component }) => [
(openBlock(),
createBlock(
KeepAlive,
{ cache: keepAliveRoute.routeCache },
[
(openBlock(),
createBlock(resolveDynamicComponent(Component), {
key: keepAliveRoute.routeKey.value,
})),
],
1032 /* PROPS, DYNAMIC_SLOTS */,
['cache']
)),
]),
_: 1 /* STABLE */,
})
}
function useTopWindow() {
const component = resolveComponent('VUniTopWindow') as ConcreteComponent
return {
component,
style: (component as any).style,
height: 0,
show: false,
}
}
function useLeftWindow() {
const component = resolveComponent('VUniLeftWindow') as ConcreteComponent
return {
component,
style: (component as any).style,
height: 0,
}
}
function useRightWindow() {
const component = resolveComponent('VUniRightWindow') as ConcreteComponent
return {
component,
style: (component as any).style,
height: 0,
}
}
function createTopWindowVNode(topWindow: unknown) {
if (!__UNI_FEATURE_TOPWINDOW__) {
return createCommentVNode('', true)
}
const { component, style, height, show } = useTopWindow()
return withDirectives(
createVNode(
'uni-top-window',
null,
[
createVNode(
'div',
{
ref: 'topWindow',
class: 'uni-top-window',
style,
},
[
createVNode(
component,
mergeProps(
{
onVnodeMounted(vnode) {
// update style.offsetHeight
},
'navigation-bar-title-text': '',
}
//bindWindow
),
null,
16 /* FULL_PROPS */,
['navigation-bar-title-text']
),
],
4 /* STYLE */
),
createVNode(
'div',
{
class: 'uni-top-window--placeholder',
style: { height },
},
null,
4 /* STYLE */
),
],
512 /* NEED_PATCH */
),
[[vShow, show]]
)
}
function createLeftWindowVNode(leftWindow: unknown) {}
function createRightWindowVNode(leftWindow: unknown) {}
import Vue from 'vue'
__uniConfig.tabBar = Vue.observable(__uniConfig.tabBar || {})
export const tabBar = __uniConfig.tabBar
<template>
<uni-actionsheet @touchmove.prevent.passive>
<uni-actionsheet @touchmove.prevent>
<transition name="uni-fade">
<div
v-show="visible"
class="uni-mask"
@click="_close(-1)"
<div
v-show="visible"
class="uni-mask uni-actionsheet__mask"
@click="_close(-1)"
/>
</transition>
<div
:class="{'uni-actionsheet_toggle':visible}"
class="uni-actionsheet"
<div
:class="{ 'uni-actionsheet_toggle': visible }"
:style="popupStyle.content"
class="uni-actionsheet"
>
<div class="uni-actionsheet__menu">
<div
v-if="title"
class="uni-actionsheet__title"
<div
ref="main"
class="uni-actionsheet__menu"
@wheel="_handleWheel"
>
<!-- title占位 -->
<div
v-if="title"
class="uni-actionsheet__cell"
:style="{height:`${titleHeight}px`}"
/>
<div
v-if="title"
class="uni-actionsheet__title"
>
{{ title }}
</div>
<div
v-for="(itemTitle,index) in itemList"
:key="index"
:style="{color:itemColor}"
class="uni-actionsheet__cell"
@click="_close(index)"
>
{{ itemTitle }}
<div :style="{maxHeight:`${HEIGHT}px`,overflow:'hidden'}">
<div ref="content">
<div
v-for="(itemTitle, index) in itemList"
:key="index"
:style="{ color: itemColor }"
class="uni-actionsheet__cell"
@click="_close(index)"
>
{{ itemTitle }}
</div>
</div>
</div>
</div>
<div class="uni-actionsheet__action">
<div
:style="{color:itemColor}"
class="uni-actionsheet__cell"
@click="_close(-1)"
<div
:style="{ color: itemColor }"
class="uni-actionsheet__cell"
@click="_close(-1)"
>
取消
{{ $$t('uni.showActionSheet.cancel') }}
</div>
</div>
<div :style="popupStyle.triangle" />
</div>
<keypress
:disable="!visible"
@esc="_close(-1)"
/>
</uni-actionsheet>
</template>
<script>
import popup from './mixins/popup'
import keypress from '../../../helpers/keypress'
import {
i18nMixin
} from 'uni-core/helpers/i18n'
import touchtrack from 'uni-mixins/touchtrack'
import scroller from 'uni-mixins/scroller/index'
import {
Friction
} from 'uni-mixins/scroller/Friction'
import {
Spring
} from 'uni-mixins/scroller/Spring'
import {
initScrollBounce,
disableScrollBounce
} from 'uni-platform/helpers/scroll'
// 由于模拟滚动阻止了点击,使用自定义事件来触发点击事件
function initClick (dom) {
const MAX_MOVE = 20
let x = 0
let y = 0
dom.addEventListener('touchstart', (event) => {
const info = event.changedTouches[0]
x = info.clientX
y = info.clientY
})
dom.addEventListener('touchend', (event) => {
const info = event.changedTouches[0]
if (Math.abs(info.clientX - x) < MAX_MOVE && Math.abs(info.clientY - y) < MAX_MOVE) {
const customEvent = new CustomEvent('click', {
bubbles: true,
cancelable: true,
target: event.target,
currentTarget: event.currentTarget
});
['screenX', 'screenY', 'clientX', 'clientY', 'pageX', 'pageY'].forEach(key => {
customEvent[key] = info[key]
})
event.target.dispatchEvent(customEvent)
}
})
}
export default {
name: 'ActionSheet',
components: {
keypress
},
mixins: [i18nMixin, popup, touchtrack, scroller],
props: {
title: {
type: String,
......@@ -58,80 +127,209 @@ export default {
type: String,
default: '#000000'
},
popover: {
type: Object,
default: null
},
visible: {
type: Boolean,
default: false
}
},
data () {
return {
HEIGHT: 260,
contentHeight: 0,
titleHeight: 0,
deltaY: 0,
scrollTop: 0
}
},
watch: {
visible (newValue) {
if (newValue) {
this.$nextTick(() => {
// title 占位
if (this.title) {
this.titleHeight = document.querySelector('.uni-actionsheet__title').offsetHeight
}
// 滚动条更新
this._scroller.update()
// 获取contentHeight 滚动时使用
this.contentHeight = this.$refs.content.clientHeight - this.HEIGHT
// 给每一个项添加点击事件
document.querySelectorAll('.uni-actionsheet__cell').forEach(item => {
initClick(item)
})
})
}
}
},
mounted () {
// 模拟滚动使用
this.touchtrack(this.$refs.content, '_handleTrack', true)
this.$nextTick(() => {
this.initScroller(this.$refs.content, {
enableY: true,
friction: new Friction(0.0001),
spring: new Spring(2, 90, 20),
onScroll: (e) => {
this.scrollTop = e.target.scrollTop
}
})
})
initScrollBounce()
},
methods: {
_close (tapIndex) {
this.$emit('close', tapIndex)
},
_handleTrack: function (e) {
if (this._scroller) {
switch (e.detail.state) {
case 'start':
this._handleTouchStart(e)
disableScrollBounce({
disable: true
})
break
case 'move':
this._handleTouchMove(e)
break
case 'end':
case 'cancel':
this._handleTouchEnd(e)
disableScrollBounce({
disable: false
})
}
}
},
_handleWheel ($event) {
const deltaY = this.deltaY + $event.deltaY
if (Math.abs(deltaY) > 10) {
this.scrollTop += deltaY / 3
this.scrollTop = this.scrollTop >= this.contentHeight
? this.contentHeight
: this.scrollTop <= 0
? 0
: this.scrollTop
this._scroller.scrollTo(this.scrollTop)
} else {
this.deltaY = deltaY
}
$event.preventDefault()
}
}
}
</script>
<style>
uni-actionsheet {
display: block;
box-sizing: border-box;
}
uni-actionsheet .uni-actionsheet {
position: fixed;
left: 0;
bottom: 0;
transform: translate(0, 100%);
backface-visibility: hidden;
z-index: 999;
width: 100%;
background-color: #efeff4;
uni-actionsheet {
display: block;
box-sizing: border-box;
}
uni-actionsheet .uni-actionsheet {
position: fixed;
left: 6px;
right: 6px;
bottom: 6px;
transform: translate(0, 100%);
backface-visibility: hidden;
z-index: 999;
visibility: hidden;
transition: transform 0.3s, visibility 0.3s;
}
transition: transform 0.3s, visibility 0.3s;
}
uni-actionsheet .uni-actionsheet.uni-actionsheet_toggle {
uni-actionsheet .uni-actionsheet.uni-actionsheet_toggle {
visibility: visible;
transform: translate(0, 0);
}
uni-actionsheet .uni-actionsheet * {
box-sizing: border-box;
}
uni-actionsheet .uni-actionsheet__menu {
background-color: #fcfcfd;
}
uni-actionsheet .uni-actionsheet__action {
margin-top: 6px;
background-color: #fcfcfd;
}
uni-actionsheet .uni-actionsheet__cell ,
uni-actionsheet .uni-actionsheet__title {
position: relative;
padding: 10px 0;
text-align: center;
font-size: 18px;
}
uni-actionsheet .uni-actionsheet__cell:before {
content: " ";
position: absolute;
left: 0;
top: 0;
right: 0;
height: 1px;
border-top: 1px solid #e5e5e5;
color: #e5e5e5;
transform-origin: 0 0;
transform: scaleY(0.5);
}
uni-actionsheet .uni-actionsheet__cell:active {
background-color: #ececec;
}
uni-actionsheet .uni-actionsheet__cell:first-child:before {
display: none;
}
</style>
transform: translate(0, 0);
}
uni-actionsheet .uni-actionsheet * {
box-sizing: border-box;
}
uni-actionsheet .uni-actionsheet__menu,
uni-actionsheet .uni-actionsheet__action {
border-radius: 5px;
background-color: #fcfcfd;
}
uni-actionsheet .uni-actionsheet__action {
margin-top: 6px;
}
uni-actionsheet .uni-actionsheet__cell,
uni-actionsheet .uni-actionsheet__title {
position: relative;
padding: 10px 6px;
text-align: center;
font-size: 18px;
text-overflow: ellipsis;
overflow: hidden;
cursor: pointer;
}
uni-actionsheet .uni-actionsheet__title {
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: 1;
background-color: #fff;
border-radius: 5px 5px 0 0;
border-bottom: 1px solid #e5e5e5;
}
uni-actionsheet .uni-actionsheet__cell:before {
content: " ";
position: absolute;
left: 0;
top: 0;
right: 0;
height: 1px;
border-top: 1px solid #e5e5e5;
color: #e5e5e5;
transform-origin: 0 0;
transform: scaleY(0.5);
}
uni-actionsheet .uni-actionsheet__cell:active {
background-color: #ececec;
}
uni-actionsheet .uni-actionsheet__cell:first-child:before {
display: none;
}
@media screen and (min-width: 500px) and (min-height: 500px) {
.uni-mask.uni-actionsheet__mask {
background: none;
}
uni-actionsheet .uni-actionsheet {
width: 300px;
left: 50%;
right: auto;
top: 50%;
bottom: auto;
transform: translate(-50%, -50%);
opacity: 0;
transition: opacity 0.3s, visibility 0.3s;
}
uni-actionsheet .uni-actionsheet.uni-actionsheet_toggle {
opacity: 1;
transform: translate(-50%, -50%);
}
uni-actionsheet .uni-actionsheet__menu {
box-shadow: 0px 0 20px 5px rgba(0, 0, 0, 0.3);
}
uni-actionsheet .uni-actionsheet__action {
display: none;
}
}
</style>
import Toast from './toast.vue'
import Modal from './modal.vue'
import ActionSheet from './actionSheet.vue'
export default {
Toast,
Modal,
ActionSheet
}
import Toast from './toast'
import Modal from './modal'
import ActionSheet from './actionSheet'
export default {
Toast,
Modal,
ActionSheet,
}
import { isFunction } from '@vue/shared'
export default {
data() {
return {
showActionSheet: {
visible: false
}
}
},
created() {
UniServiceJSBridge.on('onShowActionSheet', (args, callback) => {
this.showActionSheet = args
this.onActionSheetCloseCallback = callback
})
UniServiceJSBridge.on('onHidePopup', args => {
this.showActionSheet.visible = false
})
},
methods: {
// 处理 actionSheet close 回调
_onActionSheetClose(type) {
this.showActionSheet.visible = false
isFunction(this.onActionSheetCloseCallback) &&
this.onActionSheetCloseCallback(type)
}
}
}
import { isFn } from 'uni-shared'
export default {
data() {
return {
showActionSheet: {
visible: false,
},
}
},
created() {
UniServiceJSBridge.on('onShowActionSheet', (args, callback) => {
this.showActionSheet = args
this.onActionSheetCloseCallback = callback
})
UniServiceJSBridge.on('onHidePopup', (args) => {
this.showActionSheet.visible = false
})
},
methods: {
// 处理 actionSheet close 回调
_onActionSheetClose(type) {
this.showActionSheet.visible = false
isFn(this.onActionSheetCloseCallback) &&
this.onActionSheetCloseCallback(type)
},
},
}
import ActionSheet from './action-sheet'
import Modal from './modal'
import Toast from './toast'
import Transtion from './transition'
export default [ActionSheet, Modal, Toast, Transtion]
const mixins = []
const context = require.context('./', false, /\.js$/)
context.keys().forEach(function (key) {
if (key !== './index.js') {
mixins.push(context(key).default)
}
})
export default mixins
import { isFunction } from '@vue/shared'
export default {
data() {
return {
showModal: {
visible: false
}
}
},
created() {
UniServiceJSBridge.on('onShowModal', (args, callback) => {
this.showModal = args
this.onModalCloseCallback = callback
})
UniServiceJSBridge.on('onHidePopup', args => {
this.showModal.visible = false
})
},
methods: {
// 处理 modal close 回调
_onModalClose(type) {
this.showModal.visible = false
isFunction(this.onModalCloseCallback) && this.onModalCloseCallback(type)
}
}
}
import { isFn } from 'uni-shared'
export default {
data() {
return {
showModal: {
visible: false,
},
}
},
created() {
UniServiceJSBridge.on('onShowModal', (args, callback) => {
this.showModal = args
this.onModalCloseCallback = callback
})
UniServiceJSBridge.on('onHidePopup', (args) => {
this.showModal.visible = false
})
},
methods: {
// 处理 modal close 回调
_onModalClose(type) {
this.showModal.visible = false
isFn(this.onModalCloseCallback) && this.onModalCloseCallback(type)
},
},
}
export default {
data() {
return {
popupWidth: 0,
popupHeight: 0,
}
},
computed: {
isDesktop() {
return this.popupWidth >= 500 && this.popupHeight >= 500
},
popupStyle() {
const style = {}
const contentStyle = (style.content = {})
const triangleStyle = (style.triangle = {})
const popover = this.popover
function getNumber(value) {
return Number(value) || 0
}
if (this.isDesktop && popover) {
Object.assign(triangleStyle, {
position: 'absolute',
width: '0',
height: '0',
'margin-left': '-6px',
'border-style': 'solid',
})
const popoverLeft = getNumber(popover.left)
const popoverWidth = getNumber(popover.width)
const popoverTop = getNumber(popover.top)
const popoverHeight = getNumber(popover.height)
const center = popoverLeft + popoverWidth / 2
contentStyle.transform = 'none !important'
const contentLeft = Math.max(0, center - 300 / 2)
contentStyle.left = `${contentLeft}px`
let triangleLeft = Math.max(12, center - contentLeft)
triangleLeft = Math.min(300 - 12, triangleLeft)
triangleStyle.left = `${triangleLeft}px`
const vcl = this.popupHeight / 2
if (popoverTop + popoverHeight - vcl > vcl - popoverTop) {
contentStyle.top = 'auto'
contentStyle.bottom = `${this.popupHeight - popoverTop + 6}px`
triangleStyle.bottom = '-6px'
triangleStyle['border-width'] = '6px 6px 0 6px'
triangleStyle['border-color'] =
'#fcfcfd transparent transparent transparent'
} else {
contentStyle.top = `${popoverTop + popoverHeight + 6}px`
triangleStyle.top = '-6px'
triangleStyle['border-width'] = '0 6px 6px 6px'
triangleStyle['border-color'] =
'transparent transparent #fcfcfd transparent'
}
}
return style
},
},
mounted() {
const fixSize = () => {
const { windowWidth, windowHeight, windowTop } = uni.getSystemInfoSync()
this.popupWidth = windowWidth
this.popupHeight = windowHeight + windowTop
}
window.addEventListener('resize', fixSize)
fixSize()
this.$once('hook:beforeDestroy', () => {
window.removeEventListener('resize', fixSize)
})
},
}
export default {
data() {
return {
showToast: {
visible: false
}
}
},
created() {
let showType = ''
const createOnShow = type => {
return args => {
showType = type
setTimeout(() => {
// 延迟一下 show 可解决窗口打开前调用 showToast 在 onHidePopup 之后触发
this.showToast = args
}, 10)
}
}
UniServiceJSBridge.on('onShowToast', createOnShow('onShowToast'))
UniServiceJSBridge.on('onShowLoading', createOnShow('onShowLoading'))
const createOnHide = type => {
return () => {
if (!showType) {
return
}
let warnMsg = ''
if (type === 'onHideToast' && showType !== 'onShowToast') {
warnMsg = '请注意 showToast 与 hideToast 必须配对使用'
} else if (type === 'onHideLoading' && showType !== 'onShowLoading') {
warnMsg = '请注意 showLoading 与 hideLoading 必须配对使用'
}
if (warnMsg) {
return console.warn(warnMsg)
}
showType = ''
setTimeout(() => {
// 与 show 对应延迟10ms,避免快速调用 show,hide 导致无法关闭
this.showToast.visible = false
}, 10)
}
}
UniServiceJSBridge.on('onHidePopup', createOnHide('onHidePopup'))
UniServiceJSBridge.on('onHideToast', createOnHide('onHideToast'))
UniServiceJSBridge.on('onHideLoading', createOnHide('onHideLoading'))
}
}
import { t } from 'uni-core/helpers/i18n'
export default {
data() {
return {
showToast: {
visible: false,
},
}
},
created() {
let showType = ''
const createOnShow = (type) => {
return (args) => {
showType = type
setTimeout(() => {
// 延迟一下 show 可解决窗口打开前调用 showToast 在 onHidePopup 之后触发
this.showToast = args
}, 10)
}
}
UniServiceJSBridge.on('onShowToast', createOnShow('onShowToast'))
UniServiceJSBridge.on('onShowLoading', createOnShow('onShowLoading'))
const createOnHide = (type) => {
return () => {
if (!showType) {
return
}
let warnMsg = ''
if (type === 'onHideToast' && showType !== 'onShowToast') {
warnMsg = t('uni.showToast.unpaired')
} else if (type === 'onHideLoading' && showType !== 'onShowLoading') {
warnMsg = t('uni.showLoading.unpaired')
}
if (warnMsg) {
return console.warn(warnMsg)
}
showType = ''
setTimeout(() => {
// 与 show 对应延迟10ms,避免快速调用 show,hide 导致无法关闭
this.showToast.visible = false
}, 10)
}
}
UniServiceJSBridge.on('onHidePopup', createOnHide('onHidePopup'))
UniServiceJSBridge.on('onHideToast', createOnHide('onHideToast'))
UniServiceJSBridge.on('onHideLoading', createOnHide('onHideLoading'))
},
}
export default {
methods: {
beforeTransition() {},
afterTransition() {}
}
}
export default {
methods: {
beforeTransition() {},
afterTransition() {},
},
}
......@@ -2,7 +2,7 @@
<transition name="uni-fade">
<uni-modal
v-show="visible"
@touchmove.prevent.passive
@touchmove.prevent
>
<div class="uni-mask" />
<div class="uni-modal">
......@@ -17,7 +17,7 @@
</div>
<div
class="uni-modal__bd"
@touchmove.stop.passive
@touchmove.stop
v-text="content"
/>
<div class="uni-modal__ft">
......@@ -38,13 +38,21 @@
</div>
</div>
</div>
<keypress
:disable="!visible"
@esc="_close('cancel')"
@enter="_close('confirm')"
/>
</uni-modal>
</transition>
</template>
<script>
import transition from './mixins/transition'
import keypress from '../../../helpers/keypress'
export default {
name: 'Modal',
components: { keypress },
mixins: [transition],
props: {
title: {
......@@ -61,7 +69,7 @@ export default {
},
cancelText: {
type: String,
default: '取消'
default: 'Cancel'
},
cancelColor: {
type: String,
......@@ -69,7 +77,7 @@ export default {
},
confirmText: {
type: String,
default: '确定'
default: 'OK'
},
confirmColor: {
type: String,
......@@ -144,6 +152,7 @@ export default {
white-space: pre-wrap;
color: #999999;
max-height: 400px;
overflow-x: hidden;
overflow-y: auto;
}
......@@ -174,6 +183,7 @@ export default {
text-decoration: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
position: relative;
cursor: pointer;
}
uni-modal .uni-modal__btn:active {
......
......@@ -8,7 +8,7 @@
v-if="mask"
class="uni-mask"
style="background: transparent;"
@touchmove.prevent.passive
@touchmove.prevent
/>
<div
v-if="!image&&!iconClass"
......@@ -104,6 +104,7 @@ uni-toast {
display: block;
box-sizing: border-box;
pointer-events: none;
font-size: 16px;
}
uni-toast .uni-sample-toast {
......
import { defineComponent } from 'vue'
export default defineComponent({
name: 'TabBar',
})
<template>
<uni-tabbar>
<uni-tabbar :class="['uni-tabbar-'+position]">
<div
:style="{backgroundColor:backgroundColor}"
:style="{
backgroundColor:tabbarBackgroundColor,
'backdrop-filter':blurEffect !== 'none' ? 'blur(10px)' : blurEffect
}"
class="uni-tabbar"
>
<div
......@@ -10,18 +13,37 @@
/>
<div
v-for="(item,index) in list"
:key="item.pagePath"
:key="item.isMidButton ? index : item.pagePath"
:style="item.isMidButton ? {flex:'0 0 ' + item.width,position:'relative'} : {}"
class="uni-tabbar__item"
@click="_switchTab(item,index)"
>
<div class="uni-tabbar__bd">
<div
<!-- midButton iconPath -->
<div
v-if="item.isMidButton"
class="uni-tabbar__mid"
:style="_uniTabbarBdStyle(item)"
>
<img
v-if="item.iconPath"
:style="{width: item.iconWidth,height:item.iconWidth}"
:src="_getRealPath(item.iconPath)"
>
</div>
<!-- tabbar button -->
<div
class="uni-tabbar__bd"
:style="{height:height}"
>
<div
v-if="item.iconPath || item.isMidButton"
:class="{'uni-tabbar__icon__diff':!item.text}"
class="uni-tabbar__icon"
:style="{width: iconWidth,height:iconWidth}"
>
<img
:src="_getRealPath($route.meta.pagePath===item.pagePath?item.selectedIconPath:item.iconPath)"
v-if="!item.isMidButton"
:src="_getRealPath(selectedIndex===index?item.selectedIconPath:item.iconPath)"
>
<div
v-if="item.redDot"
......@@ -33,7 +55,12 @@
</div>
<div
v-if="item.text"
:style="{color:$route.meta.pagePath===item.pagePath?selectedColor:color,fontSize:item.iconPath?'10px':'14px'}"
:style="{
color:selectedIndex === index ? selectedColor : color,
fontSize: fontSize,
lineHeight: !item.iconPath ? 1.8 : 'normal',
marginTop: !item.iconPath ? 'inherit' : spacing
}"
class="uni-tabbar__label"
>
{{ item.text }}
......@@ -48,130 +75,154 @@
</div>
</div>
</div>
<div class="uni-placeholder" />
<div
class="uni-placeholder"
:style="{height:height}"
/>
</uni-tabbar>
</template>
<style>
uni-tabbar {
display: block;
box-sizing: border-box;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
z-index: 998;
}
uni-tabbar {
display: block;
box-sizing: border-box;
width: 100%;
z-index: 998;
}
uni-tabbar .uni-tabbar {
display: flex;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
z-index: 998;
box-sizing: border-box;
padding-bottom: 0;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
uni-tabbar .uni-tabbar {
display: flex;
z-index: 998;
box-sizing: border-box;
}
uni-tabbar .uni-tabbar ~ .uni-placeholder {
width: 100%;
height: 50px;
margin-bottom: 0;
margin-bottom: constant(safe-area-inset-bottom);
margin-bottom: env(safe-area-inset-bottom);
}
uni-tabbar.uni-tabbar-top,
uni-tabbar.uni-tabbar-bottom,
uni-tabbar.uni-tabbar-top .uni-tabbar,
uni-tabbar.uni-tabbar-bottom .uni-tabbar {
position: fixed;
left: var(--window-left);
right: var(--window-right);
}
uni-tabbar .uni-tabbar * {
box-sizing: border-box;
}
.uni-app--showlayout+uni-tabbar.uni-tabbar-top,
.uni-app--showlayout+uni-tabbar.uni-tabbar-bottom,
.uni-app--showlayout+uni-tabbar.uni-tabbar-top .uni-tabbar,
.uni-app--showlayout+uni-tabbar.uni-tabbar-bottom .uni-tabbar {
left: var(--window-margin);
right: var(--window-margin);
}
uni-tabbar .uni-tabbar__item {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex: 1;
font-size: 0;
text-align: center;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
uni-tabbar.uni-tabbar-bottom .uni-tabbar {
bottom: 0;
padding-bottom: 0;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
uni-tabbar .uni-tabbar__bd {
position: relative;
height: 50px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
}
uni-tabbar .uni-tabbar~.uni-placeholder {
width: 100%;
margin-bottom: 0;
margin-bottom: constant(safe-area-inset-bottom);
margin-bottom: env(safe-area-inset-bottom);
}
uni-tabbar .uni-tabbar__icon {
position: relative;
display: inline-block;
margin-top: 5px;
width: 24px;
height: 24px;
}
uni-tabbar .uni-tabbar * {
box-sizing: border-box;
}
uni-tabbar .uni-tabbar__icon.uni-tabbar__icon__diff {
margin-top: 0px;
width: 34px;
height: 34px;
}
uni-tabbar .uni-tabbar__item {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex: 1;
font-size: 0;
text-align: center;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
uni-tabbar .uni-tabbar__icon img {
width: 100%;
height: 100%;
}
uni-tabbar .uni-tabbar__bd {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
}
uni-tabbar .uni-tabbar__label {
position: relative;
text-align: center;
font-size: 10px;
line-height: 1.8;
}
uni-tabbar .uni-tabbar__icon {
position: relative;
display: inline-block;
margin-top: 5px;
}
uni-tabbar .uni-tabbar-border {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 1px;
transform: scaleY(0.5);
}
uni-tabbar .uni-tabbar__icon.uni-tabbar__icon__diff {
margin-top: 0px;
width: 34px;
height: 34px;
}
uni-tabbar .uni-tabbar__reddot {
position: absolute;
top: 0;
right: 0;
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #f43530;
color: #ffffff;
transform: translate(40%, -20%);
}
uni-tabbar .uni-tabbar__icon img {
width: 100%;
height: 100%;
}
uni-tabbar .uni-tabbar__badge {
width: auto;
height: 16px;
line-height: 16px;
border-radius: 16px;
min-width: 16px;
padding: 0 2px;
font-size: 12px;
text-align: center;
white-space: nowrap;
}
</style>
uni-tabbar .uni-tabbar__label {
position: relative;
text-align: center;
font-size: 10px;
}
<script>
uni-tabbar .uni-tabbar-border {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 1px;
transform: scaleY(0.5);
}
uni-tabbar .uni-tabbar__reddot {
position: absolute;
top: 0;
right: 0;
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #f43530;
color: #ffffff;
transform: translate(40%, -20%);
}
uni-tabbar .uni-tabbar__badge {
width: auto;
height: 16px;
line-height: 16px;
border-radius: 16px;
min-width: 16px;
padding: 0 2px;
font-size: 12px;
text-align: center;
white-space: nowrap;
}
uni-tabbar .uni-tabbar__mid {
display: flex;
justify-content: center;
position: absolute;
bottom: 0;
background-size: 100% 100%;
}
</style>
<script>
import getRealPath from 'uni-platform/helpers/get-real-path'
import { isPlainObject } from 'uni-shared'
import { publish } from 'uni-platform/service/bridge'
function cssSupports (css) {
return window.CSS && CSS.supports && (CSS.supports(css) || CSS.supports.apply(CSS, css.split(':')))
}
export default {
name: 'TabBar',
props: {
......@@ -191,49 +242,119 @@ export default {
},
backgroundColor: {
type: String,
default: '#f7f7fa'
default: ''
},
borderStyle: {
default: 'black',
validator (value) {
return ['black', 'white'].indexOf(value) !== -1
}
type: String,
default: 'black'
},
list: {
type: Array,
default: function () {
return []
}
},
matchMedia: {
type: Object,
default: function () {
return {}
}
},
blurEffect: {
type: String,
default: 'none'
},
fontSize: {
type: String,
default: '10px'
},
iconWidth: {
type: String,
default: '24px'
},
spacing: {
type: String,
default: '3px'
},
height: {
type: String,
default: '50px'
},
midButton: {
type: Object,
default: null
}
},
data () {
return {
selectedIndex: 0
}
},
computed: {
tabbarBackgroundColor () {
// 背景色 区分 高斯模糊 分别返回
const DefaultBgColor = '#f7f7fa'
if (this.backgroundColor) return this.backgroundColor
if (cssSupports('backdrop-filter:blur(10px)') && this.blurEffect !== 'none') {
if (this.blurEffect === 'dark') {
return 'rgb(0, 0, 0, 0.8)'
}
if (['light', 'extralight'].includes(this.blurEffect)) {
return 'rgb(250, 250, 250, 0.8)'
}
}
return DefaultBgColor
},
borderColor () {
return this.borderStyle === 'white'
? 'rgba(255, 255, 255, 0.33)'
: 'rgba(0, 0, 0, 0.33)'
// 不再限制可配置颜色值
if (this.borderStyle === 'white') return 'rgba(255, 255, 255, 0.33)'
if (this.borderStyle === 'black') return 'rgba(0, 0, 0, 0.33)'
return this.borderStyle
}
},
watch: {
'$route' (to, from) {
if (to.meta.isTabBar) {
this.__path__ = to.path
$route: {
immediate: true,
handler (to) {
if (to.meta.isTabBar) {
this.__path__ = to.path
const index = this.list.findIndex(item => to.meta.pagePath === item.pagePath)
if (index > -1) {
this.selectedIndex = index
}
}
}
}
},
created () {
this._initMidButton()
},
beforeCreate () {
this.__path__ = this.$route.path
},
methods: {
_getRealPath (filePath) {
if (filePath.indexOf('/') !== 0) {
const SCHEME_RE = /^([a-z-]+:)?\/\//i
const DATA_RE = /^data:.*,.*/
if (!(SCHEME_RE.test(filePath) || DATA_RE.test(filePath)) && filePath.indexOf('/') !== 0) {
filePath = '/' + filePath
}
return this.$getRealPath(filePath)
return getRealPath(filePath)
},
_switchTab ({
text,
pagePath
pagePath,
isMidButton = false
}, index) {
if (isMidButton) {
publish('onTabBarMidButtonTap')
return
}
this.selectedIndex = index
let url = '/' + pagePath
if (url === __uniRoutes[0].alias) {
url = '/'
......@@ -253,6 +374,29 @@ export default {
} else {
UniServiceJSBridge.emit('onTabItemTap', detail)
}
},
_initMidButton () {
const listLength = this.list.length
// 偶数则添加midButton
if (listLength % 2 === 0 && isPlainObject(this.midButton)) {
// 给midButton赋值默认值
const DefaultMidButton = {
width: '50px',
height: '50px',
iconWidth: '24px'
}
for (const key in DefaultMidButton) {
this.midButton[key] = this.midButton[key] || DefaultMidButton[key]
}
this.list.splice(~~(listLength / 2), 0, Object.assign({}, this.midButton, { isMidButton: true }))
}
},
_uniTabbarBdStyle (item) {
return Object.assign({}, {
width: item.width,
height: item.height,
backgroundImage: item.backgroundImage ? 'url(\'' + this._getRealPath(item.backgroundImage) + '\')' : ''
})
}
}
}
......
<template>
<uni-layout>
<uni-top-window> </uni-top-window>
<uni-content>
<uni-main>
<keep-alive>
<router-view />
</keep-alive>
</uni-main>
</uni-content>
</uni-layout>
</template>
<template>
<div class="uni-async-error" @click="_onClick">
连接服务器超时,点击屏幕重试
<div
class="uni-async-error"
@click="_onClick"
>
{{ $$t("uni.async.error") }}
</div>
</template>
<style>
.uni-async-error {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
color: #999;
padding: 100px 0;
text-align: center;
}
.uni-async-error {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
color: #999;
padding: 100px 10px;
text-align: center;
}
</style>
<script>
import {
i18nMixin
} from '@dcloudio/uni-core/helpers/i18n'
export default {
name: 'AsyncError',
mixins: [i18nMixin],
methods: {
_onClick() {
_onClick () {
// TODO 临时采用 reload
window.location.reload()
},
},
}
}
}
</script>
......@@ -4,20 +4,20 @@
</div>
</template>
<style>
.uni-async-loading {
box-sizing: border-box;
width: 100%;
padding: 50px;
text-align: center;
}
.uni-async-loading {
box-sizing: border-box;
width: 100%;
padding: 50px;
text-align: center;
}
.uni-async-loading .uni-loading {
width: 30px;
height: 30px;
}
.uni-async-loading .uni-loading {
width: 30px;
height: 30px;
}
</style>
<script>
export default {
name: 'AsyncLoading',
name: 'AsyncLoading'
}
</script>
</script>
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册