提交 96b57601 编写于 作者: DCloud_iOS_WZT's avatar DCloud_iOS_WZT

Merge branch 'dev' of gitcode.net:dcloud/hello-uni-app-x into dev

......@@ -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>
......@@ -123,7 +123,7 @@
.uni-bg-blue {
background: #007AFF;
}
}
.uni-btn-v {
padding: 5px 0;
......@@ -189,7 +189,7 @@
}
.text-disabled {
color: #a0a0a0;
color: #a0a0a0!important;
}
......@@ -244,6 +244,11 @@
color: #000000;
font-size: 14px;
font-weight: normal;
}
/* left-windows */
.left-win-active {
color: #007AFF!important;
}
/* --tab-bar-end-- */
......
......@@ -41,6 +41,10 @@
}
}
},
"uni-getLocation":{
"system":{},
"tencent":{}
},
"uni-ad": {
"gdt": {}
}
......
{
"leftWindow": {
"path": "windows/left-window.uvue",
"style": {
"width": "350px"
}
},
"topWindow": {
"path": "windows/top-window.uvue",
"style": {
"height": "60px"
}
},
"pages": [
{
"path": "pages/tabBar/component",
......@@ -331,34 +343,34 @@
}
},
{
"path": "pages/component/public-properties/public-properties",
"path": "pages/component/global-properties/global-properties",
"group": "0,0",
"style": {
"navigationBarTitleText": "公共属性"
"navigationBarTitleText": "全局属性"
}
},
{
"path": "pages/component/public-events/public-events",
"path": "pages/component/global-events/global-events",
"group": "0,0",
"style": {
"navigationBarTitleText": "公共事件"
"navigationBarTitleText": "全局事件"
}
},
{
"path": "pages/component/public-events/transition-events",
"path": "pages/component/global-events/transition-events",
"group": "0,0",
"style": {
"navigationBarTitleText": "Transition Events"
}
},
{
"path": "pages/component/public-events/touch-events",
"path": "pages/component/global-events/touch-events",
"group": "0,0",
"style": {
"navigationBarTitleText": "Touch Events"
}
},
// #ifndef WEB
// #ifndef WEB
{
"path": "pages/component/nested-scroll-header/nested-scroll-header",
"group": "0,1,8,0",
......@@ -366,8 +378,8 @@
"navigationBarTitleText": "nested-scroll-header"
}
},
// #endif
// #ifndef WEB
// #endif
// #ifndef WEB
{
"path": "pages/component/nested-scroll-body/nested-scroll-body",
"group": "0,1,8,1",
......@@ -375,7 +387,7 @@
"navigationBarTitleText": "nested-scroll-body"
}
},
// #endif
// #endif
{
"path": "pages/component/swiper/swiper-list-view",
"style": {
......@@ -383,7 +395,7 @@
"enablePullDownRefresh": false
}
},
// #ifdef WEB
// #ifdef WEB
{
"path": "pages/component/movable-view/movable-view",
"group": "0,1,4,1",
......@@ -391,8 +403,8 @@
"navigationBarTitleText": "movable-view | 可拖动视图容器"
}
},
// #endif
// #ifdef WEB
// #endif
// #ifdef WEB
{
"path": "pages/component/label/label",
"group": "0,3,5",
......@@ -400,8 +412,8 @@
"navigationBarTitleText": "label"
}
},
// #endif
// #ifdef WEB
// #endif
// #ifdef WEB
{
"path": "pages/component/picker/picker",
"group": "0,3,6",
......@@ -409,8 +421,8 @@
"navigationBarTitleText": "picker | 底部弹出滚动选择器"
}
},
// #endif
// #ifdef WEB
// #endif
// #ifdef WEB
{
"path": "pages/component/map/map",
"group": "0,6",
......@@ -418,8 +430,8 @@
"navigationBarTitleText": "map | 地图"
}
},
// #endif
// #ifdef WEB
// #endif
// #ifdef WEB
{
"path": "pages/component/cover-view/cover-view",
"group": "0,1,5,0",
......@@ -427,8 +439,8 @@
"navigationBarTitleText": "cover-view"
}
},
// #endif
// #ifdef WEB
// #endif
// #ifdef WEB
{
"path": "pages/component/editor/editor",
"group": "0,3,4",
......@@ -436,8 +448,8 @@
"navigationBarTitleText": "editor | 富文本编辑器"
}
},
// #endif
// #ifdef WEB
// #endif
// #ifdef WEB
{
"path": "pages/API/open-location/open-location",
"group": "1,8,1",
......@@ -445,8 +457,8 @@
"navigationBarTitleText": "openLocation | 使用地图查看位置"
}
},
// #endif
// #ifdef WEB
// #endif
// #ifdef WEB
{
"path": "pages/API/choose-location/choose-location",
"group": "1,8,2",
......@@ -454,7 +466,7 @@
"navigationBarTitleText": "chooseLocation | 使用地图选择位置"
}
},
// #endif
// #endif
{
"path": "pages/component/list-view/issue-2199",
"style": {
......@@ -476,6 +488,16 @@
"navigationBarTitleText": "ball"
}
},
// #ifndef WEB
{
"path": "pages/component/animation-view/animation-view",
"group": "0,5,3",
"style": {
"navigationBarTitleText": "animation-view | Lottie动画",
"enablePullDownRefresh": false
}
},
// #endif
{
"path": "pages/tabBar/API",
"style": {
......@@ -490,7 +512,7 @@
"navigationBarTitleText": "getApp | 获取当前应用实例"
}
},
// #ifdef APP-ANDROID
// #ifdef APP-ANDROID
{
"path": "pages/API/exit/exit",
"group": "1,1,5",
......@@ -498,8 +520,8 @@
"navigationBarTitleText": "exit | 退出应用"
}
},
// #endif
// #ifdef APP-ANDROID
// #endif
// #ifdef APP-ANDROID
{
"path": "pages/API/install-apk/install-apk",
"group": "1,6,6",
......@@ -508,7 +530,7 @@
"enablePullDownRefresh": false
}
},
// #endif
// #endif
{
"path": "pages/API/get-current-pages/get-current-pages",
"group": "1,0,1",
......@@ -592,7 +614,7 @@
"navigationBarTitleText": "storage | key-value本地数据存储"
}
},
// #ifndef WEB
// #ifndef WEB
{
"path": "pages/API/get-file-system-manager/get-file-system-manager",
"group": "1,10,0",
......@@ -600,8 +622,8 @@
"navigationBarTitleText": "getFileSystemManager | 获取文件管理器"
}
},
// #endif
// #ifndef WEB
// #endif
// #ifndef WEB
{
"path": "pages/API/env/env",
"group": "1,1,0",
......@@ -609,7 +631,7 @@
"navigationBarTitleText": "env | 环境变量"
}
},
// #endif
// #endif
{
"path": "pages/API/show-action-sheet/show-action-sheet",
"group": "1,4,1",
......@@ -746,7 +768,7 @@
"navigationBarTitleText": "getAppBaseInfo | 获取APP基础信息"
}
},
// #ifndef WEB
// #ifndef WEB
{
"path": "pages/API/get-system-setting/get-system-setting",
"group": "1,6,5",
......@@ -754,8 +776,8 @@
"navigationBarTitleText": "getSystemSetting | 获取系统设置"
}
},
// #endif
// #ifndef WEB
// #endif
// #ifndef WEB
{
"path": "pages/API/element-takesnapshot/element-takesnapshot",
"group": "1,30",
......@@ -764,8 +786,8 @@
"enablePullDownRefresh": false
}
},
// #endif
// #ifndef WEB
// #endif
// #ifndef WEB
{
"path": "pages/API/get-app-authorize-setting/get-app-authorize-setting",
"group": "1,6,4",
......@@ -773,7 +795,7 @@
"navigationBarTitleText": "getAppAuthorizeSetting | 获取APP授权设置"
}
},
// #endif
// #endif
{
"path": "pages/API/preview-image/preview-image",
"group": "1,7,1",
......@@ -795,7 +817,7 @@
"navigationBarTitleText": "getImageInfo | 获取图片信息"
}
},
// #ifndef WEB
// #ifndef WEB
{
"path": "pages/API/compress-image/compress-image",
"group": "1,7,4",
......@@ -803,7 +825,7 @@
"navigationBarTitleText": "compressImage | 压缩图片"
}
},
// #endif
// #endif
{
"path": "pages/API/choose-video/choose-video",
"group": "1,7,5",
......@@ -811,7 +833,7 @@
"navigationBarTitleText": "chooseVideo | 拍摄视频或从相册中选择视频"
}
},
// #ifndef WEB
// #ifndef WEB
{
"path": "pages/API/save-image-to-photos-album/save-image-to-photos-album",
"group": "1,7,2",
......@@ -819,8 +841,8 @@
"navigationBarTitleText": "saveImageToPhotosAlbum | 保存图片到相册"
}
},
// #endif
// #ifndef WEB
// #endif
// #ifndef WEB
{
"path": "pages/API/save-video-to-photos-album/save-video-to-photos-album",
"group": "1,7,6",
......@@ -828,7 +850,7 @@
"navigationBarTitleText": "saveVideoToPhotosAlbum | 保存视频到相册"
}
},
// #endif
// #endif
{
"path": "pages/API/get-video-info/get-video-info",
"group": "1,7,7",
......@@ -836,7 +858,7 @@
"navigationBarTitleText": "getVideoInfo | 获取视频信息"
}
},
// #ifndef WEB
// #ifndef WEB
{
"path": "pages/API/compress-video/compress-video",
"group": "1,7,8",
......@@ -844,7 +866,7 @@
"navigationBarTitleText": "compressVideo | 压缩视频"
}
},
// #endif
// #endif
{
"path": "pages/API/get-network-type/get-network-type",
"group": "1,5,3",
......@@ -894,7 +916,7 @@
"navigationBarTitleText": "getWindowInfo | 获取窗口信息"
}
},
// #ifndef WEB
// #ifndef WEB
{
"path": "pages/API/element-draw/element-draw",
"group": "1,30",
......@@ -903,8 +925,8 @@
"enablePullDownRefresh": false
}
},
// #endif
// #ifndef WEB
// #endif
// #ifndef WEB
{
"path": "pages/API/facial-recognition-meta-info/facial-recognition-meta-info",
"group": "1,11,1",
......@@ -913,8 +935,8 @@
"enablePullDownRefresh": false
}
},
// #endif
// #ifndef WEB
// #endif
// #ifndef WEB
{
"path": "pages/API/get-univerify-manager/get-univerify-manager",
"group": "1,11,0",
......@@ -923,7 +945,7 @@
"enablePullDownRefresh": false
}
},
// #endif
// #endif
{
"path": "pages/API/rpx2px/rpx2px",
"group": "1,4,6",
......@@ -932,7 +954,7 @@
"enablePullDownRefresh": false
}
},
// #ifdef APP-ANDROID
// #ifdef APP-ANDROID
{
"path": "pages/API/create-request-permission-listener/create-request-permission-listener",
"group": "1,6,16",
......@@ -941,8 +963,8 @@
"enablePullDownRefresh": false
}
},
// #endif
// #ifndef WEB
// #endif
// #ifndef WEB
{
"path": "pages/API/request-payment/request-payment",
"group": "1,14,0",
......@@ -951,8 +973,8 @@
"enablePullDownRefresh": false
}
},
// #endif
// #ifndef WEB
// #endif
// #ifndef WEB
{
"path": "pages/API/create-rewarded-video-ad/create-rewarded-video-ad",
"group": "1,12,0",
......@@ -961,7 +983,7 @@
"enablePullDownRefresh": false
}
},
// #endif
// #endif
{
"path": "pages/API/request-payment/request-payment/request-payment-uni-pay",
"group": "1,14",
......@@ -970,6 +992,16 @@
"enablePullDownRefresh": false
}
},
// #ifdef APP-IOS
{
"path": "pages/API/virtual-payment/virtual-payment",
"group": "1,14,1",
"style": {
"navigationBarTitleText": "virtualPayment | 苹果内购",
"enablePullDownRefresh": false
}
},
// #endif
{
"path": "pages/API/request-payment/request-payment/order-detail",
"style": {
......@@ -977,7 +1009,7 @@
"enablePullDownRefresh": false
}
},
// #ifdef WEB
// #ifdef WEB
{
"path": "pages/API/make-phone-call/make-phone-call",
"group": "1,6,9",
......@@ -985,8 +1017,8 @@
"navigationBarTitleText": "makePhoneCall | 打电话"
}
},
// #endif
// #ifdef WEB
// #endif
// #ifdef WEB
{
"path": "pages/API/create-inner-audio-context/create-inner-audio-context",
"group": "1,7,9",
......@@ -994,24 +1026,24 @@
"navigationBarTitleText": "createInnerAudioContext | 音频"
}
},
// #endif
// #ifdef WEB
// #endif
// #ifdef WEB
{
"path": "pages/API/create-inner-audio-context/inner-audio-format",
"style": {
"navigationBarTitleText": "inner-audio-format"
}
},
// #endif
// #ifdef WEB
// #endif
// #ifdef WEB
{
"path": "pages/API/create-inner-audio-context/inner-audio-path",
"style": {
"navigationBarTitleText": "inner-audio-path"
}
},
// #endif
// #ifdef WEB
// #endif
// #ifdef WEB
{
"path": "pages/API/clipboard/clipboard",
"group": "1,6,10",
......@@ -1019,8 +1051,8 @@
"navigationBarTitleText": "clipboard | 剪切板"
}
},
// #endif
// #ifdef WEB
// #endif
// #ifdef WEB
{
"path": "pages/API/compass/compass",
"group": "1,6,11",
......@@ -1028,8 +1060,8 @@
"navigationBarTitleText": "compass | 罗盘"
}
},
// #endif
// #ifndef WEB
// #endif
// #ifndef WEB
{
"path": "pages/API/theme-change/theme-change",
"group": "1,4,7",
......@@ -1038,7 +1070,7 @@
"enablePullDownRefresh": false
}
},
// #endif
// #endif
{
"path": "pages/API/get-element-by-id/get-element-by-id",
"group": "1,3,0",
......@@ -1066,7 +1098,7 @@
"navigationBarTitleText": "UniResizeObserver"
}
},
// #ifndef WEB
// #ifndef WEB
{
"path": "pages/API/get-provider/get-provider",
"group": "1,1,6",
......@@ -1074,8 +1106,8 @@
"navigationBarTitleText": "getProvider | 获取服务提供商"
}
},
// #endif
// #ifndef WEB
// #endif
// #ifndef WEB
{
"path": "pages/API/push/push",
"group": "1,6,7",
......@@ -1083,7 +1115,7 @@
"navigationBarTitleText": "push | 推送"
}
},
// #endif
// #endif
{
"path": "pages/tabBar/CSS",
"style": {
......@@ -1672,15 +1704,6 @@
}
},
// #endif
// #ifdef APP-ANDROID
{
"path": "pages/template/lottie-anim/lottie-anim",
"style": {
"navigationBarTitleText": "lottie动画-需要自定义基座",
"enablePullDownRefresh": false
}
},
// #endif
// #ifdef APP || WEB
{
"path": "uni_modules/uni-pay-x/pages/success/success",
......@@ -1778,8 +1801,8 @@
"name": "组件",
"children": [
{
"id": "component.public-properties-events",
"name": "公共属性和事件"
"id": "component.global-properties-events",
"name": "全局属性和事件"
},
{
"id": "component.view-container",
......@@ -1948,6 +1971,10 @@
{
"id": "component.media.video",
"name": "video"
},
{
"id": "component.media.animation-view",
"name": "animation-view"
}
]
},
......@@ -2293,6 +2320,10 @@
{
"id": "api.payment.requestPayment",
"name": "requestPayment"
},
{
"id": "api.payment.virtualPayment",
"name": "virtualPayment"
}
]
},
......
......@@ -7,10 +7,19 @@
<view class="service-item" v-for="(item, index) in serviceList" :key="index">
<text class="service-name">{{item.name}}:</text>
<view class="provider-list">
<!-- #ifdef APP-IOS -->
<text class="provider-item" v-for="(item2, index2) in item.provider" :key="index2">
{{item2}}
{{item.providerObj.length > 0 ? ':'+ JSON.stringify(item.providerObj[index2]) : '' }}
{{item.providerObjMap.length > 0 ? ':' + JSON.stringify(item.providerObjMap[index2]) : '' }}
</text>
<!-- #endif -->
<!-- #ifdef APP-ANDROID -->
<text class="provider-item" v-for="(item2, index2) in item.provider" :key="index2">
{{item2}}
{{item.providerObj.length > 0 ? ':' + JSON.stringify(item.providerObj[index2]) : '' }}
</text>
<!-- #endif -->
</view>
</view>
<button class="btn-get-provider" type="primary" @click="getProviderIds">getProviderIds</button>
......@@ -22,26 +31,25 @@
</template>
<script>
type ProviderItem = {
service : string,
name : string,
provider : string[],
providerObj : UniProvider[]
providerObj : UniProvider[],
providerObjMap : Object[],
}
export default {
data() {
return {
title: 'provider',
flag: false,
serviceList: [
{ service: "oauth", name: "登陆", provider: [], providerObj: [] },
{ service: "share", name: "分享", provider: [], providerObj: [] },
{ service: "payment", name: "支付", provider: [], providerObj: [] },
{ service: "push", name: "推送", provider: [], providerObj: [] },
{ service: "location", name: "定位", provider: [], providerObj: [] }
{ service: "oauth", name: "登陆", provider: [], providerObj: [], providerObjMap: [] },
{ service: "share", name: "分享", provider: [], providerObj: [], providerObjMap: [] },
{ service: "payment", name: "支付", provider: [], providerObj: [], providerObjMap: [] },
{ service: "push", name: "推送", provider: [], providerObj: [], providerObjMap: [] },
{ service: "location", name: "定位", provider: [], providerObj: [], providerObjMap: [] }
] as ProviderItem[],
providerObjList: [] as UniProvider[]
}
......@@ -74,13 +82,52 @@
provider: provider
})
if (obj != null) {
console.log(obj)
console.log(JSON.stringify(obj))
value.providerObj.push(obj)
}
// #ifdef APP-IOS
const providerObjMap = this.getProviderObjectMap(obj)
console.log(providerObjMap)
value.providerObjMap.push(providerObjMap)
// #endif
}
})
})
},
// #ifdef APP-IOS
getProviderObjectMap(provider : UniProvider) {
const map = new Map()
if (this.hasProperty(provider, 'id') && provider.id != null) {
map.set('id', provider.id)
}
if (this.hasProperty(provider, 'description') && provider.description != null) {
map.set('description', provider.description)
}
if (this.hasProperty(provider, 'isAppExist') && provider.isAppExist != null) {
map.set('isAppExist', provider.isAppExist)
}
if (this.hasProperty(provider, 'isWeChatInstalled') && provider.isWeChatInstalled != null) {
map.set('isWeChatInstalled', provider.isWeChatInstalled)
}
if (this.hasMethod(provider, 'uniqueMethodForProvider')) {
map.set('func-uniqueMethodForProvider', provider.uniqueMethodForProvider())
}
return Object.fromEntries(map)
},
hasMethod(provider : UniProvider, methodName : string) {
return typeof provider[methodName] === 'function';
},
hasProperty(provider : UniProvider, propName : string) {
return propName in provider
}
},
// #endif
}
}
</script>
......
......@@ -55,5 +55,22 @@ describe('interceptor', () => {
const currentPage = await program.currentPage()
expect(currentPage.path).toBe('pages/API/interceptor/page1')
await program.navigateBack()
})
})
it('addSwitchTabInterceptor', async () => {
await page.callMethod('addSwitchTabInterceptor')
await page.callMethod('switchTab')
const currentPage = await program.currentPage()
expect(currentPage.path).toBe('pages/tabBar/API')
})
it('removeSwitchTabInterceptor', async () => {
const currentPage1 = await program.navigateTo(PAGE_PATH)
await currentPage1.callMethod('addSwitchTabInterceptor')
await currentPage1.callMethod('removeSwitchTabInterceptor')
await currentPage1.callMethod('switchTab')
const currentPage2 = await program.currentPage()
expect(currentPage2.path).toBe('pages/tabBar/component')
})
})
......@@ -4,14 +4,15 @@
<button @click="removeInterceptor">移除路由拦截器</button>
<text>点击下方按钮{{ msg }}</text>
<button @click="navigateTo">navigatorTo API跳转到测试页面</button>
<navigator url="./page1"><button class="navigatorButton">
navigator组件跳转到测试页面
</button></navigator>
<navigator url="./page1">
<button class="navigatorButton">navigator组件跳转到测试页面</button>
</navigator>
<button class="navigatorButton" @click="switchTab">switchTab API</button>
</view>
</template>
<script>
const interceptor = {
const navigateToInterceptor = {
invoke: function (options : NavigateToOptions) {
console.log('拦截 navigateTo 接口传入参数为:', options)
const url = './page2'
......@@ -30,6 +31,23 @@
console.log('拦截 navigateTo 接口 complete 返回参数为:', res)
}
} as Interceptor
const switchTabInterceptor = {
invoke: function (options : SwitchTabOptions) {
console.log('拦截 switchTab 接口传入参数为:', options)
options.url = 'pages/tabBar/API'
},
success: function (res : SwitchTabSuccess) {
console.log('拦截 switchTab 接口 success 返回参数为:', res)
},
fail: function (err : SwitchTabFail) {
console.log('拦截 switchTab 接口 fail 返回参数为:', err)
},
complete: function (res : SwitchTabComplete) {
console.log('拦截 switchTab 接口 complete 返回参数为:', res)
}
} as Interceptor
export default {
data() {
return {
......@@ -39,21 +57,28 @@
beforeUnmount() {
// 移除 navigateTo 所有拦截器
uni.removeInterceptor('navigateTo')
uni.removeInterceptor('switchTab')
},
methods: {
addInterceptor() {
uni.addInterceptor('navigateTo', interceptor)
uni.addInterceptor('navigateTo', navigateToInterceptor)
uni.showToast({
title: '页面跳转已拦截'
title: '页面跳转/切换tabbar已拦截'
})
this.msg = ",路由被劫持到测试页面2"
},
removeInterceptor() {
uni.removeInterceptor('navigateTo', interceptor)
uni.removeInterceptor('navigateTo', navigateToInterceptor)
uni.showToast({
title: '拦截器已移除'
})
this.msg = "会跳转到测试页面1"
},
addSwitchTabInterceptor() {
uni.addInterceptor('switchTab', switchTabInterceptor)
},
removeSwitchTabInterceptor() {
uni.removeInterceptor('switchTab', switchTabInterceptor)
},
navigateTo() {
uni.navigateTo({
......@@ -68,6 +93,20 @@
console.log('res:', res)
}
})
},
switchTab() {
uni.switchTab({
url: 'pages/tabBar/component',
success(res) {
console.log('res:', res)
},
fail(err) {
console.error('err:', err)
},
complete(res) {
console.log('res:', res)
}
})
}
}
}
......
......@@ -164,4 +164,11 @@ describe('ExtApi-Request', () => {
expect(res).toBe(true)
})
}
it('Check Respone Json String', async () => {
res = await page.callMethod('jest_respone_json_string')
await page.waitFor(2000);
res = await page.data('jest_result');
expect(res).toBe(true)
})
});
......@@ -396,6 +396,18 @@
}
} as CommonOptions)
// #endif
},
jest_respone_json_string(){
uni.request({
url:"https://request.dcloud.net.cn/api/http/contentType/text/json",
success:(res: RequestSuccess<any>)=>{
console.log("res :", res, typeof res.data);
this.jest_result = typeof res.data == "object"
},
fail:(e: RequestFail)=>{
this.jest_result = false
}
})
}
}
}
......
<template>
<!-- #ifdef APP -->
<scroll-view style="flex: 1;">
<!-- #endif -->
<page-head title="苹果内购支付"></page-head>
<view style="padding-left: 20px; padding-right: 20px;">
<text>
requestVirtualPayment api 适用于消耗性类型、非消耗性类型、自动续期订阅类型、非自动续期订阅类型产品的购买。\n\n
1. 消耗性类型:该类型的产品可以设置购买数量,默认是1,最大值是10; \n
2. 非消耗性类型、自动续期订阅类型、非自动续期订阅类型: 这些类型的产品购买数量设置无效,数量只能是1。
</text>
<button style="margin-top: 20px;" type="primary" v-for="(item,index) in productList" :key="index"
@click="requestVirtualPayment(item)">{{item.name}}</button>
<text>
\nrestoreCompletedTransactions api 适用于非消耗性类型、自动续期订阅类型、非自动续期订阅类型产品的购买。\n\n
1. 非消耗性类型: 返回每个已购买的非消耗性类型产品的购买记录;\n
2. 自动续期订阅类型: 返回每个已购买的自动续期订阅类型产品的最新购买记录,沙盒账号最多可自动续订 12 次;\n
3. 非自动续期订阅类型: 返回每个已购买的非自动续期订阅类型产品的最新购买记录, 该类型订阅可以连续多次购买,开发者需要自己的后台计算产品过期的时间。\n
Note: 不能用来恢复消耗性类型的购买记录。
</text>
<button style="margin-top: 20px;" type="primary" @click="restoreCompletedTransactions">恢复购买订单列表</button>
<text>
\ngetUnfinishedTransactions api 适用于获取未完成的各种类型产品的购买记录(用来防止丢单)。\n\n
1. 比如用户点击购买已经付款成功,但因网络、手机没电关机等特殊情况,Apple IAP
没有返回客户端对应的购买凭证,从而导致无法finish该交易导致的丢单,可以在需要的地方调用该api获得此类未finished的交易记录; \n
2. 针对消耗性类型产品交易,只能通过该api获取未finished的交易,防止丢单;\n
3. 对于其他类型产品未finished交易, 不仅可以通过该api获取,也可以通过restoreCompletedTransactions api (也可获取已经finished的交易)获取;
</text>
<button style="margin-top: 20px; margin-bottom: 50px;" type="primary"
@click="getUnfinishedTransactions">获取未结束的订单列表</button>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
export type PayItem = { id : string, name : string, quantity ?: number }
export default {
data() {
return {
productList: [] as PayItem[]
}
},
onLoad: function () {
this.productList.push({
name: '消耗性产品:个人赞助1元,购买数量=5',
id: this.isDebug() ? "uniappx.consumable.sponsor_1" : "uniappx.consumable.sponsor1",
quantity: 5
} as PayItem);
this.productList.push({
name: '消耗性产品:金牌赞助50元',
id: this.isDebug() ? "uniappx.consumable.sponsor_50" : "uniappx.consumable.sponsor50",
quantity: 1
} as PayItem);
this.productList.push({
name: '非消耗性产品: 赞助特效1元',
id: this.isDebug() ? "uniappx.nonconsumable.sponsorskin_1" : "uniappx.nonconsumable.sponsorskin1"
} as PayItem);
this.productList.push({
name: '自动续期订阅产品:每月定期赞助1元',
id: this.isDebug() ? "uniappx.autorenewable.monthly_1" : "uniappx.autorenewable.monthly1"
} as PayItem);
this.productList.push({
name: '非自动续期订阅产品:月赞助1元',
id: this.isDebug() ? "uniappx.nonrenewable.monthly_1" : "uniappx.nonrenewable.monthly1"
} as PayItem);
this.productList.push({
name: '测试不存在的产品',
id: "uniappx.nonrenewable.none"
} as PayItem);
},
methods: {
getPackageName() : string {
const res = uni.getAppBaseInfo();
let packageName : string = ""
// #ifdef APP-ANDROID
packageName = res.packageName
// #endif
// #ifdef APP-IOS
packageName = res.bundleId
// #endif
return packageName
},
isDebug() : boolean {
if (this.getPackageName() == 'io.dcloud.uniappx') {
return true
}
return false
},
isProd() : boolean {
if (this.getPackageName() == 'io.dcloud.hellouniappx') {
return true
}
return false
},
isCustom() : boolean {
if (this.isDebug() == false && this.isProd() == false) {
return true
}
return false
},
requestVirtualPayment(e : PayItem) {
uni.showLoading({
title: "",
mask: true
});
uni.requestVirtualPayment({
apple: {
productId: e.id,
appAccountToken: "orderId+accountId",
quantity: e.quantity ?? 1
},
success: (res) => {
uni.hideLoading()
console.log("购买成功:该productId= " + res.apple?.payment.productId)
//TODO: 开发者server验证逻辑
//经过开发者server验证成功后请结束该交易
uni.finishedTransaction({
transaction: res.apple,
success: (r) => {
console.log("关单成功, 该productId= " + res.apple?.payment.productId)
},
fail: (e) => {
console.log("关单失败, 该productId= " + res.apple?.payment.productId)
}
})
uni.showToast({
title: "购买成功:" + res.apple?.payment.productId,
icon: 'error'
})
},
fail: (e) => {
uni.hideLoading()
console.log("购买失败:errSubject= " + e.errSubject + ", errCode= " + e.errCode + ", errMsg= " + e.errMsg)
uni.showToast({
title: "购买失败:errCode=" + e.errCode,
icon: 'error'
})
}
})
},
restoreCompletedTransactions() {
uni.showLoading({
title: "",
mask: true
});
uni.restoreCompletedTransactions({
success: (res) => {
uni.hideLoading()
console.log("restore成功的交易个数:" + res.transactions.length)
res.transactions.forEach(transaction => {
//TODO: 开发者server验证逻辑
console.log("restore成功的交易productId= " + transaction.payment.productId)
})
uni.showToast({
title: "restore成功的交易个数:" + res.transactions.length,
icon: 'error'
})
},
fail: (e) => {
uni.hideLoading()
console.log("restore失败:errSubject= " + e.errSubject + ", errCode= " + e.errCode + ", errMsg= " + e.errMsg)
uni.showToast({
title: "restore失败:errCode=" + e.errCode,
icon: 'error'
})
}
})
},
getUnfinishedTransactions() {
uni.showLoading({
title: "",
mask: true
});
uni.getUnfinishedTransactions({
success: (res) => {
uni.hideLoading()
console.log("获取未结束的订单列表个数:" + res.transactions.length)
res.transactions.forEach(transaction => {
//TODO: 开发者server验证逻辑
//经过开发者server验证成功后请结束该交易
uni.finishedTransaction({
transaction: transaction,
success: (r) => {
console.log("关单成功, 该productId= " + transaction.payment.productId)
},
fail: (e) => {
console.log("关单失败, 该productId= " + transaction.payment.productId)
}
})
})
uni.showToast({
title: "获取未结束的订单列表个数:" + res.transactions.length,
icon: 'error'
})
},
fail: (e) => {
uni.hideLoading()
console.log("获取未结束的订单列表失败:errSubject= " + e.errSubject + ", errCode= " + e.errCode + ", errMsg= " + e.errMsg)
uni.showToast({
title: "获取未结束的订单列表失败:errCode= " + e.errCode,
icon: 'error'
})
}
})
}
}
}
</script>
<style>
</style>
......@@ -27,6 +27,11 @@
<text>border-bottom-right-radius: 10px</text>
<view class="common" style="border-bottom-right-radius: 10px"></view>
</view>
<view>
<text>border-radius: 250px(与长宽相同形成正圆)</text>
<view class="common" style="border-radius: 250px"></view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
......
......@@ -14,7 +14,7 @@
<script>
function hidpi(canvas : UniCanvasElement) {
const context = canvas.getContext("2d")!;
const dpr = uni.getSystemInfoSync().pixelRatio;
const dpr = uni.getDeviceInfo().devicePixelRatio ?? 1;
canvas.width = canvas.offsetWidth * dpr;
canvas.height = canvas.offsetHeight * dpr;
context.scale(dpr, dpr);
......
......@@ -55,16 +55,13 @@
private runningFlag : boolean = false
// #ifdef WEB
private _bindAnimate: Function = null
private _animateResult: number = 0
// #endif
constructor(ctx : CanvasRenderingContext2D) {
this.ctx = ctx
this.initBall()
this.ctx.fillStyle = '#007AFF'
// #ifdef WEB
this._bindAnimate = this.animate.bind(this)
// #endif
this.ctx.fillStyle = '#007AFF'
}
private getDistance(x : number, y : number) : number {
......@@ -106,13 +103,15 @@
if (!this.runningFlag) {
return
}
requestAnimationFrame(this._bindAnimate)
this._animateResult = requestAnimationFrame(() => {
this.animate()
})
// #endif
}
start() {
// #ifdef WEB
cancelAnimationFrame(this._bindAnimate)
cancelAnimationFrame(this._animateResult)
this.runningFlag = true
this.animate()
// #endif
......@@ -129,7 +128,7 @@
stop() {
// #ifdef WEB
this.runningFlag = false
cancelAnimationFrame(this._bindAnimate)
cancelAnimationFrame(this._animateResult)
// #endif
// #ifdef APP
......@@ -144,7 +143,7 @@
let canvas = uni.getElementById("canvas") as UniCanvasElement
let canvasContext = canvas.getContext("2d");
if (canvasContext != null) {
const dpr = uni.getSystemInfoSync().pixelRatio
const dpr = uni.getDeviceInfo().devicePixelRatio ?? 1;
canvas.width = canvas.offsetWidth * dpr
canvas.height = canvas.offsetHeight * dpr
canvasContext.scale(dpr, dpr)
......
const PAGE_PATH = '/pages/component/public-events/public-events'
const PAGE_PATH = '/pages/component/global-events/global-events'
describe('event trigger', () => {
const platformInfo = process.env.uniTestPlatformInfo.toLocaleLowerCase()
......
......@@ -433,7 +433,7 @@
export default {
data() {
return {
title: 'public-events',
title: 'global-events',
touchStartEvent: null as TouchEvent | null,
touchCancelEvent: null as TouchEvent | null,
touchMoveEvent: null as TouchEvent | null,
......@@ -502,4 +502,4 @@
margin-top: 5px;
font-size: 16px;
}
</style>
</style>
......@@ -3,7 +3,7 @@
describe('transition event', () => {
let page;
beforeAll(async () => {
page = await program.reLaunch('/pages/component/public-events/transition-events')
page = await program.reLaunch('/pages/component/global-events/transition-events')
await page.waitFor(3000);
});
......
const PAGE_PATH = '/pages/component/public-properties/public-properties'
const PAGE_PATH = '/pages/component/global-properties/global-properties'
describe('general attribute', () => {
let page
......
......@@ -55,7 +55,7 @@
export default {
data() {
return {
title: 'public-properties',
title: 'global-properties',
generalId: 'general-id',
generalClass: 'general-class',
generalName: 'general-name',
......
......@@ -30,6 +30,14 @@
</view>
</view>
</view>
<view>
<text class="uni-subtitle-text">image默认mode</text>
<view class="uni-center" style="background:#FFFFFF;">
<view class="uni-center" style="margin: 20px;">
<image style="width: 100px; height: 100px;" src="/static/logo.png"></image>
</view>
</view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
......
<template>
<view class="content">
<map class="map" id="map1" ref="map1" :controls="controls" :scale="scale" :longitude="location.longitude"
<map class="map" id="map1" ref="map1" :controls="controls" :scale="scale" min-scale="3" max-scale="20" :longitude="location.longitude"
:latitude="location.latitude" :show-location="showLocation" :enable-3D="enable3D" :rotate="rotate" :skew="skew"
:show-compass="showCompass" :enable-overlooking="enableOverlooking" :enable-zoom="enableZoom"
:enable-scroll="enableScroll" :enable-rotate="enableRotate" :enable-satellite="enableSatellite"
......@@ -8,22 +8,29 @@
:include-points="includePoints" @tap="maptap" @controltap="oncontroltap" @markertap="onmarkertap"
@callouttap="oncallouttap" @poitap="onpoitap" @updated="onupdated" @regionchange="onregionchange"></map>
<scroll-view class="scrollview" scroll-y="true">
<view class="uni-title">
<text class="uni-title-text">属性示例</text>
</View>
<input-data defaultValue="13" title="scale: 缩放级别,取值范围为3-20" type="number" @confirm="confirm_scale_input"></input-data>
<boolean-data :defaultValue="showLocation" title="开启显示带有方向的当前定位点" @change="change_show_location"></boolean-data>
<button class="button" @click="changeScale">changeScale</button>
<button class="button" @click="addMarkers">addMarkers</button>
<button class="button" @click="addPolyline">addPolyline</button>
<button class="button" @click="addPolygons">addPolygons</button>
<button class="button" @click="addCircles">addCircles</button>
<button class="button" @click="includePoint">includePoints</button>
<button class="button" @click="handleGetCenterLocation">getCenterLocation</button>
<button class="button" @click="handleGetRegion">getRegion</button>
<button class="button" @click="handleTranslateMarker">translateMarker</button>
<button class="button" @click="addControls">控件</button>
<button class="button" @click="addMarkers">标记点</button>
<button class="button" @click="addPolyline">路线</button>
<button class="button" @click="addPolygons">多边形</button>
<button class="button" @click="addCircles">圆</button>
<button class="button" @click="includePoint">缩放视野以包含所有给定的坐标点</button>
<view class="uni-title">
<text class="uni-title-text">方法示例</text>
</View>
<button class="button" @click="handleGetCenterLocation">获取当前地图中心的经纬度</button>
<button class="button" @click="handleGetRegion">获取当前地图的视野范围</button>
<button class="button" @click="handleTranslateMarker">平移marker,带动画</button>
</scroll-view>
</view>
</template>
<script lang="uts">
<script setup lang="uts">
type Anchor = {
x : number,
y : number
......@@ -42,17 +49,17 @@
}
type Markers = {
id : string | number,
id : number,
latitude : number,
longitude : number,
title : string
zIndex : string,
title ?: string
zIndex ?: string,
iconPath : string,
rotate ?: number,
width : number,
height : number,
anchor : Anchor,
callout : Callout
width ?: number,
height ?: number,
anchor ?: Anchor,
callout ?: Callout
}
type Points = {
......@@ -269,169 +276,213 @@
}
];
export default {
data() {
return {
location: {
longitude: 116.3974770000,
latitude: 39.9086920000
},
controls: [{
id: 1,
position: {
left: 5,
top: 180,
width: 30,
height: 30
},
iconPath: '../../../static/uni.png',
clickable: true
}],
showLocation: false,
scale: 13,
showCompass: true,
enable3D: true,
enableOverlooking: true,
enableZoom: true,
enableScroll: true,
enableRotate: true,
enableSatellite: false,
enableTraffic: false,
polyline: [] as Polyline[],
markers: [] as Markers[],
polygons: [] as Polygons[],
circles: [] as Circles[],
includePoints: [] as Points[],
rotate: 0,
skew: 0,
map: null as MapContext | null,
// 自动化测试
autoTest: false,
getCenterLocationTest:{},
getRegionTest:{},
}
},
onReady() {
this.map = uni.createMapContext("map1", this);
},
methods: {
changeScale() {
this.scale = this.scale == 9 ? 15 : 9;
},
enableThreeD(e) {
this.enable3D = e.detail.value;
},
changeShowCompass(e) {
this.showCompass = e.detail.value;
},
changeEnableOverlooking(e) {
this.enableOverlooking = e.detail.value;
},
changeEnableZoom(e) {
this.enableZoom = e.detail.value;
},
changeEnableScroll(e) {
this.enableScroll = e.detail.value;
},
changeEnableRotate(e) {
this.enableRotate = e.detail.value;
},
changeEnableSatellite(e) {
this.enableSatellite = e.detail.value;
},
changeEnableTraffic(e) {
this.enableTraffic = e.detail.value;
},
addMarkers() {
this.markers = testMarkers;
},
addPolyline() {
this.polyline = testPolyline;
},
type ControlsType = {
id?: number;
position: PositionType;
iconPath:string;
clickable?: boolean;
}
addPolygons() {
this.polygons = testPolygons;
},
type PositionType = {
left: number,
top: number,
width: number,
height: number
}
addCircles() {
this.circles = testCircles;
},
includePoint() {
this.includePoints = testIncludePoints;
},
handleGetCenterLocation() {
this.map!.getCenterLocation({
success: ret => {
console.log(JSON.stringify(ret));
this.getCenterLocationTest = ret
if(!this.autoTest){
uni.showModal({
content: JSON.stringify(ret)
})
}
}
})
},
handleGetRegion() {
this.map!.getRegion({
success: ret => {
console.log(JSON.stringify(ret));
this.getRegionTest = ret
if(!this.autoTest){
uni.showModal({
content: JSON.stringify(ret)
})
}
}
})
},
const location = ref({ longitude: 116.39742, latitude: 39.909 });
const controls = ref( []as ControlsType[]);
const showLocation = ref(false);
const scale = ref(13);
const showCompass = ref(true);
const enable3D = ref(true);
const enableOverlooking = ref(true);
const enableZoom = ref(true);
const enableScroll = ref(true);
const enableRotate = ref(true);
const enableSatellite = ref(false);
const enableTraffic = ref(false);
const polyline = ref([] as Polyline[]);
const markers = ref([] as Markers[]);
const polygons = ref([] as Polygons[]);
const circles = ref([] as Circles[]);
const includePoints = ref([] as Points[]);
const rotate = ref(0);
const skew = ref(0);
const map = ref(null as MapContext | null);
const autoTest = ref(false);
const getCenterLocationTest = ref({});
const getRegionTest = ref({});
handleTranslateMarker() {
this.map!.translateMarker({
markerId: 1,
destination: {
latitude: 39.989631,
longitude: 116.481018
},
duration: 2000,
success: ret => {
console.log(JSON.stringify(ret));
}
});
},
maptap(e) {
uni.showModal({
content: JSON.stringify(e)
})
},
onmarkertap(e) {
uni.showModal({
content: JSON.stringify(e)
})
},
oncontroltap(e) {
uni.showModal({
content: JSON.stringify(e)
})
},
oncallouttap(e) {
uni.showModal({
content: JSON.stringify(e)
})
},
onupdated(e) {
console.log(JSON.stringify(e))
},
onregionchange(e) {
console.log(JSON.stringify(e));
onReady(() => {
map.value = uni.createMapContext("map1", getCurrentInstance()!.proxy!)
});
const addControls = () => {
controls.value = [{
id: 1,
position: {
left: 5,
top: 180,
width: 30,
height: 30
},
onpoitap(e) {
uni.showModal({
content: JSON.stringify(e)
})
}
}
iconPath: '../../../static/uni.png',
clickable: true
}]
}
const confirm_scale_input = (value: number) => {
scale.value = value
};
const change_show_location = (checked : boolean)=>{
showLocation.value = checked
}
const enableThreeD = (e)=>{
enable3D.value = e.detail.value;
}
const changeShowCompass = (e)=>{
showCompass.value = e.detail.value;
}
const changeEnableOverlooking = (e) => {
enableOverlooking.value = e.detail.value;
};
const changeEnableZoom = (e) => {
enableZoom.value = e.detail.value;
};
const changeEnableScroll = (e) => {
enableScroll.value = e.detail.value;
};
const changeEnableRotate = (e) => {
enableRotate.value = e.detail.value;
};
const changeEnableSatellite = (e) => {
enableSatellite.value = e.detail.value;
};
const changeEnableTraffic = (e) => {
enableTraffic.value = e.detail.value;
};
const addMarkers = () => {
markers.value = testMarkers;
};
const addPolygons = () => {
polygons.value = testPolygons;
};
const addPolyline = () => {
polyline.value = testPolyline;
};
const addCircles = () => {
circles.value = testCircles;
};
const includePoint = () => {
includePoints.value = testIncludePoints;
};
const handleGetCenterLocation = () => {
if (map.value) {
map.value.getCenterLocation({
success: ret => {
console.log('getCenterLocation',ret);
// console.log(JSON.stringify(ret));
getCenterLocationTest.value = ret;
uni.showModal({
content: JSON.stringify(ret)
});
}
});
}
};
const handleGetRegion = () => {
if (map.value) {
map.value.getRegion({
success: ret => {
console.log(JSON.stringify(ret));
getRegionTest.value = ret;
uni.showModal({
content: JSON.stringify(ret)
});
}
});
}
};
const handleTranslateMarker = () => {
if (map.value) {
map.value.translateMarker({
markerId: 1,
destination: {
latitude: 39.989631,
longitude: 116.481018
},
autoRotate:true,
rotate:10,
duration: 2000,
animationEnd: () => {
console.log('动画结束');
},
success: ret => {
console.log('handleTranslateMarker',JSON.stringify(ret));
},
fail: ret => {
console.log('handleTranslateMarker',JSON.stringify(ret));
}
});
}
};
const maptap = (e) => {
uni.showModal({
content: JSON.stringify(e)
});
};
const onmarkertap = (e:UniEvent) => {
console.log('点击标记点时触发',e)
uni.showModal({
content: JSON.stringify(e)
});
};
const oncontroltap = (e:UniEvent) => {
console.log('点击控件时触发',e)
uni.showModal({
content: JSON.stringify(e)
});
};
const oncallouttap = (e:UniEvent) => {
console.log('点击标记点对应的气泡时触发',e)
uni.showModal({
content: JSON.stringify(e)
});
};
const onupdated = (e:UniEvent) => {
console.log('在地图渲染更新完成时触发',e)
};
const onregionchange = (e:UniEvent) => {
console.log('视野发生变化时触发',e)
};
const onpoitap = (e) => {
uni.showModal({
content: JSON.stringify(e)
});
};
</script>
<style>
......@@ -441,7 +492,7 @@
.map {
width: 100%;
height: 250px;
height: 300px;
background-color: #f0f0f0;
}
......
......@@ -2,7 +2,7 @@
<!-- #ifdef APP -->
<scroll-view class="page-scroll-view">
<!-- #endif -->
<page-head :title="title"></page-head>
<page-head title="video-format"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title">
<text class="uni-title-text">支持的视频格式示例</text>
......@@ -17,7 +17,7 @@
</view>
<view v-for="(item,index) in notSupportFormats" :key="index">
<text class="uni-subtitle-text">{{item.format}}</text>
<video :id="'video-' + item.format" class="video" :src="item.src" :controls="true" :direction="-90"></video>
<video :id="'video-' + item.format" :ref="'videoRef-' + item.format" class="video" :src="item.src" :controls="true" :direction="-90"></video>
</view>
</view>
<!-- #ifdef APP -->
......@@ -25,82 +25,82 @@
<!-- #endif -->
</template>
<script>
<script setup>
type VideoFormat = {
format : string
src : string
}
let supportFormats = ref([
// TODO web本地运行时本地服务返回的content-type不对,导致本地视频无法播放。此外web端原生video不支持flv、m3u8、avi格式,但是和app端相比多了ogg格式的支持
{
format: 'mp4',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.mp4'
},
{
format: 'm4v',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.m4v'
},
{
format: 'mov',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.mov'
},
{
format: 'webm(iOS和Safari不支持)',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.webm'
},
{
format: '3gp',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.3gp'
},
// #ifndef WEB
{
format: 'flv',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.flv'
},
{
format: 'm3u8',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.m3u8'
},
{
format: '本地m3u8',
src: '/static/test-video/2minute-demo.m3u8'
},
// #endif
{
format: '错误路径',
src: 'https://www.dcloud.net.cn/errorpath.mp4'
},
] as Array<VideoFormat>)
export default {
data() {
return {
title: 'video-format',
supportFormats: [
// TODO web本地运行时本地服务返回的content-type不对,导致本地视频无法播放。此外web端原生video不支持flv、m3u8、avi格式,但是和app端相比多了ogg格式的支持
{
format: 'mp4',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.mp4'
},
{
format: 'm4v',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.m4v'
},
{
format: 'mov',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.mov'
},
{
format: 'webm(iOS和Safari不支持)',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.webm'
},
{
format: '3gp',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.3gp'
},
// #ifndef WEB
{
format: 'flv',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.flv'
},
{
format: 'm3u8',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.m3u8'
},
{
format: '本地m3u8',
src: '/static/test-video/2minute-demo.m3u8'
},
// #endif
{
format: '错误路径',
src: 'https://www.dcloud.net.cn/errorpath.mp4'
},
] as Array<VideoFormat>,
notSupportFormats: [
// #ifndef WEB
{
format: 'ogg',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.ogg'
},
// #endif
{
format: 'avi',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.avi'
}
] as Array<VideoFormat>,
// 自动化测试
isError: false
}
let notSupportFormats =ref([
// #ifndef WEB
{
format: 'ogg',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.ogg'
},
methods: {
onError: function (format : string, e : UniVideoErrorEvent) {
console.log(format + ":" + JSON.stringify(e));
if (format != "错误路径") {
this.isError = true;
}
}
// #endif
{
format: 'avi',
src: 'https://qiniu-web-assets.dcloud.net.cn/video/sample/2minute-demo.avi'
}
] as Array<VideoFormat>)
// 自动化测试
const isError = reactive({value: false})
const onError = (format : string, e : UniVideoErrorEvent) => {
console.log(format + ":" + JSON.stringify(e));
if (format != "错误路径") {
isError['value'] = true;
}
}
onReady(() => {
// const v = uni.createVideoContext("video-mp4",getCurrentInstance()!.proxy!)
// v?.play()
})
defineExpose({isError})
</script>
<style>
......
......@@ -214,6 +214,6 @@ describe('component-native-video', () => {
it('test format', async () => {
page = await program.navigateTo('/pages/component/video/video-format');
await page.waitFor(1000);
expect(await page.data('isError')).toBe(false);
expect((await page.data('isError')).value).toBe(false);
});
});
......@@ -90,7 +90,8 @@
import { ItemType } from '@/components/enum-data/enum-data';
export default {
onReady() {
this.videoContext = uni.createVideoContext('video', this);
this.videoContext = uni.createVideoContext('video');
// this.videoContext = uni.createVideoContext('video', this);
},
data() {
return {
......
......@@ -49,6 +49,7 @@
}
},
webviewContext: null as WebviewContext | null,
webviewElement: null as UniWebViewElement | null,
loadError: false,
horizontalScrollBarAccess: true,
verticalScrollBarAccess: true,
......@@ -65,7 +66,10 @@
onReady() {
// #ifdef APP
// TODO web 实现createWebviewContext
this.webviewContext = uni.createWebviewContext('web-view', this)
this.webviewContext = uni.createWebviewContext('web-view',this)
this.webviewElement = uni.getElementById('web-view') as UniWebViewElement //推荐使用element,功能更丰富
// console.log('url: ',this.webviewElement?.getAttribute("src"));
// this.webviewElement?.setAttribute("src","https://ext.dcloud.net.cn/")
// #endif
},
methods: {
......@@ -77,6 +81,7 @@
},
reload() {
this.webviewContext?.reload();
// this.webviewElement?.reload();
},
stop() {
this.webviewContext?.stop();
......
......@@ -82,10 +82,10 @@ const pages = [
// '/pages/component/unicloud-db/unicloud-db/contacts/detail',
'/pages/component/unicloud-db/unicloud-db/mixin-datacom/mixin-datacom',
// 单独测试例截图
// '/pages/component/public-properties/public-properties',
'/pages/component/public-events/public-events',
'/pages/component/public-events/transition-events',
'/pages/component/public-events/touch-events',
// '/pages/component/global-properties/global-properties',
'/pages/component/global-events/global-events',
'/pages/component/global-events/transition-events',
'/pages/component/global-events/touch-events',
// 单独测试例截图
// '/pages/component/nested-scroll-header/nested-scroll-header',
// 单独测试例截图
......@@ -344,7 +344,7 @@ function getWaitForTagName(pagePath) {
return 'video'
}
if (
pagePath === '/pages/component/public-events/transition-events' ||
pagePath === '/pages/component/global-events/transition-events' ||
pagePath === '/pages/component/list-view/list-view-refresh' ||
pagePath === '/pages/API/env/env'
) {
......
......@@ -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"
<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">
......@@ -33,28 +31,37 @@
</uni-collapse-item>
</uni-collapse>
</uni-collapse-item>
</uni-collapse>
</uni-collapse>
<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 -->
<view ref="pop" @click="hidePop()" class="popup">
<view style="width: 90%; background-color: white" @click="stopClickPop">
<api-set-tabbar></api-set-tabbar>
</view>
</view>
</template>
<script lang="uts">
import { generateMenu } from './generateMenu.uts'
import { MenuItem } from './generateMenu.uts'
const menu = generateMenu('pages/API')
const menu = generateMenu('pages/API')
import { state } from '@/store/index.uts'
export default {
data() {
return {
menu: menu as (MenuItem | null)[],
arrowRightIcon: '/static/icons/arrow-right.png',
}
},
computed: {
hasLeftWin():boolean{
return !state.noMatchLeftWindow
},
leftWinActive():string{
return state.leftWinActive.slice(1)
}
},
methods: {
goPage(url : string) {
......@@ -73,7 +80,24 @@
stopClickPop: function (e : PointerEvent) {
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>
......@@ -43,19 +43,45 @@
<script lang="uts">
import { generateMenu } from './generateMenu.uts'
import { MenuItem } from './generateMenu.uts'
const menu = generateMenu('pages/CSS')
const menu = generateMenu('pages/CSS')
import { state } from '@/store/index.uts'
export default {
data() {
return {
menu: menu as (MenuItem | null)[],
arrowRightIcon: '/static/icons/arrow-right.png',
}
},
computed: {
hasLeftWin():boolean{
return !state.noMatchLeftWindow
},
leftWinActive():string{
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 {
......@@ -59,7 +59,15 @@
arrowRightIcon: '/static/icons/arrow-right.png' as string.ImageURIString,
pageHiden: false
}
},
},
computed: {
hasLeftWin():boolean{
return !state.noMatchLeftWindow
},
leftWinActive():string{
return state.leftWinActive.slice(1)
}
},
methods: {
goPage(url : string) {
uni.navigateTo({ url })
......@@ -76,7 +84,24 @@
uni.showTabBar()?.catch(_ => { })
}
// #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,
......@@ -87,7 +87,7 @@ export function generateMenu(tabBarType : string) : (MenuItem | null)[] {
return removeNullItem(res)
}
function hasPageGroup(value : string | null) : boolean {
function hasPageGroup(value ?: string | null) : boolean {
// #ifdef APP-ANDROID
return value !== null
// #endif
......@@ -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>
......@@ -50,11 +50,19 @@
pages : Page[]
url ?: string
enable ?: boolean
}
}
import { state } from '@/store/index.uts'
export default {
data() {
return {
list: [
list: [
{
id: 'slider-100',
url: 'slider-100',
name: 'slider-100',
open: false,
pages: [] as Page[],
},
{
id: 'long-list',
url: 'long-list',
......@@ -103,13 +111,6 @@
},
] as Page[],
},
{
id: 'slider-100',
url: 'slider-100',
name: 'slider-100',
open: false,
pages: [] as Page[],
},
{
id: 'custom-long-list',
url: 'custom-long-list',
......@@ -231,6 +232,14 @@
arrowDownIcon: '/static/icons/arrow-down.png',
arrowRightIcon: '/static/icons/arrow-right.png',
}
},
computed: {
hasLeftWin():boolean{
return !state.noMatchLeftWindow
},
leftWinActive():string{
return state.leftWinActive.split('/')[3]
}
},
methods: {
triggerCollapse(index : number, item : ListItem) {
......@@ -267,6 +276,27 @@
url,
})
},
},
},
// #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>
<template>
<view>
<page-head :title="title"></page-head>
<view class="page-body">
<!-- 如何使用浏览器内置 canvas -->
<view ref="drawing" class="drawing"></view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: '浏览器 canvas',
drawing: null as HTMLElement | null,
canvasElement: null as HTMLCanvasElement | null,
canvasContext: null as CanvasRenderingContext2D | null,
}
},
onReady() {
this.drawing = this.$refs['drawing'] as HTMLElement;
this.canvasElement = document.createElement('canvas') as HTMLCanvasElement;
this.canvasElement!.className = 'canvas'
this.drawing!.appendChild(this.canvasElement)
this.canvasContext = this.canvasElement!.getContext('2d')
this.canvasContext!.fillRect(100, 50, 100, 50)
}
}
</script>
<style>
.drawing>>>.canvas {
width: 300px;
height: 150px;
margin-left: auto;
margin-right: auto;
border: 1px dashed #000;
}
</style>
......@@ -24,17 +24,24 @@ npx husky@9.0.11
#### pages.json
**注意:**\
创建 `component``API``CSS` 示例页面时,如果该示例页面需要在对应 `tabBar` 菜单中展示,`path` 命名需要遵循以下规则:
- pages/component/component-name/component-name
- pages/API/api-name/api-name
- pages/CSS/css-name/css-name
所以,如果是扩展示例,比如针对 `button type 属性` 的示例,`path` 可以是:`pages/component/button/button-type`\
如果想要该示例页面在菜单中显示,则需要调整为:`pages/component/button/button/type`
如果想要该示例页面在菜单中显示,则需要调整为:`pages/component/button/button/type`\
如果 API 示例为多个 API 的组合,此时无法以单一 API 名称命名,可以使用 `pages/API/xxx/xxx` 命名示例页面,但在维护 [syntaxdoc](http://git.dcloud.io/uni-app-x/syntaxdoc) `modules.json` 时,需要通过 `items` 节点关联对应 API 信息。\
增加上述示例页面时,相同类型的页面要放在一起,不要随意放置在最后或最前!
**注意:**增加上述示例页面时,不需要基于平台兼容性补充条件编译,代码提交后,会基于 [syntaxdoc](http://git.dcloud.io/uni-app-x/syntaxdoc) 仓库中的平台兼容性信息,自动生成对应的条件编译代码,并更新 `pages.json`
增加上述示例页面时,不需要基于平台兼容性补充条件编译,代码提交后,会基于 [syntaxdoc](http://git.dcloud.io/uni-app-x/syntaxdoc) 仓库中的平台兼容性信息,自动生成对应的条件编译代码,并更新 `pages.json`
`pages.json` 中增加后页面配置后,需要在 [syntaxdoc](http://git.dcloud.io/uni-app-x/syntaxdoc) 仓库的 `modules.json` 中维护目录信息。
**注意:**调整现有页面的路径或平台兼容性,或移除页面时,如果该页面涉及截图对比测试,需要同时调整 `pages/pages.test.js` 中的页面地址。
如需在本地调试时增加 `tabBar` 页面入口,需要修改 `pages.json``page``group` 信息,格式为使用 `,` 分隔的数字字符串。\
`page.group` 属性中的数字代表该页面在 `pages.json/groups` 中对应位置的下标,
`pages.json/groups` 中维护了基于 `syntaxdoc/modules.json` 获取的目录信息。
调整现有页面的路径或平台兼容性,或移除页面时,如果该页面涉及截图对比测试,需要同时调整 `pages/pages.test.js` 中的页面地址。
export type SafeArea = {
top : number,
right : number,
bottom : number,
left : number,
width : number,
height : number,
}
export type SafeArea = {
top : number,
right : number,
bottom : number,
left : number,
width : number,
height : number,
}
type State = {
lifeCycleNum : number,
// 状态栏高度
......@@ -16,13 +16,21 @@ type State = {
devicePixelRatio : number
// 事件判断回调
eventCallbackNum: number
// 是否匹配左侧窗口
noMatchLeftWindow:boolean
// 当前激活的tab页
active: string
leftWinActive:string
}
export const state = reactive({
lifeCycleNum: 0,
statusBarHeight: 0,
devicePixelRatio: 1,
devicePixelRatio: 1,
eventCallbackNum: 0,
noMatchLeftWindow: true,
active: 'componentPage',
leftWinActive: '/pages/component/global-properties/global-properties',
safeArea: {
top: 0,
right: 0,
......@@ -35,21 +43,33 @@ export const state = reactive({
export const setLifeCycleNum = (num : number) => {
state.lifeCycleNum = num
}
}
export const setEventCallbackNum = (num : number) => {
state.eventCallbackNum = num
}
export const setStatusBarHeight = (height : number) => {
state.statusBarHeight = height
}
}
export const setSafeArea = (value : SafeArea) => {
state.safeArea = value
}
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
}
## 0.8.2(2024-07-15)
- 更新 static 下的静态图片放入 static/app 目录下,防止编译除 app 平台以外的平台时带入
## 0.8.1(2024-04-28)
- 修复 在 HX 4.0.3+ uni-app x 项目运行到 Android 调不起安装的Bug
## 0.8.0(2024-04-15)
......
......@@ -5,7 +5,7 @@
<view class="content-top">
<text class="content-top-text">{{title}}</text>
<image class="content-top-image" mode="widthFix"
src="/uni_modules/uni-upgrade-center-app/static/bg_top.png"></image>
src="/uni_modules/uni-upgrade-center-app/static/app/bg_top.png"></image>
</view>
<view class="content-body">
......@@ -53,7 +53,7 @@
</view>
<view class="content-bottom">
<image v-if="!is_mandatory" class="close-img" mode="widthFix" src="/uni_modules/uni-upgrade-center-app/static/app_update_close.png" @click="closeUpdate">
<image v-if="!is_mandatory" class="close-img" mode="widthFix" src="/uni_modules/uni-upgrade-center-app/static/app/app_update_close.png" @click="closeUpdate">
</image>
</view>
</view>
......
{
"id": "uni-upgrade-center-app",
"displayName": "升级中心 uni-upgrade-center - App",
"version": "0.8.1",
"version": "0.8.2",
"description": "uni升级中心 - 客户端检查更新",
"keywords": [
"uniCloud",
......@@ -48,32 +48,32 @@
"client": {
"App": {
"app-vue": "y",
"app-nvue": "u"
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
"Safari": "n",
"Android Browser": "n",
"微信浏览器(Android)": "n",
"QQ浏览器(Android)": "n"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
"Chrome": "n",
"IE": "n",
"Edge": "n",
"Firefox": "n",
"Safari": "n"
},
"小程序": {
"微信": "u",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"京东": "u"
"微信": "n",
"阿里": "n",
"百度": "n",
"字节跳动": "n",
"QQ": "n",
"京东": "n"
},
"快应用": {
"华为": "u",
"联盟": "u"
"华为": "n",
"联盟": "n"
},
"Vue": {
"vue2": "y",
......
......@@ -3,7 +3,7 @@
<view class="content botton-radius">
<view class="content-top">
<text class="content-top-text">{{title}}</text>
<image class="content-top" style="top: 0;" width="100%" height="100%" src="/uni_modules/uni-upgrade-center-app/static/bg_top.png">
<image class="content-top" style="top: 0;" width="100%" height="100%" src="/uni_modules/uni-upgrade-center-app/static/app/bg_top.png">
</image>
</view>
<view class="content-header"></view>
......@@ -57,7 +57,7 @@
</view>
</view>
<image v-if="!is_mandatory" class="close-img" src="/uni_modules/uni-upgrade-center-app/static/app_update_close.png" @click.stop="closeUpdate">
<image v-if="!is_mandatory" class="close-img" src="/uni_modules/uni-upgrade-center-app/static/app/app_update_close.png" @click.stop="closeUpdate">
</image>
</view>
</view>
......
<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():string{
return state.active
},
hasLeftWin():boolean{
return !state.noMatchLeftWindow
},
leftWinActive():string{
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/global-properties/global-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/global-properties/global-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/global-properties/global-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/global-properties/global-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/global-properties/global-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.
先完成此消息的编辑!
想要评论请 注册