提交 c8d5d47f 编写于 作者: M mehaotian

Merge branch 'alpha' into alpha-stat

......@@ -2,7 +2,7 @@ root = true
[*]
charset = utf-8
end_of_line = lf
end_of_line = auto
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
......
......@@ -29,6 +29,7 @@
} as OnShowOptions
},
onLaunch: function (res : OnLaunchOptions) {
this.globalData.launchOptions = res
// 自动化测试
......@@ -47,15 +48,28 @@
// } as PerformanceObserverOptions)
// 统计上报 - 应用启动
// uni.report({
// name: 'uni-app-launch',
// options: res,
// success(res_data) {
// console.log(res_data);
// }, fail(err_data) {
// console.log(err_data);
// }
// })
uni.report({
name: 'uni-app-launch',
options: res,
success(res_data) {
console.log(res_data);
}, fail(err) {
console.log(err);
}
})
// #ifdef APP
if (process.env.NODE_ENV !== 'development') { //真机运行可以注释此条件
uni.getPrivacySetting({
success(res1){
if(res1.needAuthorization){
uni.openDialogPage({
url: '/pages/component/button/privacy',
})
}
}
})
}
// #endif
},
onShow: function (res : OnShowOptions) {
this.globalData.onShowOption = res
......@@ -73,14 +87,14 @@
console.log('App Show')
// 统计上报 - 应用显示
// uni.report({
// name: 'uni-app-show',
// success(res_data) {
// console.log(res_data);
// }, fail(err_data) {
// console.log(err_data);
// }
// })
uni.report({
name: 'uni-app-show',
success(res_data) {
console.log(res_data);
}, fail(err) {
console.log(err);
}
})
},
onHide: function () {
// 自动化测试
......@@ -119,18 +133,18 @@
onExit() {
console.log('App Exit')
},
// onError(err : any) {
// // 统计上报 - 应用发生错误
// uni.report({
// name: 'uni-app-error',
// options: err,
// success(res) {
// console.log(res);
// }, fail(err) {
// console.log(err);
// }
// })
// },
onError(err : any) {
// 统计上报 - 应用发生错误
uni.report({
name: 'uni-app-error',
options: err,
success(res) {
console.log(res);
}, fail(err) {
console.log(err);
}
})
},
// #endif
methods: {
increasetLifeCycleNum() {
......@@ -182,10 +196,5 @@
.uni-top-window uni-tabbar .uni-tabbar {
background-color: #fff !important;
}
.uni-app--showleftwindow .uni-page-head-btn {
display: none !important;
}
/* #endif */
</style>
## 1.0.32
* update 4.31.2024102414-alpha
## 1.0.31
* update 4.28.2024092105-alpha
## 1.0.30
* update 4.27.2024091308-alpha
......
......@@ -6,6 +6,10 @@
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
},
defaultValue: {
type: Boolean,
default: false
......@@ -32,7 +36,7 @@
<template>
<view class="button-data-main uni-flex">
<view class="uni-title" style="width:80%">{{ title }}</view>
<switch :checked="_checked" @change="_change" />
<switch :checked="_checked" :disabled="disabled" @change="_change" />
</view>
</template>
......
// 仅测试 console.log 时机问题
import './test-main-console.uts'
import { uniStat } from '@/uni_modules/uni-stat/plugin.uts'
import App from './App.uvue'
// 仅测试 console.log 时机问题
import './test-main-console.uts'
import { uniStat } from '@/uni_modules/uni-stat/plugin.uts'
import App from './App.uvue'
import { createSSRApp } from 'vue'
// 统计配置
const collectItems = {
uniStatPageLog: true
}
const statOptions = {
debug: true,
collectItems: collectItems,
}
import { createSSRApp } from 'vue'
// 统计配置
const collectItems = {
uniStatPageLog: true
}
const statOptions = {
debug: false,
collectItems: collectItems,
}
export function createApp() {
const app = createSSRApp(App)
app.use(uniStat, statOptions)
const app = createSSRApp(App)
app.use(uniStat, statOptions)
// app.mixin({
// onReady() {
// setTimeout(() => {
......
......@@ -2,8 +2,8 @@
"name": "Hello uni-app x",
"appid": "__UNI__HelloUniAppX",
"description": "",
"versionName": "1.5",
"versionCode": 10500,
"versionName": "1.6",
"versionCode": 10600,
"uni-app-x": {},
/* 快应用特有相关 */
"quickapp": {},
......
......@@ -2,7 +2,7 @@
"id": "hello-uniapp-x-alpha",
"name": "hello-uniapp-x-alpha",
"displayName": "hello-uniapp-x-alpha",
"version": "1.0.30",
"version": "1.0.32",
"description": "演示 uni-app x 框架的组件、接口、模板",
"scripts": {
"check-commit": "node ./git-hooks/check-commit.cjs"
......
......@@ -297,21 +297,21 @@
},
{
"path": "pages/component/web-view/web-view",
"group": "0,8",
"group": "0,9",
"style": {
"navigationBarTitleText": "web-view"
}
},
{
"path": "pages/component/web-view/web-view/web-view-local",
"group": "0,8",
"group": "0,9",
"style": {
"navigationBarTitleText": "本地网页"
}
},
{
"path": "pages/component/unicloud-db/unicloud-db/contacts/list",
"group": "0,10",
"group": "0,11",
"style": {
"navigationBarTitleText": "联系人",
"enablePullDownRefresh": true
......@@ -337,7 +337,7 @@
},
{
"path": "pages/component/unicloud-db/unicloud-db/mixin-datacom/mixin-datacom",
"group": "0,10",
"group": "0,11",
"style": {
"navigationBarTitleText": "mixinDatacom"
}
......@@ -370,12 +370,12 @@
"navigationBarTitleText": "Touch Events"
}
},
{
"path": "pages/component/global-events/touch-events-bubbles",
"style": {
"navigationBarTitleText": "Touch Events bubbles"
}
},
{
"path": "pages/component/global-events/touch-events-bubbles",
"style": {
"navigationBarTitleText": "Touch Events bubbles"
}
},
// #ifndef WEB
{
"path": "pages/component/nested-scroll-header/nested-scroll-header",
......@@ -428,7 +428,7 @@
}
},
// #endif
// #ifdef WEB
// #ifdef WEB || APP
{
"path": "pages/component/map/map",
"group": "0,6",
......@@ -489,6 +489,34 @@
"navigationBarTitleText": "涂鸦"
}
},
// #ifndef WEB
{
"path": "pages/component/native-view/native-view",
"group": "0,2,4",
"style": {
"navigationBarTitleText": "native-view"
}
},
// #endif
// #ifndef WEB
{
"path": "pages/component/ad/ad",
"group": "0,8",
"style": {
"navigationBarTitleText": "ad | 信息流广告",
"enablePullDownRefresh": false
}
},
// #endif
// #ifndef WEB
{
"path": "pages/component/ad/list-view-ad",
"style": {
"navigationBarTitleText": "ad | 信息流广告",
"enablePullDownRefresh": false
}
},
// #endif
{
"path": "pages/tabBar/API",
"style": {
......@@ -567,14 +595,14 @@
},
{
"path": "pages/API/set-navigation-bar-color/set-navigation-bar-color",
"group": "1,2,1",
"group": "1,2,2",
"style": {
"navigationBarTitleText": "setNavigationBarColor | 设置导航条颜色"
}
},
{
"path": "pages/API/set-navigation-bar-title/set-navigation-bar-title",
"group": "1,2,2",
"group": "1,2,3",
"style": {
"navigationBarTitleText": "setNavigationBarTitle | 设置导航条标题"
}
......@@ -606,7 +634,7 @@
},
{
"path": "pages/API/pull-down-refresh/pull-down-refresh",
"group": "1,2,4",
"group": "1,2,5",
"style": {
"navigationBarTitleText": "pullDownRefresh | 页面下拉刷新",
"enablePullDownRefresh": true
......@@ -899,7 +927,7 @@
},
{
"path": "pages/API/page-scroll-to/page-scroll-to",
"group": "1,2,5",
"group": "1,2,6",
"style": {
"navigationBarTitleText": "pageScrollTo | 将页面滚动到指定位置"
}
......@@ -939,6 +967,13 @@
"navigationBarTitleText": "getWindowInfo | 获取窗口信息"
}
},
{
"path": "pages/API/get-window-info/window-area",
"style": {
"navigationBarTitleText": "window area",
"navigationStyle": "custom"
}
},
// #ifndef WEB
{
"path": "pages/API/element-draw/element-draw",
......@@ -1024,13 +1059,15 @@
"enablePullDownRefresh": false
}
},
{
"path": "pages/API/virtual-payment/virtual-payment-uni-pay",
"style": {
"navigationBarTitleText": "苹果虚拟支付(uni-pay)",
"enablePullDownRefresh": false
}
},
// #endif
// #ifdef APP-IOS
{
"path": "pages/API/virtual-payment/virtual-payment-uni-pay",
"style": {
"navigationBarTitleText": "苹果虚拟支付(uni-pay)",
"enablePullDownRefresh": false
}
},
// #endif
{
"path": "pages/API/request-payment/request-payment/order-detail",
......@@ -1146,8 +1183,14 @@
"navigationBarTitleText": "provider | 服务提供商"
}
},
{
"path": "pages/API/privacy/privacy",
"group": "1,1,8",
"style": {
"navigationBarTitleText": "privacy | 隐私信息授权"
}
},
// #endif
// #ifndef WEB
{
"path": "pages/API/uni-push/uni-push",
"group": "1,15,0",
......@@ -1155,6 +1198,40 @@
"navigationBarTitleText": "推送"
}
},
{
"path": "pages/API/dialog-page/dialog-page",
"group": "1,2,1",
"style": {
"navigationBarTitleText": "dialogPage | 弹框页面"
}
},
{
"path": "pages/API/dialog-page/next-page",
"style": {
"navigationBarTitleText": "dialogNextPage"
}
},
{
"path": "pages/API/dialog-page/dialog-1",
"style": {
"navigationBarTitleText": "dialogPage1"
}
},
{
"path": "pages/API/dialog-page/dialog-2",
"style": {
"navigationBarTitleText": "dialogPage1"
}
},
// #ifndef WEB
{
"path": "pages/API/create-interstitial-ad/create-interstitial-ad",
"group": "1,13,1",
"style": {
"navigationBarTitleText": "createInterstitialAd | 插屏广告",
"enablePullDownRefresh": false
}
},
// #endif
{
"path": "pages/tabBar/CSS",
......@@ -1254,6 +1331,13 @@
"navigationBarTitleText": "border动态修改"
}
},
{
"path": "pages/CSS/border/border-update",
"group": "2,13",
"style": {
"navigationBarTitleText": "border更新样式"
}
},
{
"path": "pages/CSS/box-shadow/box-shadow",
"group": "2,15",
......@@ -1782,15 +1866,37 @@
"navigationBarTitleText": "",
"backgroundColorContent": "#fffae8"
}
},
// #ifdef APP-IOS
{
"path" : "pages/API/event-bus/uts-event-bus",
"style" :
{
"navigationBarTitleText" : ""
}
},
// #endif
// #ifdef APP
{
"path": "pages/component/button/privacy",
"style": {
"navigationBarTitleText": ""
}
}
// #endif
],
"globalStyle": {
// #ifdef APP-ANDROID
"hideStatusBar": false,
"hideBottomNavigationIndicator": false,
// #endif
"pageOrientation": "portrait",
"navigationBarTitleText": "Hello uniapp x",
"navigationBarTextStyle": "@navigationBarTextStyle",
"navigationBarBackgroundColor": "@navigationBarBackgroundColor",
"backgroundColorContent": "@backgroundColorContent",
"backgroundColor": "@backgroundColor"
"backgroundColor": "@backgroundColor",
"backgroundTextStyle": "@backgroundTextStyle"
},
"tabBar": {
"color": "@tabBarColor",
......@@ -1932,6 +2038,10 @@
{
"id": "component.basic-content.progress",
"name": "progress"
},
{
"id": "component.basic-content.native-view",
"name": "native-view"
}
]
},
......@@ -2021,6 +2131,10 @@
"id": "component.canvas",
"name": "画布"
},
{
"id": "component.ad",
"name": "广告"
},
{
"id": "component.web-view",
"name": "网页"
......@@ -2092,7 +2206,12 @@
{
"id": "api.base.provider",
"name": "provider"
}
},
null,
{
"id": "api.base.privacy",
"name": "privacy"
}
]
},
{
......@@ -2103,6 +2222,10 @@
"id": "api.page.navigator",
"name": "navigator"
},
{
"id": "api.page.dialogPage",
"name": "dialogPage"
},
{
"id": "api.page.setNavigationBarColor",
"name": "setNavigationBarColor"
......@@ -2355,6 +2478,10 @@
{
"id": "api.ad.createRewardedVideoAd",
"name": "createRewardedVideoAd"
},
{
"id": "api.ad.createInterstitialAd",
"name": "createInterstitialAd"
}
]
},
......
......@@ -3,8 +3,8 @@
<page-head :title="title"></page-head>
<button @click="startRequestAnimationFrame">requestAnimationFrame</button>
<button @click="stopRequestAnimationFrame">cancelAnimationFrame</button>
<text class="frame-count">FPS: {{FPSString}}</text>
<text class="frame-count">FrameCount: {{testFrameCount}}</text>
<text class="frame-count">FPS: {{FPSString}}</text>
<text class="frame-count">FrameCount: {{testFrameCount}}</text>
<text class="tips">提示: 在当前测试例子中,每增加一次调用 requestAnimationFrame 帧率翻倍,cancelAnimationFrame 后恢复</text>
</view>
</template>
......@@ -14,7 +14,7 @@
data() {
return {
title: 'AnimationFrame',
taskId: 0,
taskId: 0,
FPSString: '- / -ms',
lastTime: 0,
frameCount: 0,
......@@ -29,25 +29,25 @@
methods: {
startRequestAnimationFrame() {
this.taskId = requestAnimationFrame((timestamp : number) => {
this.updateFPS(timestamp)
this.updateFPS(timestamp)
this.testFrameCount++
this.startRequestAnimationFrame()
})
},
stopRequestAnimationFrame() {
cancelAnimationFrame(this.taskId)
this.lastTime = 0
this.frameCount = 0
cancelAnimationFrame(this.taskId)
this.lastTime = 0
this.frameCount = 0
this.FPSString = '- / -ms'
},
updateFPS(timestamp : number) {
this.frameCount++
if (timestamp - this.lastTime >= 1000) {
const timeOfFrame = (1000 / this.frameCount)
this.FPSString = `${this.frameCount} / ${timeOfFrame.toFixed(3)}ms`
this.frameCount = 0
this.lastTime = timestamp
}
},
updateFPS(timestamp : number) {
this.frameCount++
if (timestamp - this.lastTime >= 1000) {
const timeOfFrame = (1000 / this.frameCount)
this.FPSString = `${this.frameCount} / ${timeOfFrame.toFixed(3)}ms`
this.frameCount = 0
this.lastTime = timestamp
}
}
}
}
......@@ -60,11 +60,11 @@
.frame-count {
margin-top: 15px;
}
.tips {
font-size: 12px;
margin-top: 30px;
opacity: 0.7;
}
</style>
.tips {
font-size: 12px;
margin-top: 30px;
opacity: 0.7;
}
</style>
<template>
<!-- #ifdef APP -->
<scroll-view class="page-scroll-view">
<!-- #endif -->
<view>
<page-head :title="title"></page-head>
<view class="uni-common-mt">
<view class="uni-list">
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left uni-label">
图片来源
</view>
<view class="uni-list-cell-right" @click="chooseImageSource">
<text class="click-t">{{sourceType[sourceTypeIndex]}}</text>
</view>
</view>
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left uni-label">
图片质量
</view>
<view class="uni-list-cell-right" @click="chooseImageType">
<text class="click-t">{{sizeType[sizeTypeIndex]}}</text>
</view>
</view>
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left uni-label">
数量限制
</view>
<view class="uni-list-cell-right">
<input class="click-t" :value="countIndex+1" type="number" :maxlength="1" @confirm="chooseImageCount" confirm-type="done" />
</view>
</view>
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left uni-label">
图像裁剪
</view>
<view class="uni-list-cell-right">
<switch :checked="isCrop" @change="switchCrop"></switch>
</view>
</view>
<view ref="cropOptionNode" class="crop-option" :style="{'height':isCrop?'200px':'0px','margin-bottom':isCrop?'11px':'0px'}">
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left item_width">
图片质量(%)
</view>
<view class="uni-list-cell-right">
<input :value="cropPercent" @confirm="cropPercentConfim" type="number" maxlength="-1"/>
</view>
</view>
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left item_width">
裁剪宽度(px)
</view>
<view class="uni-list-cell-right">
<input :value="cropWidth" @confirm="cropWidthConfim" type="number" maxlength="-1"/>
</view>
</view>
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left item_width">
裁剪高度(px)
</view>
<view class="uni-list-cell-right">
<input :value="cropHeight" @confirm="cropHeightConfim" type="number" maxlength="-1"/>
</view>
</view>
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left item_width">
保留原宽高
</view>
<view class="uni-list-cell-right">
<switch :checked="cropResize" @change="cropResizeChange"></switch>
</view>
</view>
</view>
</view>
<view class="uni-list list-pd" style="padding: 15px;">
<view class="uni-flex" style="margin-bottom: 10px;">
<view class="uni-list-cell-left">点击可预览选好的图片</view>
<view style="margin-left: auto;">
<text class="click-t">{{imageList.length}}/{{countIndex+1}}</text>
</view>
</view>
<view class="uni-flex" style="flex-wrap: wrap;">
<view v-for="(image,index) in imageList" :key="index" class="uni-uploader__input-box" style="border: 0;">
<image style="width: 104px; height: 104px;" :src="image" :data-src="image" @tap="previewImage(index)">
</image>
<image src="/static/plus.png" class="image-remove" @click="removeImage(index)"></image>
</view>
<image class="uni-uploader__input-box" @tap="chooseImage" src="/static/plus.png"></image>
</view>
</view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
var sourceTypeArray = [
['camera'],
['album'],
['camera', 'album']
]
var sizeTypeArray = [
['compressed'],
['original'],
['compressed', 'original']
]
export default {
data() {
return {
title: 'chooseImage',
imageList: [] as Array<string>,
sourceTypeIndex: 2,
sourceType: ['拍照', '相册', '拍照或相册'],
sizeTypeIndex: 2,
sizeType: ['压缩', '原图', '压缩或原图'],
countIndex: 8,
count: [1, 2, 3, 4, 5, 6, 7, 8, 9],
isCrop: false,
cropPercent: 80,
cropWidth: 100,
cropHeight: 100,
cropResize: false
}
},
onUnload() {
this.imageList = [];
this.sourceTypeIndex = 2
this.sourceType = ['拍照', '相册', '拍照或相册']
this.sizeTypeIndex = 2
this.sizeType = ['压缩', '原图', '压缩或原图']
this.countIndex = 8
},
methods: {
cropHeightConfim(e : InputConfirmEvent) {
let value = parseInt(e.detail.value)
if (value > 0) {
this.cropHeight = value
} else {
uni.showToast({
position: "bottom",
title: "裁剪高度需要大于0"
})
}
},
cropWidthConfim(e : InputConfirmEvent) {
let value = parseInt(e.detail.value)
if (value > 0) {
this.cropWidth = value
} else {
uni.showToast({
position: "bottom",
title: "裁剪宽度需要大于0"
})
}
},
cropPercentConfim(e : InputConfirmEvent) {
let value = parseInt(e.detail.value)
if (value > 0 && value <= 100) {
this.cropPercent = value
} else {
uni.showToast({
position: "bottom",
title: "请输入0~100之间的值"
})
}
},
cropResizeChange(e : UniSwitchChangeEvent) {
this.cropResize = e.detail.value
},
switchCrop(e : UniSwitchChangeEvent) {
this.isCrop = e.detail.value
},
removeImage(index : number) {
this.imageList.splice(index, 1)
},
chooseImageSource() {
uni.showActionSheet({
itemList: ['拍照', '相册', '拍照或相册'],
success: (e) => {
this.sourceTypeIndex = e.tapIndex!
}
})
},
chooseImageType() {
uni.showActionSheet({
itemList: ['压缩', '原图', '压缩或原图'],
success: (e) => {
this.sizeTypeIndex = e.tapIndex!
}
})
},
chooseImageCount(event : InputConfirmEvent) {
let count = parseInt(event.detail.value) - 1
if (count < 0) {
uni.showToast({
position: "bottom",
title: "图片数量应该大于0"
})
return
}
this.countIndex = count
},
chooseImage: function () {
// var cropOption:ChooseImageCropOptions|null = this.isCrop ? null : new ChooseImageCropOptions( )
if (this.imageList.length >= 9) {
uni.showToast({
position: "bottom",
title: "已经有9张图片了,请删除部分图片之后重新选择"
})
return
}
uni.chooseImage({
sourceType: sourceTypeArray[this.sourceTypeIndex],
sizeType: sizeTypeArray[this.sizeTypeIndex],
crop: this.isCrop ? { "quality": this.cropPercent, "width": this.cropWidth, "height": this.cropHeight, "resize": this.cropResize } as ChooseImageCropOptions : null,
count: this.imageList.length + this.count[this.countIndex] > 9 ? 9 - this.imageList.length : this.count[this.countIndex],
success: (res) => {
this.imageList = this.imageList.concat(res.tempFilePaths);
},
fail: (err) => {
console.log("err: ", JSON.stringify(err));
}
})
},
previewImage: function (index : number) {
uni.previewImage({
current: index,
urls: this.imageList
})
}
}
}
</script>
<style>
.cell-pd {
padding: 11px 15px;
}
.click-t {
color: darkgray;
}
.list-pd {
margin-top: 25px;
}
.uni-uploader__input-box {
margin: 5px;
width: 104px;
height: 104px;
border: 1px solid #D9D9D9;
}
.uni-uploader__input {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.image-remove {
transform: rotate(45deg);
width: 25px;
height: 25px;
position: absolute;
top: 0;
right: 0;
border-radius: 13px;
background-color: rgba(200, 200, 200, 0.8);
}
.item_width {
width: 130px;
}
.crop-option {
margin-left: 11px;
margin-right: 11px;
border-radius: 11px;
background-color: #eee;
transition-property: height, margin-bottom;
transition-duration: 200ms;
}
<template>
<!-- #ifdef APP -->
<scroll-view class="page-scroll-view">
<!-- #endif -->
<view>
<page-head :title="title"></page-head>
<view class="uni-common-mt">
<view class="uni-list">
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left uni-label">
图片来源
</view>
<view class="uni-list-cell-right" @click="chooseImageSource">
<text class="click-t">{{sourceType[sourceTypeIndex]}}</text>
</view>
</view>
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left uni-label">
图片质量
</view>
<view class="uni-list-cell-right" @click="chooseImageType">
<text class="click-t">{{sizeType[sizeTypeIndex]}}</text>
</view>
</view>
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left uni-label">
数量限制
</view>
<view class="uni-list-cell-right">
<input class="click-t" :value="countIndex+1" type="number" :maxlength="1" @confirm="chooseImageCount"
confirm-type="done" />
</view>
</view>
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left uni-label">
图像裁剪
</view>
<view class="uni-list-cell-right">
<switch :checked="isCrop" @change="switchCrop"></switch>
</view>
</view>
<view ref="cropOptionNode" class="crop-option"
:style="{'height':isCrop?'200px':'0px','margin-bottom':isCrop?'11px':'0px'}">
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left item_width">
图片质量(%)
</view>
<view class="uni-list-cell-right">
<input :value="cropPercent" @confirm="cropPercentConfim" type="number" maxlength="-1" />
</view>
</view>
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left item_width">
裁剪宽度(px)
</view>
<view class="uni-list-cell-right">
<input :value="cropWidth" @confirm="cropWidthConfim" type="number" maxlength="-1" />
</view>
</view>
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left item_width">
裁剪高度(px)
</view>
<view class="uni-list-cell-right">
<input :value="cropHeight" @confirm="cropHeightConfim" type="number" maxlength="-1" />
</view>
</view>
<view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left item_width">
保留原宽高
</view>
<view class="uni-list-cell-right">
<switch :checked="cropResize" @change="cropResizeChange"></switch>
</view>
</view>
</view>
</view>
<view class="uni-list list-pd" style="padding: 15px;">
<view class="uni-flex" style="margin-bottom: 10px;">
<view class="uni-list-cell-left">点击可预览选好的图片</view>
<view style="margin-left: auto;">
<text class="click-t">{{imageList.length}}/{{countIndex+1}}</text>
</view>
</view>
<view class="uni-flex" style="flex-wrap: wrap;">
<view v-for="(image,index) in imageList" :key="index" class="uni-uploader__input-box" style="border: 0;">
<image style="width: 104px; height: 104px;" :src="image" :data-src="image" @tap="previewImage(index)">
</image>
<image src="/static/plus.png" class="image-remove" @click="removeImage(index)"></image>
</view>
<image class="uni-uploader__input-box" @tap="chooseImage" src="/static/plus.png"></image>
</view>
</view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
var sourceTypeArray = [
['camera'],
['album'],
['camera', 'album']
]
var sizeTypeArray = [
['compressed'],
['original'],
['compressed', 'original']
]
export default {
data() {
return {
title: 'chooseImage',
imageList: [] as Array<string>,
sourceTypeIndex: 2,
sourceType: ['拍照', '相册', '拍照或相册'],
sizeTypeIndex: 2,
sizeType: ['压缩', '原图', '压缩或原图'],
countIndex: 8,
count: [1, 2, 3, 4, 5, 6, 7, 8, 9],
isCrop: false,
cropPercent: 80,
cropWidth: 100,
cropHeight: 100,
cropResize: false
}
},
onUnload() {
this.imageList = [];
this.sourceTypeIndex = 2
this.sourceType = ['拍照', '相册', '拍照或相册']
this.sizeTypeIndex = 2
this.sizeType = ['压缩', '原图', '压缩或原图']
this.countIndex = 8
},
methods: {
cropHeightConfim(e : InputConfirmEvent) {
let value = parseInt(e.detail.value)
if (value > 0) {
this.cropHeight = value
} else {
uni.showToast({
position: "bottom",
title: "裁剪高度需要大于0"
})
}
},
cropWidthConfim(e : InputConfirmEvent) {
let value = parseInt(e.detail.value)
if (value > 0) {
this.cropWidth = value
} else {
uni.showToast({
position: "bottom",
title: "裁剪宽度需要大于0"
})
}
},
cropPercentConfim(e : InputConfirmEvent) {
let value = parseInt(e.detail.value)
if (value > 0 && value <= 100) {
this.cropPercent = value
} else {
uni.showToast({
position: "bottom",
title: "请输入0~100之间的值"
})
}
},
cropResizeChange(e : UniSwitchChangeEvent) {
this.cropResize = e.detail.value
},
switchCrop(e : UniSwitchChangeEvent) {
this.isCrop = e.detail.value
},
removeImage(index : number) {
this.imageList.splice(index, 1)
},
chooseImageSource() {
uni.showActionSheet({
itemList: ['拍照', '相册', '拍照或相册'],
success: (e) => {
this.sourceTypeIndex = e.tapIndex!
}
})
},
chooseImageType() {
uni.showActionSheet({
itemList: ['压缩', '原图', '压缩或原图'],
success: (e) => {
this.sizeTypeIndex = e.tapIndex!
}
})
},
chooseImageCount(event : InputConfirmEvent) {
let count = parseInt(event.detail.value) - 1
if (count < 0) {
uni.showToast({
position: "bottom",
title: "图片数量应该大于0"
})
return
}
this.countIndex = count
},
chooseImage: function () {
// var cropOption:ChooseImageCropOptions|null = this.isCrop ? null : new ChooseImageCropOptions( )
if (this.imageList.length >= 9) {
uni.showToast({
position: "bottom",
title: "已经有9张图片了,请删除部分图片之后重新选择"
})
return
}
uni.chooseImage({
sourceType: sourceTypeArray[this.sourceTypeIndex],
sizeType: sizeTypeArray[this.sizeTypeIndex],
crop: this.isCrop ? { "quality": this.cropPercent, "width": this.cropWidth, "height": this.cropHeight, "resize": this.cropResize } as ChooseImageCropOptions : null,
count: this.imageList.length + this.count[this.countIndex] > 9 ? 9 - this.imageList.length : this.count[this.countIndex],
success: (res) => {
this.imageList = this.imageList.concat(res.tempFilePaths);
},
fail: (err) => {
console.log("err: ", JSON.stringify(err));
}
})
},
previewImage: function (index : number) {
uni.previewImage({
current: index,
urls: this.imageList
})
}
}
}
</script>
<style>
.cell-pd {
padding: 11px 15px;
}
.click-t {
color: darkgray;
}
.list-pd {
margin-top: 25px;
}
.uni-uploader__input-box {
margin: 5px;
width: 104px;
height: 104px;
border: 1px solid #D9D9D9;
}
.uni-uploader__input {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.image-remove {
transform: rotate(45deg);
width: 25px;
height: 25px;
position: absolute;
top: 0;
right: 0;
border-radius: 13px;
background-color: rgba(200, 200, 200, 0.8);
}
.item_width {
width: 130px;
}
.crop-option {
margin-left: 11px;
margin-right: 11px;
border-radius: 11px;
background-color: #eee;
transition-property: height, margin-bottom;
transition-duration: 200ms;
}
</style>
......@@ -26,7 +26,7 @@
</view>
</template>
<script lang="uts">
function formatLocation (longitude, latitude) {
function formatLocation(longitude, latitude) {
if (typeof longitude === 'string' && typeof latitude === 'string') {
longitude = parseFloat(longitude)
latitude = parseFloat(latitude)
......@@ -39,7 +39,7 @@
}
}
export default {
data () {
data() {
return {
title: 'chooseLocation',
hasLocation: false,
......
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<view class="uni-title">请输入剪贴板内容</view>
<view class="uni-list">
<view class="uni-list-cell">
<input class="uni-input" type="text" placeholder="请输入剪贴板内容" :value="data" @input="dataChange"/>
</view>
</view>
<view class="uni-btn-v">
<button type="primary" @click="setClipboard">存储数据</button>
<button @tap="getClipboard">读取数据</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'get/setClipboardData',
data: '',
// 自动化测试
getDataTest:'',
setClipboardTest: false
}
},
methods: {
dataChange: function (e) {
this.data = e.detail.value
},
getClipboard: function () {
uni.getClipboardData({
success: (res) => {
console.log(res.data);
this.getDataTest = res.data;
const content = res.data ? '剪贴板内容为:' + res.data : '剪贴板暂无内容';
uni.showModal({
content,
title: '读取剪贴板',
showCancel: false
})
},
fail: () => {
uni.showModal({
content: '读取剪贴板失败!',
showCancel: false
})
}
});
},
setClipboard: function () {
if (this.data.length === 0) {
uni.showModal({
title: '设置剪贴板失败',
content: '内容不能为空',
showCancel: false
})
} else {
uni.setClipboardData({
data: this.data,
success: () => {
this.setClipboardTest = true
// 成功处理
uni.showToast({
title: '设置剪贴板成功',
icon: "success",
mask: !1
})
},
fail: () => {
// bug:自动化测试时设置成功也进入了fail
this.setClipboardTest = false
// 失败处理
uni.showToast({
title: '储存数据失败!',
icon: "none",
mask: !1
})
}
});
}
}
}
}
</script>
<style>
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<view class="uni-title">请输入剪贴板内容</view>
<view class="uni-list">
<view class="uni-list-cell">
<input class="uni-input" type="text" placeholder="请输入剪贴板内容" :value="data" @input="dataChange" />
</view>
</view>
<view class="uni-btn-v">
<button type="primary" @click="setClipboard">存储数据</button>
<button @tap="getClipboard">读取数据</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'get/setClipboardData',
data: '',
// 自动化测试
getDataTest: '',
setClipboardTest: false
}
},
methods: {
dataChange: function (e) {
this.data = e.detail.value
},
getClipboard: function () {
uni.getClipboardData({
success: (res) => {
console.log(res.data);
this.getDataTest = res.data;
const content = res.data ? '剪贴板内容为:' + res.data : '剪贴板暂无内容';
uni.showModal({
content,
title: '读取剪贴板',
showCancel: false
})
},
fail: () => {
uni.showModal({
content: '读取剪贴板失败!',
showCancel: false
})
}
});
},
setClipboard: function () {
if (this.data.length === 0) {
uni.showModal({
title: '设置剪贴板失败',
content: '内容不能为空',
showCancel: false
})
} else {
uni.setClipboardData({
data: this.data,
success: () => {
this.setClipboardTest = true
// 成功处理
uni.showToast({
title: '设置剪贴板成功',
icon: "success",
mask: !1
})
},
fail: () => {
// bug:自动化测试时设置成功也进入了fail
this.setClipboardTest = false
// 失败处理
uni.showToast({
title: '储存数据失败!',
icon: "none",
mask: !1
})
}
});
}
}
}
}
</script>
<style>
</style>
<template>
<!-- #ifdef APP -->
<scroll-view class="page-scroll-view">
<!-- #endif -->
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-btn-v uni-common-mt">
<button type="primary" @click="uploadFile">选择文件上传</button>
<button type="primary" @click="chooseAndUploadFile">一个接口选择文件并上传</button>
</view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
export default {
data() {
return {
title: '云存储'
}
},
onLoad() {
},
onUnload() {
},
methods: {
uploadFile: function () {
uni.chooseImage({
count: 1,
success(res) : void {
uni.showLoading({
title: '上传中...'
})
const tempFilePath = res.tempFilePaths[0]
uniCloud.uploadFile({
filePath: tempFilePath,
cloudPath: 'test.jpg'
})
.then(function (res) {
uni.hideLoading()
console.log(res)
uni.showModal({
content: '上传成功',
showCancel: false
});
})
.catch(function (err : any | null) {
uni.hideLoading()
const error = err as UniCloudError
uni.showModal({
content: '上传失败,' + error.errMsg,
showCancel: false
});
})
// .finally((_: number) : void => {
// uni.hideLoading()
// })
},
fail(err) : void {
console.error('chooseImage fail: ', err)
}
})
},
chooseAndUploadFile() {
uniCloud.chooseAndUploadFile({
type: 'image'
}).then(function (res) {
uni.hideLoading()
console.log(res)
uni.showModal({
content: '上传成功',
showCancel: false
});
})
.catch(function (err : any | null) {
uni.hideLoading()
const error = err as UniCloudError
uni.showModal({
content: '上传失败,' + error.errMsg,
showCancel: false
});
})
}
}
}
</script>
<style>
<template>
<!-- #ifdef APP -->
<scroll-view class="page-scroll-view">
<!-- #endif -->
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-btn-v uni-common-mt">
<button type="primary" @click="uploadFile">选择文件上传</button>
<button type="primary" @click="chooseAndUploadFile">一个接口选择文件并上传</button>
</view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
export default {
data() {
return {
title: '云存储'
}
},
onLoad() {
},
onUnload() {
},
methods: {
uploadFile: function () {
uni.chooseImage({
count: 1,
success(res) : void {
uni.showLoading({
title: '上传中...'
})
const tempFilePath = res.tempFilePaths[0]
uniCloud.uploadFile({
filePath: tempFilePath,
cloudPath: 'test.jpg'
})
.then(function (res) {
uni.hideLoading()
console.log(res)
uni.showModal({
content: '上传成功',
showCancel: false
});
})
.catch(function (err : any | null) {
uni.hideLoading()
const error = err as UniCloudError
uni.showModal({
content: '上传失败,' + error.errMsg,
showCancel: false
});
})
// .finally((_: number) : void => {
// uni.hideLoading()
// })
},
fail(err) : void {
console.error('chooseImage fail: ', err)
}
})
},
chooseAndUploadFile() {
uniCloud.chooseAndUploadFile({
type: 'image'
}).then(function (res) {
uni.hideLoading()
console.log(res)
uni.showModal({
content: '上传成功',
showCancel: false
});
})
.catch(function (err : any | null) {
uni.hideLoading()
const error = err as UniCloudError
uni.showModal({
content: '上传失败,' + error.errMsg,
showCancel: false
});
})
}
}
}
</script>
<style>
</style>
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<view class="uni-hello-text uni-center" style="padding-bottom:50rpx;">
旋转手机即可获取方位信息
</view>
<view class="direction">
<view class="bg-compass-line"></view>
<image class="bg-compass" src="../../../static/compass.png" :style="'transform: rotate('+direction+'deg)'"></image>
<view class="direction-value">
<text>{{direction}}</text>
<text class="direction-degree">o</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'onCompassChange',
direction: 0
}
},
onReady: function () {
uni.onCompassChange((res) => {
console.log('onCompassChange', res)
this.direction = res.direction
})
},
onUnload() {
uni.stopCompass();
this.direction = 0;
}
}
</script>
<style>
.direction {
position: relative;
margin-top: 70rpx;
display: flex;
width: 540rpx;
height: 540rpx;
align-items: center;
justify-content: center;
margin:0 auto;
}
.direction-value {
position: relative;
font-size: 200rpx;
color: #353535;
line-height: 1;
z-index: 1;
}
.direction-degree {
position: absolute;
top: 0;
right: -40rpx;
font-size: 60rpx;
}
.bg-compass {
position: absolute;
top: 0;
left: 0;
width: 540rpx;
height: 540rpx;
transition: .1s;
}
.bg-compass-line {
position: absolute;
left: 267rpx;
top: -10rpx;
width: 6rpx;
height: 56rpx;
background-color: #1AAD19;
border-radius: 999rpx;
z-index: 1;
}
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<view class="uni-hello-text uni-center" style="padding-bottom:50rpx;">
旋转手机即可获取方位信息
</view>
<view class="direction">
<view class="bg-compass-line"></view>
<image class="bg-compass" src="../../../static/compass.png" :style="'transform: rotate('+direction+'deg)'">
</image>
<view class="direction-value">
<text>{{direction}}</text>
<text class="direction-degree">o</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'onCompassChange',
direction: 0
}
},
onReady: function () {
uni.onCompassChange((res) => {
console.log('onCompassChange', res)
this.direction = res.direction
})
},
onUnload() {
uni.stopCompass();
this.direction = 0;
}
}
</script>
<style>
.direction {
position: relative;
margin-top: 70rpx;
display: flex;
width: 540rpx;
height: 540rpx;
align-items: center;
justify-content: center;
margin: 0 auto;
}
.direction-value {
position: relative;
font-size: 200rpx;
color: #353535;
line-height: 1;
z-index: 1;
}
.direction-degree {
position: absolute;
top: 0;
right: -40rpx;
font-size: 60rpx;
}
.bg-compass {
position: absolute;
top: 0;
left: 0;
width: 540rpx;
height: 540rpx;
transition: .1s;
}
.bg-compass-line {
position: absolute;
left: 267rpx;
top: -10rpx;
width: 6rpx;
height: 56rpx;
background-color: #1AAD19;
border-radius: 999rpx;
z-index: 1;
}
</style>
......@@ -50,8 +50,6 @@
quality: 80,
compressedWidth: null as number | null,
compressedHeight: null as number | null,
width: "auto",
height: "auto",
rotate: 0,
// 自动化测试
imageInfoForTest: null,
......@@ -75,8 +73,6 @@
quality: this.quality,
compressedWidth: this.compressedWidth,
compressedHeight: this.compressedHeight,
width: this.width,
height: this.height,
rotate: this.rotate,
success: (res) => {
console.log("compressImage success", JSON.stringify(res));
......@@ -137,12 +133,6 @@
onCompressedHeightConfirm(value : string) {
this.compressedHeight = parseInt(value);
},
onWidthConfirm(value : string) {
this.width = value;
},
onHeightConfirm(value : string) {
this.height = value;
},
onRotateConfirm(value : number) {
this.rotate = value;
},
......
......@@ -10,45 +10,42 @@ describe('inner-audio', () => {
await page.waitFor('view');
});
function getData(key = '') {
return new Promise(async (resolve, reject) => {
const data = await page.data()
resolve(key ? data[key] : data)
})
}
it('onCanplay',async()=>{
await page.waitFor(1000)
await page.waitFor(async()=>{
return await getData('isCanplay')
return await page.data('isCanplay')
})
expect(await getData('buffered')).toBeGreaterThan(0)
expect(await page.data('buffered')).toBeGreaterThan(0)
})
it('play-onPlay-onTimeUpdate', async () => {
await page.callMethod('play')
await page.waitFor(3000);
expect(await getData('isPlaying')).toBeTruthy()
console.log("duration:",await getData('duration'),"currentTime:",await getData('currentTime'))
expect(await getData('duration')).toBeCloseTo(175.109, 0);
// console.log("isPaused",await getData('isPaused'))
// expect(await getData('currentTime')).toBeGreaterThan(0);
// expect(await getData('isPaused')).toBeFalsy();
const waitTime = process.env.uniTestPlatformInfo.includes('chrome') ? 5000:3000
await page.waitFor(waitTime)
expect(await page.data('isPlaying')).toBeTruthy()
console.log("duration:",await page.data('duration'),"currentTime:",await page.data('currentTime'))
expect(await page.data('duration')).toBeCloseTo(175.109, 0);
// console.log("isPaused",await page.data('isPaused'))
// expect(await page.data('currentTime')).toBeGreaterThan(0);
// expect(await page.data('isPaused')).toBeFalsy();
});
it('seek-onSeeking-onSeeked', async () => {
await page.callMethod('onchange',20)
await page.waitFor(500);
expect(await getData('onSeekingTest')).toBeTruthy();
// expect(await getData('onWaitingTest')).toBeTruthy();
expect(await getData('onSeekedTest')).toBeTruthy();
const waitTime = process.env.uniTestPlatformInfo.includes('chrome') ? 1500:500
await page.waitFor(waitTime)
console.log("seek-onSeeking-onSeeked:",await page.data())
expect(await page.data('onSeekingTest')).toBeTruthy();
// expect(await page.data('onWaitingTest')).toBeTruthy();
// expect(await page.data('onSeekedTest')).toBeTruthy();
expect(await program.screenshot()).toSaveImageSnapshot();
});
it('pause-onPause', async () => {
await page.callMethod('pause')
await page.waitFor(500);
expect(await getData('isPlaying')).toBeFalsy()
// expect(await getData('isPaused')).toBeTruthy();
expect(await page.data('isPlaying')).toBeFalsy()
// expect(await page.data('isPaused')).toBeTruthy();
});
it('stop-onStop', async () => {
......@@ -58,8 +55,8 @@ describe('inner-audio', () => {
await page.callMethod('stop')
await page.callMethod('stop')
await page.waitFor(1000);
expect(await getData('isPlaying')).toBeFalsy()
// expect(await getData('isPaused')).toBeTruthy();
expect(await page.data('isPlaying')).toBeFalsy()
// expect(await page.data('isPaused')).toBeTruthy();
});
it('onEnded', async () => {
......@@ -67,7 +64,7 @@ describe('inner-audio', () => {
await page.waitFor(500);
await page.callMethod('play')
await page.waitFor(3000);
// expect(await getData('isPlayEnd')).toBeTruthy();
// expect(await page.data('isPlayEnd')).toBeTruthy();
});
});
......@@ -58,9 +58,9 @@
_isChanging: false,
_audioContext: null as InnerAudioContext | null,
// 自动化测试
onSeekingTest:false,
onSeekedTest:false,
onWaitingTest:false
onSeekingTest: false,
onSeekedTest: false,
onWaitingTest: false
}
},
computed: {
......@@ -129,7 +129,7 @@
}
this._audioContext!.onPlay(() => {
this.isPaused = false;
console.log('开始播放',this.isPaused);
console.log('开始播放', this.isPaused);
});
this.onTimeUpdate()
this.onWaiting()
......@@ -159,6 +159,7 @@
// console.log('onTimeUpdate:音频播放进度更新事件,currentTime',this._audioContext!.currentTime);
if (this._isChanging === true) { return; }
this.currentTime = this._audioContext!.currentTime || 0;
console.log('currentTime', this.currentTime);
if (this.currentTime > this.buffered) {
console.log('缓冲不足');
}
......@@ -208,7 +209,7 @@
console.log('音频停止事件');
});
this.isPlaying = false;
console.log('stop',this.isPaused);
console.log('stop', this.isPaused);
}
}
}
......
<template>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title">
<text class="uni-title-text">支持的音频格式示例</text>
</view>
<view class="formats" v-for="(item,index) in supportFormats" :key="index">
<text class="uni-subtitle-text">{{item.format}}</text>
<image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'" @click="play(item.src,index)"></image>
</view>
<view class="uni-title">
<text class="uni-title-text">不支持的音频格式</text>
</view>
<view class="formats" v-for="(item,index) in notSupportFormats" :key="index">
<text class="uni-subtitle-text">{{item.format}}</text>
<image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'" @click="play(item.src,index)"></image>
</view>
</view>
</template>
<script>
type AudioFormat = {
format : string
src : string
}
export default {
data() {
return {
title: 'audio-format',
playIndex:0,
isPlaying: false,
_audioContext: null as InnerAudioContext | null,
supportFormats: [
{
format: 'mp3',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp3'
},
{
format: 'mp4',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp4'
},
{
format: 'm4a',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.m4a'
},
{
format: 'aac',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.aac'
},
{
format: 'flac',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.flac'
},
{
format: 'ogg',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.ogg'
},
{
format: 'wav',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wav'
},
] as Array<AudioFormat>,
notSupportFormats:[
{
format: 'wma',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wma'
},
{
format: 'aiff',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.aiff'
},
{
format: 'caf',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.caf'
},
{
format: '错误格式',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wmaa'
},
] as Array<AudioFormat>
}
},
onReady() {
this._audioContext = uni.createInnerAudioContext();
},
onUnload() {
if (this._audioContext != null) {
this.pause();
this._audioContext!.destroy()
}
},
methods: {
pause() {
this._audioContext!.pause();
this.isPlaying = false;
},
play(audioUrl,index){
// console.log(index,audioUrl);
if (this.isPlaying && this.playIndex == index) {
this.pause();
return;
}
this.playIndex = index
this._audioContext!.src = audioUrl;
this._audioContext!.play();
this.isPlaying = true;
this._audioContext!.onPlay(() => {
console.log('开始播放');
});
this._audioContext!.onEnded(() => {
console.log('播放结束');
this.isPlaying = false;
});
this._audioContext!.onError((err) => {
this.isPlaying = false;
console.log('err',err);
});
},
},
}
</script>
<style>
.formats{
align-items: center;
}
.icon-play {
width: 60px;
height: 60px;
margin: 10px;
}
<template>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title">
<text class="uni-title-text">支持的音频格式示例</text>
</view>
<view class="formats" v-for="(item,index) in supportFormats" :key="index">
<text class="uni-subtitle-text">{{item.format}}</text>
<image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'"
@click="play(item.src,index)"></image>
</view>
<view class="uni-title">
<text class="uni-title-text">不支持的音频格式</text>
</view>
<view class="formats" v-for="(item,index) in notSupportFormats" :key="index">
<text class="uni-subtitle-text">{{item.format}}</text>
<image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'"
@click="play(item.src,index)"></image>
</view>
</view>
</template>
<script>
type AudioFormat = {
format : string
src : string
}
export default {
data() {
return {
title: 'audio-format',
playIndex: 0,
isPlaying: false,
_audioContext: null as InnerAudioContext | null,
supportFormats: [
{
format: 'mp3',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp3'
},
{
format: 'mp4',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp4'
},
{
format: 'm4a',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.m4a'
},
{
format: 'aac',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.aac'
},
{
format: 'flac',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.flac'
},
{
format: 'ogg',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.ogg'
},
{
format: 'wav',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wav'
},
] as Array<AudioFormat>,
notSupportFormats: [
{
format: 'wma',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wma'
},
{
format: 'aiff',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.aiff'
},
{
format: 'caf',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.caf'
},
{
format: '错误格式',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wmaa'
},
] as Array<AudioFormat>
}
},
onReady() {
this._audioContext = uni.createInnerAudioContext();
},
onUnload() {
if (this._audioContext != null) {
this.pause();
this._audioContext!.destroy()
}
},
methods: {
pause() {
this._audioContext!.pause();
this.isPlaying = false;
},
play(audioUrl, index) {
// console.log(index,audioUrl);
if (this.isPlaying && this.playIndex == index) {
this.pause();
return;
}
this.playIndex = index
this._audioContext!.src = audioUrl;
this._audioContext!.play();
this.isPlaying = true;
this._audioContext!.onPlay(() => {
console.log('开始播放');
});
this._audioContext!.onEnded(() => {
console.log('播放结束');
this.isPlaying = false;
});
this._audioContext!.onError((err) => {
this.isPlaying = false;
console.log('err', err);
});
},
},
}
</script>
<style>
.formats {
align-items: center;
}
.icon-play {
width: 60px;
height: 60px;
margin: 10px;
}
</style>
<template>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title">
<text class="uni-title-text">音频路径示例</text>
</view>
<view class="formats" v-for="(item,index) in supportPaths" :key="index">
<text class="uni-subtitle-text">{{item.description}}</text>
<image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'" @click="play(item.src,index)"></image>
</view>
</view>
</template>
<script>
type AudioPath = {
description : string
src : string
}
export default {
data() {
return {
title: 'audio-path',
playIndex:0,
isPlaying: false,
_audioContext: null as InnerAudioContext | null,
supportPaths: [
{
description: '本地路径:/static方式',
src: '/static/test-audio/ForElise.mp3'
},
{
description: '本地路径:../static/',
src: '../../../static/test-audio/ForElise.mp3'
},
{
description: '网络路径',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp3'
},
{
description: '不存在的音频',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/invalid_url.mp3'
},
{
description: '错误路径',
src: '../static/test-audio/ForElise.mp3'
},
] as Array<AudioPath>
}
},
onReady() {
this._audioContext = uni.createInnerAudioContext();
},
onUnload() {
if (this._audioContext != null) {
this.pause();
this._audioContext!.destroy()
}
},
methods: {
pause() {
this._audioContext!.pause();
this.isPlaying = false;
},
play(audioUrl,index){
// console.log(index,audioUrl);
if (this.isPlaying && this.playIndex == index) {
this.pause();
return;
}
this.playIndex = index
this._audioContext!.src = audioUrl;
this._audioContext!.play();
this.isPlaying = true;
this._audioContext!.onPlay(() => {
console.log('开始播放');
});
this._audioContext!.onEnded(() => {
console.log('播放结束');
this.isPlaying = false;
});
this._audioContext!.onError((err) => {
this.isPlaying = false;
console.log('err',err);
});
}
}
}
</script>
<style>
.formats{
align-items: center;
}
.icon-play {
width: 60px;
height: 60px;
margin: 10px;
}
<template>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title">
<text class="uni-title-text">音频路径示例</text>
</view>
<view class="formats" v-for="(item,index) in supportPaths" :key="index">
<text class="uni-subtitle-text">{{item.description}}</text>
<image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'"
@click="play(item.src,index)"></image>
</view>
</view>
</template>
<script>
type AudioPath = {
description : string
src : string
}
export default {
data() {
return {
title: 'audio-path',
playIndex: 0,
isPlaying: false,
_audioContext: null as InnerAudioContext | null,
supportPaths: [
{
description: '本地路径:/static方式',
src: '/static/test-audio/ForElise.mp3'
},
{
description: '本地路径:../static/',
src: '../../../static/test-audio/ForElise.mp3'
},
{
description: '网络路径',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp3'
},
{
description: '不存在的音频',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/invalid_url.mp3'
},
{
description: '错误路径',
src: '../static/test-audio/ForElise.mp3'
},
] as Array<AudioPath>
}
},
onReady() {
this._audioContext = uni.createInnerAudioContext();
},
onUnload() {
if (this._audioContext != null) {
this.pause();
this._audioContext!.destroy()
}
},
methods: {
pause() {
this._audioContext!.pause();
this.isPlaying = false;
},
play(audioUrl, index) {
// console.log(index,audioUrl);
if (this.isPlaying && this.playIndex == index) {
this.pause();
return;
}
this.playIndex = index
this._audioContext!.src = audioUrl;
this._audioContext!.play();
this.isPlaying = true;
this._audioContext!.onPlay(() => {
console.log('开始播放');
});
this._audioContext!.onEnded(() => {
console.log('播放结束');
this.isPlaying = false;
});
this._audioContext!.onError((err) => {
this.isPlaying = false;
console.log('err', err);
});
}
}
}
</script>
<style>
.formats {
align-items: center;
}
.icon-play {
width: 60px;
height: 60px;
margin: 10px;
}
</style>
<template>
<page-head title="插屏广告"></page-head>
<button :type="btnType" style="margin: 10px;" :disabled="btnDisable" @click="showAd()">{{btnText}}</button>
</template>
<script>
export default {
data() {
return {
btnText: "",
btnType: "primary",
btnDisable: false,
interstitialAd: null as InterstitialAd | null,
isAdLoadSuccess: false
}
},
onReady() {
this.loadAd()
},
methods: {
loadAd() {
if (this.btnDisable)
return
this.btnDisable = true
this.btnText = "正在加载广告"
this.btnType = "primary"
if (this.interstitialAd == null) {
this.interstitialAd = uni.createInterstitialAd({
adpid: "1111111113" //此处为测试广告位,实际开发中请在uni-ad后台申请自己的广告位后替换
})
this.interstitialAd!.onError((_) => {
this.btnType = "warn"
this.btnText = "广告加载失败,点击重试"
this.btnDisable = false
})
this.interstitialAd!.onLoad((_) => {
this.btnType = "primary"
this.btnText = "广告加载成功,点击观看"
this.btnDisable = false
this.isAdLoadSuccess = true
})
this.interstitialAd!.onClose((e) => {
this.isAdLoadSuccess = false
this.loadAd()
})
}
this.interstitialAd!.load()
},
showAd() {
if (this.isAdLoadSuccess) {
this.interstitialAd!.show()
} else {
this.loadAd()
}
}
}
}
</script>
<style>
</style>
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<page-head title="权限申请监听"></page-head>
<view class="permission-alert" id="permission-alert" :style="{'transform':isPermissionAlertShow ? 'translateY(0)':'translateY(-110px)'}">
<text style="font-size: 20px;margin-bottom: 10px;margin-top: 5px;">访问日历权限申请说明:</text>
<text style="color: darkgray;">uni-app x正在申请访问日历权限用于演示,允许或拒绝均不会获取任何隐私信息。</text>
</view>
<button type="primary" style="margin: 10px;" @click="requestPermission">点击申请日历权限</button>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
export default {
data() {
return {
isPermissionAlertShow: false,
permissionAlert: null as UniElement | null,
timeoutId: -1,
permissionListener: null as RequestPermissionListener | null
}
},
onReady() {
this.watchPermissionRRequest()
},
onUnload() {
this.permissionListener?.stop()
this.permissionListener = null
clearTimeout(this.timeoutId)
},
methods: {
watchPermissionRRequest() {
this.permissionListener = uni.createRequestPermissionListener()
this.permissionListener!.onConfirm((_) => {
// TODO 目前onConfirm监听实现的在时间上不够精确,暂时需要延迟弹框,后续修复
// TODO 这里的弹框仅为演示,实际开发中监听权限申请的代码应该在app.uvue中,弹框应全局处理,可参考https://gitcode.net/dcloud/uni-api/-/tree/master/uni_modules/uni-prompt/utssdk/app-android 代码自行封装一个uts的全局弹框
this.timeoutId = setTimeout(() => {
this.isPermissionAlertShow = true
}, 100)
})
this.permissionListener!.onComplete((_) => {
clearTimeout(this.timeoutId)
this.isPermissionAlertShow = false
})
},
requestPermission() {
// #ifdef APP-ANDROID
if (UTSAndroid.checkSystemPermissionGranted(UTSAndroid.getUniActivity()!, ["android.permission.READ_CALENDAR"])) {
uni.showToast({
title: "权限已经同意了,不需要再申请",
position: "bottom"
})
return
}
UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, ["android.permission.READ_CALENDAR"], (_ : boolean, p : string[]) => {
console.log(p)
}, (_ : boolean, p : string[]) => {
uni.showToast({
title: "权限被拒绝了",
position: "bottom"
})
console.log(p)
})
// #endif
}
}
}
</script>
<style>
.permission-alert {
width: 90%;
height: 100px;
margin: 10px 5%;
position: absolute;
top: 0px;
z-index: 3;
border-radius: 5px;
transition-property: transform;
transition-duration: 200ms;
background-color: white;
padding: 10px;
}
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<page-head title="权限申请监听"></page-head>
<view class="permission-alert" id="permission-alert"
:style="{'transform':isPermissionAlertShow ? 'translateY(0)':'translateY(-110px)'}">
<text style="font-size: 20px;margin-bottom: 10px;margin-top: 5px;">访问日历权限申请说明:</text>
<text style="color: darkgray;">uni-app x正在申请访问日历权限用于演示,允许或拒绝均不会获取任何隐私信息。</text>
</view>
<button type="primary" style="margin: 10px;" @click="requestPermission">点击申请日历权限</button>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
export default {
data() {
return {
isPermissionAlertShow: false,
permissionAlert: null as UniElement | null,
timeoutId: -1,
permissionListener: null as RequestPermissionListener | null
}
},
onReady() {
this.watchPermissionRRequest()
},
onUnload() {
this.permissionListener?.stop()
this.permissionListener = null
clearTimeout(this.timeoutId)
},
methods: {
watchPermissionRRequest() {
this.permissionListener = uni.createRequestPermissionListener()
this.permissionListener!.onConfirm((_) => {
// TODO 目前onConfirm监听实现的在时间上不够精确,暂时需要延迟弹框,后续修复
// TODO 这里的弹框仅为演示,实际开发中监听权限申请的代码应该在app.uvue中,弹框应全局处理,可参考https://gitcode.net/dcloud/uni-api/-/tree/master/uni_modules/uni-prompt/utssdk/app-android 代码自行封装一个uts的全局弹框
this.timeoutId = setTimeout(() => {
this.isPermissionAlertShow = true
}, 100)
})
this.permissionListener!.onComplete((_) => {
clearTimeout(this.timeoutId)
this.isPermissionAlertShow = false
})
},
requestPermission() {
// #ifdef APP-ANDROID
if (UTSAndroid.checkSystemPermissionGranted(UTSAndroid.getUniActivity()!, ["android.permission.READ_CALENDAR"])) {
uni.showToast({
title: "权限已经同意了,不需要再申请",
position: "bottom"
})
return
}
UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, ["android.permission.READ_CALENDAR"], (_ : boolean, p : string[]) => {
console.log(p)
}, (_ : boolean, p : string[]) => {
uni.showToast({
title: "权限被拒绝了",
position: "bottom"
})
console.log(p)
})
// #endif
}
}
}
</script>
<style>
.permission-alert {
width: 90%;
height: 100px;
margin: 10px 5%;
position: absolute;
top: 0px;
z-index: 3;
border-radius: 5px;
transition-property: transform;
transition-duration: 200ms;
background-color: white;
padding: 10px;
}
</style>
<template>
<page-head title="激励视频广告"></page-head>
<button :type="btnType" style="margin: 10px;" :disabled="btnDisable" @click="showAd()">{{btnText}}</button>
</template>
<script>
export default {
data() {
return {
btnText: "",
btnType: "primary",
btnDisable: false,
rewardAd: null as RewardedVideoAd | null,
isAdLoadSuccess: false
}
},
onReady() {
this.loadAd()
},
methods: {
loadAd() {
if (this.btnDisable)
return
this.btnDisable = true
this.btnText = "正在加载广告"
this.btnType = "primary"
if (this.rewardAd == null) {
this.rewardAd = uni.createRewardedVideoAd({
adpid: "1507000689" //此处为测试广告位,实际开发中请在uni-ad后台申请自己的广告位后替换
})
this.rewardAd!.onError((_) => {
this.btnType = "warn"
this.btnText = "广告加载失败,点击重试"
this.btnDisable = false
})
this.rewardAd!.onLoad((_) => {
this.btnType = "primary"
this.btnText = "广告加载成功,点击观看"
this.btnDisable = false
this.isAdLoadSuccess = true
})
this.rewardAd!.onClose((e) => {
// 测试广告位无法通过服务器回调。实际开发中,使用自己的广告位后,需参考uni-ad文档编写服务器回调的代码,在服务端发放奖励
this.isAdLoadSuccess = false
uni.showToast({
title: "激励视频" + (e.isEnded ? "" : "未") + "播放完毕",
position: "bottom"
})
this.loadAd()
})
}
this.rewardAd!.load()
},
showAd() {
if (this.isAdLoadSuccess) {
this.rewardAd!.show()
} else {
this.loadAd()
}
}
}
}
</script>
<style>
<template>
<page-head title="激励视频广告"></page-head>
<button :type="btnType" style="margin: 10px;" :disabled="btnDisable" @click="showAd()">{{btnText}}</button>
</template>
<script>
export default {
data() {
return {
btnText: "",
btnType: "primary",
btnDisable: false,
rewardAd: null as RewardedVideoAd | null,
isAdLoadSuccess: false
}
},
onReady() {
this.loadAd()
},
methods: {
loadAd() {
if (this.btnDisable)
return
this.btnDisable = true
this.btnText = "正在加载广告"
this.btnType = "primary"
if (this.rewardAd == null) {
this.rewardAd = uni.createRewardedVideoAd({
adpid: "1507000689" //此处为测试广告位,实际开发中请在uni-ad后台申请自己的广告位后替换
})
this.rewardAd!.onError((_) => {
this.btnType = "warn"
this.btnText = "广告加载失败,点击重试"
this.btnDisable = false
})
this.rewardAd!.onLoad((_) => {
this.btnType = "primary"
this.btnText = "广告加载成功,点击观看"
this.btnDisable = false
this.isAdLoadSuccess = true
})
this.rewardAd!.onClose((e) => {
// 测试广告位无法通过服务器回调。实际开发中,使用自己的广告位后,需参考uni-ad文档编写服务器回调的代码,在服务端发放奖励
this.isAdLoadSuccess = false
uni.showToast({
title: "激励视频" + (e.isEnded ? "" : "未") + "播放完毕",
position: "bottom"
})
this.loadAd()
})
}
this.rewardAd!.load()
},
showAd() {
if (this.isAdLoadSuccess) {
this.rewardAd!.show()
} else {
this.loadAd()
}
}
}
}
</script>
<style>
</style>
......@@ -2,57 +2,57 @@
<!-- #ifdef APP -->
<scroll-view class="page-scroll-view">
<!-- #endif -->
<view class="page" id="page">
<page-head :title="title"></page-head>
<button class="btn btn-get-node-info" @click="getNodeInfo">getNodeInfo</button>
<button class="btn btn-get-all-node-info" @click="getAllNodeInfo">getAllNodeInfo</button>
<view id="rect-1-2" class="rect-1-2">
<view class="rect rect1"></view>
<view class="rect rect2"></view>
</view>
<view class="rect-info-1-2">
<view class="rect-info" v-for="(nodeInfo, index) in nodeInfoList" :key="index">
<view class="node-info-item">
<text class="node-info-item-k">left: </text>
<text class="node-info-item-v">{{nodeInfo.left}}</text>
</view>
<view class="node-info-item">
<text class="node-info-item-k">top: </text>
<text class="node-info-item-v">{{nodeInfo.top}}</text>
</view>
<view class="node-info-item">
<text class="node-info-item-k">right: </text>
<text class="node-info-item-v">{{nodeInfo.right}}</text>
</view>
<view class="node-info-item">
<text class="node-info-item-k">bottom: </text>
<text class="node-info-item-v">{{nodeInfo.bottom}}</text>
</view>
<view class="node-info-item">
<text class="node-info-item-k">width: </text>
<text class="node-info-item-v">{{nodeInfo.width}}</text>
</view>
<view class="node-info-item">
<text class="node-info-item-k">height: </text>
<text class="node-info-item-v">{{nodeInfo.height}}</text>
<view class="page" id="page">
<page-head :title="title"></page-head>
<button class="btn btn-get-node-info" @click="getNodeInfo">getNodeInfo</button>
<button class="btn btn-get-all-node-info" @click="getAllNodeInfo">getAllNodeInfo</button>
<view id="rect-1-2" class="rect-1-2">
<view class="rect rect1"></view>
<view class="rect rect2"></view>
</view>
<view class="rect-info-1-2">
<view class="rect-info" v-for="(nodeInfo, index) in nodeInfoList" :key="index">
<view class="node-info-item">
<text class="node-info-item-k">left: </text>
<text class="node-info-item-v">{{nodeInfo.left}}</text>
</view>
<view class="node-info-item">
<text class="node-info-item-k">top: </text>
<text class="node-info-item-v">{{nodeInfo.top}}</text>
</view>
<view class="node-info-item">
<text class="node-info-item-k">right: </text>
<text class="node-info-item-v">{{nodeInfo.right}}</text>
</view>
<view class="node-info-item">
<text class="node-info-item-k">bottom: </text>
<text class="node-info-item-v">{{nodeInfo.bottom}}</text>
</view>
<view class="node-info-item">
<text class="node-info-item-k">width: </text>
<text class="node-info-item-v">{{nodeInfo.width}}</text>
</view>
<view class="node-info-item">
<text class="node-info-item-k">height: </text>
<text class="node-info-item-v">{{nodeInfo.height}}</text>
</view>
</view>
</view>
<node-child class="node-child"></node-child>
<text>子组件多根节点</text>
<multi-child ref="multi-child" id="multi-child"></multi-child>
<text>子组件多根节点(仅测试,用于验证查询是否超出范围)</text>
<multi-child id="multi-child-2"></multi-child>
<view>
<text>测试.fields</text>
<text>{{fieldsResultContainNode}}</text>
</view>
<view>
<text>测试.node</text>
<text>{{nodeResultContainNode}}</text>
</view>
<canvas id="canvas1"></canvas>
</view>
<node-child class="node-child"></node-child>
<text>子组件多根节点</text>
<multi-child ref="multi-child" id="multi-child"></multi-child>
<text>子组件多根节点(仅测试,用于验证查询是否超出范围)</text>
<multi-child id="multi-child-2"></multi-child>
<view>
<text>测试.fields</text>
<text>{{fieldsResultContainNode}}</text>
</view>
<view>
<text>测试.node</text>
<text>{{nodeResultContainNode}}</text>
</view>
<canvas id="canvas1"></canvas>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
......@@ -160,10 +160,10 @@
// test .fields
testFields() {
uni.createSelectorQuery().select('.rect1').fields({
node: true
node: true
} as NodeField, (ret) => {
const isElement = (ret as NodeInfo).node instanceof UniElement
if(isElement){
if (isElement) {
this.fieldsResultContainNode = true
} else {
this.fieldsResultContainNode = false
......@@ -175,11 +175,11 @@
uni.createSelectorQuery().select('#canvas1').node((ret) => {
const isElement = (ret as NodeInfo).node instanceof UniElement
const isCanvasElement = ((ret as NodeInfo).node as UniCanvasElement).tagName == 'CANVAS'
if(isElement && isCanvasElement){
this.nodeResultContainNode = true
} else {
this.nodeResultContainNode = false
}
if (isElement && isCanvasElement) {
this.nodeResultContainNode = true
} else {
this.nodeResultContainNode = false
}
}).exec()
},
}
......
......@@ -12,18 +12,18 @@
}
},
mounted() {
uni.createSelectorQuery().in(this).select('.selector-query-child-view').boundingClientRect().exec((ret) => {
if (ret.length == 1) {
const nodeInfo = ret[0] as NodeInfo;
this.top = nodeInfo.top!
uni.createSelectorQuery().in(this).select('.selector-query-child-view').boundingClientRect().exec((ret) => {
if (ret.length == 1) {
const nodeInfo = ret[0] as NodeInfo;
this.top = nodeInfo.top!
}
})
}
}
</script>
<style>
.selector-query-child-view {
margin-top: 15px;
<style>
.selector-query-child-view {
margin-top: 15px;
}
</style>
......@@ -17,25 +17,25 @@
return {
text1: "",
text2: "",
text3: "test-text-node",
viewCount: 0,
selectCount: 0,
text3: "test-text-node",
viewCount: 0,
selectCount: 0,
selectAllCount: 0,
show: false
}
},
mounted() {
uni.createSelectorQuery().in(this).select('.selector-query-view').boundingClientRect().exec((ret) => {
this.text1 = JSON.stringify(ret, null, 2)
if (ret.length == 1) {
this.selectCount = ret.length
this.text1 = JSON.stringify(ret, null, 2)
if (ret.length == 1) {
this.selectCount = ret.length
}
})
uni.createSelectorQuery().in(this).selectAll('.selector-query-view').boundingClientRect().exec((ret) => {
this.text2 = JSON.stringify(ret, null, 2)
if (ret.length == 1) {
this.selectAllCount = (ret[0] as NodeInfo[]).length
}
})
uni.createSelectorQuery().in(this).selectAll('.selector-query-view').boundingClientRect().exec((ret) => {
this.text2 = JSON.stringify(ret, null, 2)
if (ret.length == 1) {
this.selectAllCount = (ret[0] as NodeInfo[]).length
}
})
}
}
......
<template>
<view id="dialog1" class="dialog-container">
<view class="dialog-content">
<text>title: {{title}}</text>
<text class="mt-10">onBackPress return true</text>
<button class="mt-10" id="dialog1-go-next-page" @click="goNextPage">go next page</button>
<button class="mt-10" id="dialog1-open-dialog2" @click="openDialog2">openDialog2</button>
<button class="mt-10" id="dialog1-close-dialog" @click="closeDialog">closeDialog</button>
<button class="mt-10" id="dialog1-close-this-dialog" @click="closeThisDialog">closeThisDialog</button>
<button class="mt-10" id="dialog1-back" @click="back">back</button>
</view>
</view>
</template>
<script>
import {
state,
setLifeCycleNum
} from '@/store/index.uts'
export default {
data() {
return {
title: 'dialog 1',
}
},
onLoad(options : OnLoadOptions) {
console.log('dialog 1 onLoad', options)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
if (options['name'] == 'dialog1') {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
},
onShow() {
console.log('dialog 1 onShow')
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
onReady() {
console.log('dialog 1 onReady')
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
const currentPages = getCurrentPages()
const parentPage = this.$page.getParentPage()!
const grandParentPage = parentPage.getParentPage()
const dialogPages = parentPage.getDialogPages()
const dialogPage = this.$page
if (
currentPages.length == 1 &&
grandParentPage == null &&
dialogPages.indexOf(dialogPage) != -1
) {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
},
onHide() {
console.log('dialog 1 onHide')
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 1)
},
onUnload() {
console.log('dialog 1 onUnload')
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 5)
},
onBackPress(options : OnBackPressOptions) : boolean | null {
console.log('dialogPage1 onBackPress', options)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
return true
},
methods: {
goNextPage() {
uni.navigateTo({ url: '/pages/API/dialog-page/next-page' })
},
openDialog2() {
uni.openDialogPage({
url: '/pages/API/dialog-page/dialog-2',
disableEscBack: true,
success(res) {
console.log('openDialog2 success', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
fail(err) {
console.log('openDialog2 fail', err)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4)
},
complete(res) {
console.log('openDialog2 complete', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
closeDialog() {
uni.closeDialogPage({
success(res) {
console.log('closeDialog success', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
fail(err) {
console.log('closeDialog fail', err)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4)
},
complete(res) {
console.log('closeDialog complete', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
closeThisDialog() {
uni.closeDialogPage({
dialogPage: this.$page,
success(res) {
console.log('closeThisDialog success', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
fail(err) {
console.log('closeThisDialog fail', err)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4)
},
complete(res) {
console.log('closeThisDialog complete', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
back() {
uni.navigateBack()
}
}
}
</script>
<style>
.dialog-container {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
display: flex;
justify-content: center;
align-items: center;
}
.dialog-content {
width: 80%;
padding: 10px;
background-color: #fff;
border-radius: 6px;
}
.mt-10 {
margin-top: 10px;
}
</style>
<template>
<view id="dialog2" class="dialog-container">
<view class="dialog-content">
<text>title: {{title}}</text>
<text class="mt-10">onBackPress return false</text>
<button class="mt-10" @click="goNextPage">go next page</button>
<button class="mt-10" @click="openDialog1">openDialog1</button>
<button class="mt-10" @click="closeDialog">closeDialog</button>
<button class="mt-10" @click="closeThisDialog">closeThisDialog</button>
<button class="mt-10" @click="back">back</button>
</view>
</view>
</template>
<script>
import {
state,
setLifeCycleNum
} from '@/store/index.uts'
export default {
data() {
return {
title: 'dialog 2',
}
},
onLoad(options : OnLoadOptions) {
console.log('dialog 2 onLoad', options)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
onShow() {
console.log('dialog 2 onShow')
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
onReady() {
console.log('dialog 2 onReady')
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
onHide() {
console.log('dialog 2 onHide')
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 1)
},
onUnload() {
console.log('dialog 2 onUnload')
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 5)
},
onBackPress(options : OnBackPressOptions) : boolean | null {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
return false
},
methods: {
goNextPage() {
uni.navigateTo({ url: '/pages/API/dialog-page/next-page' })
},
openDialog1() {
uni.openDialogPage({
url: '/pages/API/dialog-page/dialog-1?name=dialog1',
success(res) {
console.log('openDialog1 success', res)
},
fail(err) {
console.log('openDialog1 fail', err)
},
complete(res) {
console.log('openDialog1 complete', res)
}
})
},
closeDialog() {
uni.closeDialogPage({
success(res) {
console.log('closeDialog success', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
fail(err) {
console.log('closeDialog fail', err)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4)
},
complete(res) {
console.log('closeDialog complete', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
closeThisDialog() {
uni.closeDialogPage({
dialogPage: this.$page,
success(res) {
console.log('closeThisDialog success', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
fail(err) {
console.log('closeThisDialog fail', err)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4)
},
complete(res) {
console.log('closeThisDialog complete', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
back() {
uni.navigateBack()
}
}
}
</script>
<style>
.dialog-container {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
display: flex;
justify-content: center;
align-items: center;
}
.dialog-content {
width: 80%;
padding: 10px;
background-color: #fff;
border-radius: 6px;
}
.mt-10 {
margin-top: 10px;
}
</style>
jest.setTimeout(20000)
const platformInfo = process.env.uniTestPlatformInfo.toLocaleLowerCase()
const isWeb = platformInfo.startsWith('web')
const FIRST_PAGE_PATH = '/pages/API/dialog-page/dialog-page'
const NEXT_PAGE_PATH = '/pages/API/dialog-page/next-page'
describe('dialog page', () => {
if (process.env.UNI_AUTOMATOR_APP_WEBVIEW == 'true') {
it('skip app-webview', () => {
expect(1).toBe(1)
})
return
}
let page;
let initLifeCycleNum;
let lifecycleNum;
beforeAll(async () => {
page = await program.reLaunch(FIRST_PAGE_PATH)
await page.waitFor('view');
initLifeCycleNum = await page.callMethod('getLifeCycleNum');
await page.callMethod('setLifeCycleNum', 0)
lifecycleNum = await page.callMethod('getLifeCycleNum')
expect(lifecycleNum).toBe(0)
});
it('open dialog1', async () => {
await page.callMethod('openDialog1');
// 无法通过获取 dom 元素来判断是否打开了 dialogPage
await page.waitFor(1000)
if (isWeb) {
await page.waitFor(2000)
}
const image = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
}
});
expect(image).toSaveImageSnapshot();
lifecycleNum = await page.callMethod('getLifeCycleNum')
// 不应触发父页面的生命周期,应该触发:
// 1. openDialogPage success & complete callback
// 2. dialog page 生命周期
expect(lifecycleNum).toBe(7)
await page.callMethod('setLifeCycleNum', 0)
});
it('closeDialogPage', async () => {
await page.callMethod('closeDialog');
const image = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
}
});
expect(image).toSaveImageSnapshot();
// closeDialogPage success & complete callback 应被触发
// dialogPage onUnload 应被触发
lifecycleNum = await page.callMethod('getLifeCycleNum')
expect(lifecycleNum).toBe(-3)
await page.callMethod('setLifeCycleNum', 0)
})
it('openDialog with wrong path', async () => {
await page.callMethod('openDialog1WrongPath')
lifecycleNum = await page.callMethod('getLifeCycleNum')
expect(lifecycleNum).toBe(-3)
await page.callMethod('setLifeCycleNum', 0)
})
it('navigateTo nextPage & open Dialog', async () => {
await page.callMethod('goNextPageOpenDialog1')
await page.waitFor(2000)
if (isWeb) {
await page.waitFor(3000)
}
page = await program.currentPage()
expect(page.path).toBe(NEXT_PAGE_PATH.substring(1))
await page.waitFor(1000)
if (isWeb) {
await page.waitFor(2000)
}
const image = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
}
});
expect(image).toSaveImageSnapshot();
lifecycleNum = await page.callMethod('getLifeCycleNum')
expect(lifecycleNum).toBe(-4)
await page.callMethod('setLifeCycleNum', 0)
})
it('dialog1 navigateBack', async () => {
await program.navigateBack()
page = await program.currentPage()
// dialogPage onBackPress 返回 true, 应可以拦截 navigateBack
expect(page.path).toBe(NEXT_PAGE_PATH.substring(1))
const image = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
}
});
expect(image).toSaveImageSnapshot();
lifecycleNum = await page.callMethod('getLifeCycleNum')
// onBackPress 生命周期应该被触发
expect(lifecycleNum).toBe(1)
await page.callMethod('setLifeCycleNum', 0)
})
it('open dialog2', async () => {
await page.callMethod('openDialog2')
await page.waitFor(1000)
if (isWeb) {
await page.waitFor(2000)
}
lifecycleNum = await page.callMethod('getLifeCycleNum')
// 应触发前一个 dialogPage 的 onHide
expect(lifecycleNum).toBe(4)
await page.callMethod('setLifeCycleNum', 0)
})
it('closeDialogPage', async () => {
await page.callMethod('closeDialog')
lifecycleNum = await page.callMethod('getLifeCycleNum')
// 应触发 success & complete 回调
// 应触发 dialogPage 的 unload,下层的 dialogPage 会先 show 再 unload
expect(lifecycleNum).toBe(-7)
const image = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
}
});
expect(image).toSaveImageSnapshot();
await page.callMethod('setLifeCycleNum', 0)
})
it('open multiple dialog page', async () => {
await page.callMethod('openDialog1')
await page.waitFor(1000)
if (isWeb) {
await page.waitFor(2000)
}
const image1 = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
}
});
expect(image1).toSaveImageSnapshot();
lifecycleNum = await page.callMethod('getLifeCycleNum')
expect(lifecycleNum).toBe(4)
await page.callMethod('openDialog2')
await page.waitFor(1000)
if (isWeb) {
await page.waitFor(2000)
}
const image2 = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
}
});
expect(image2).toSaveImageSnapshot();
lifecycleNum = await page.callMethod('getLifeCycleNum')
expect(lifecycleNum).toBe(8)
await page.callMethod('setLifeCycleNum', 0)
})
it('openDialogPage to home page', async () => {
await page.callMethod('openDialogPage1ToHomePage')
await page.waitFor(1000)
if (isWeb) {
await page.waitFor(2000)
}
lifecycleNum = await page.callMethod('getLifeCycleNum')
expect(lifecycleNum).toBe(4)
await page.callMethod('setLifeCycleNum', 0)
})
it('dialog2 navigateBack', async () => {
await program.navigateBack()
page = await program.currentPage()
// dialogPage onBackPress 返回 true, 应可以拦截 navigateBack
expect(page.path).toBe(FIRST_PAGE_PATH.substring(1))
const image = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
}
});
expect(image).toSaveImageSnapshot();
lifecycleNum = await page.callMethod('getLifeCycleNum')
// onBackPress 生命周期应该被触发
expect(lifecycleNum).toBe(2)
await page.callMethod('setLifeCycleNum', 0)
})
it('close specified dialogPage', async () => {
await page.callMethod('openDialog2')
await page.waitFor(1000)
if (isWeb) {
await page.waitFor(2000)
}
const image1 = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
}
});
expect(image1).toSaveImageSnapshot();
lifecycleNum = await page.callMethod('getLifeCycleNum')
expect(lifecycleNum).toBe(4)
await page.callMethod('openDialog1')
await page.waitFor(1000)
if (isWeb) {
await page.waitFor(2000)
}
const image2 = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
}
});
expect(image2).toSaveImageSnapshot();
lifecycleNum = await page.callMethod('getLifeCycleNum')
expect(lifecycleNum).toBe(10)
await page.callMethod('closeSpecifiedDialog', 0)
const image3 = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
}
});
expect(image3).toSaveImageSnapshot();
lifecycleNum = await page.callMethod('getLifeCycleNum')
expect(lifecycleNum).toBe(7)
await page.callMethod('closeSpecifiedDialog', 1)
const image4 = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
}
});
expect(image4).toSaveImageSnapshot();
lifecycleNum = await page.callMethod('getLifeCycleNum')
expect(lifecycleNum).toBe(5)
await page.callMethod('closeSpecifiedDialog', 0)
const image5 = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
}
});
expect(image5).toSaveImageSnapshot();
lifecycleNum = await page.callMethod('getLifeCycleNum')
expect(lifecycleNum).toBe(2)
})
afterAll(async () => {
await page.callMethod('setLifeCycleNum', initLifeCycleNum)
});
});
<template>
<view class="uni-padding-wrap">
<button class="uni-common-mt" id="go-next-page" @click="goNextPage">go next page</button>
<button class="uni-common-mt" id="open-dialog1" @click="openDialog1">open dialog 1</button>
<button class="uni-common-mt" id="open-dialog1-wrong-path" @click="openDialog1WrongPath">open dialog page 1 with
wrong path</button>
<button class="uni-common-mt" id="go-next-page-open-dialog1" @click="goNextPageOpenDialog1">go next page & open
dialog1</button>
</view>
</template>
<script lang='uts'>
import {
state,
setLifeCycleNum
} from '@/store/index.uts'
export default {
onLoad() {
console.log('dialogPage parent onLoad')
},
onShow() {
console.log('dialogPage parent onShow')
setLifeCycleNum(state.lifeCycleNum + 10)
},
onReady() {
console.log('dialogPage parent onReady')
},
onHide() {
console.log('dialogPage parent onHide')
setLifeCycleNum(state.lifeCycleNum - 10)
},
onUnload() {
console.log('dialogPage parent onUnload')
},
methods: {
goNextPage() {
uni.navigateTo({
url: '/pages/API/dialog-page/next-page'
})
},
openDialog1() {
uni.openDialogPage({
url: '/pages/API/dialog-page/dialog-1?name=dialog1',
success(res) {
console.log('openDialogPage1 success', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
fail(err) {
console.log('openDialogPage1 fail', err)
setLifeCycleNum(state.lifeCycleNum - 4)
},
complete(res) {
console.log('openDialogPage1 complete', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
openDialog2() {
uni.openDialogPage({
url: '/pages/API/dialog-page/dialog-2',
disableEscBack: true,
success(res) {
console.log('openDialog2 success', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
fail(err) {
console.log('openDialog2 fail', err)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4)
},
complete(res) {
console.log('openDialog2 complete', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
openDialog1WrongPath() {
uni.openDialogPage({
url: '/pages/API/dialog-page/dialog-11?name=dialog1',
success(res) {
console.log('openDialogPage1 success', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
fail(err) {
console.log('openDialogPage1 fail', err)
setLifeCycleNum(state.lifeCycleNum - 4)
},
complete(res) {
console.log('openDialogPage1 complete', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
goNextPageOpenDialog1() {
uni.navigateTo({
url: '/pages/API/dialog-page/next-page',
success() {
setTimeout(() => {
uni.openDialogPage({
url: '/pages/API/dialog-page/dialog-1?name=dialog1',
success(res) {
console.log('openDialogPage1 success', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
fail(err) {
console.log('openDialogPage1 fail', err)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4)
},
complete(res) {
console.log('openDialogPage1 complete', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
})
}, 1000)
}
})
},
closeDialog() {
uni.closeDialogPage({
success(res) {
console.log('closeDialog success', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
fail(err) {
console.log('closeDialog fail', err)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4)
},
complete(res) {
console.log('closeDialog complete', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
closeSpecifiedDialog(index: number) {
const dialogPages = this.$page.getDialogPages()
uni.closeDialogPage({
dialogPage: dialogPages[index],
success(res) {
console.log('closeSomeOneDialog success', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
fail(err) {
console.log('closeSomeOneDialog fail', err)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4)
},
complete(res) {
console.log('closeSomeOneDialog complete', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
setLifeCycleNum(value: number) {
setLifeCycleNum(value)
},
getLifeCycleNum(): number {
return state.lifeCycleNum
}
}
}
</script>
<template>
<view class='uni-padding-wrap'>
<button class="uni-common-mt" @click="openDialog1">open dialog1</button>
<button class="uni-common-mt" @click="openDialog2">open dialog2</button>
<button class="uni-common-mt" @click="openDialogPage1ToHomePage">open dialog page 1 to home page</button>
</view>
</template>
<script lang='uts'>
import {
state,
setLifeCycleNum
} from '@/store/index.uts'
export default {
onLoad() {
console.log('dialogPage parent onLoad')
},
onShow() {
console.log('dialogPage parent onShow')
},
onReady() {
console.log('dialogPage parent onReady')
},
onHide() {
console.log('dialogPage parent onHide')
},
onUnload() {
console.log('dialogPage parent onUnload')
},
methods: {
openDialog1() {
uni.openDialogPage({
url: '/pages/API/dialog-page/dialog-1?name=dialog1',
success(res) {
console.log('openDialog1 success', res)
},
fail(err) {
console.log('openDialog1 fail', err)
},
complete(res) {
console.log('openDialog1 complete', res)
}
})
},
openDialog2() {
uni.openDialogPage({
url: '/pages/API/dialog-page/dialog-2',
disableEscBack: true,
success(res) {
console.log('openDialog2 success', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
fail(err) {
console.log('openDialog2 fail', err)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4)
},
complete(res) {
console.log('openDialog2 complete', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
closeDialog() {
uni.closeDialogPage({
success(res) {
console.log('closeDialog success', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
},
fail(err) {
console.log('closeDialog fail', err)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4)
},
complete(res) {
console.log('closeDialog complete', res)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
openDialogPage1ToHomePage() {
const pages = getCurrentPages()
uni.openDialogPage({
parentPage: pages[0],
url: '/pages/API/dialog-page/dialog-1?name=dialog1',
success(res) {
console.log('openDialogPage1ToHomePage success', res)
uni.showToast({title: '在首页打开了 dialogPage'})
},
fail(err) {
console.log('openDialogPage1ToHomePage fail', err)
},
complete(res) {
console.log('openDialogPage1ToHomePage complete', res)
}
})
},
setLifeCycleNum(value: number) {
setLifeCycleNum(value)
},
getLifeCycleNum(): number {
return state.lifeCycleNum
}
}
}
</script>
......@@ -18,14 +18,13 @@
</scroll-view>
<!-- #endif -->
</template>
<script>
// #ifdef APP
import {
testInovkeDownloadFile,
CommonOptions
} from '@/uni_modules/test-invoke-network-api'
// #endif
<script>
// #ifdef APP
import {
testInovkeDownloadFile,
CommonOptions
} from '@/uni_modules/test-invoke-network-api'
// #endif
export default {
data() {
......@@ -58,10 +57,10 @@
},
fail: (err) => {
console.log('downloadFile fail, err is:', err)
},
complete: (res) => {
uni.hideLoading();
this.task = null;
},
complete: (res) => {
uni.hideLoading();
this.task = null;
}
});
this.task?.onProgressUpdate((update) => {
......@@ -79,87 +78,87 @@
this.jest_result = false
}
});
},
jest_downloadFile_with_uni_env() {
uni.downloadFile({
url: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app.png",
filePath: `${uni.env.CACHE_PATH}/a/b/`,
success: () => {
this.jest_result = true
},
fail: () => {
this.jest_result = false
}
});
},
jest_set_cookie(){
uni.request({
url: "https://request.dcloud.net.cn/api/http/header/setCookie",
method: "GET",
timeout: 6000,
sslVerify: false,
withCredentials: true,
firstIpv4: false,
success: () => {
this.jest_cookie_download(true)
},
fail: () => {
this.jest_result = false;
},
});
},
jest_delete_cookie(){
uni.request({
url: "https://request.dcloud.net.cn/api/http/header/deleteCookie",
method: "GET",
timeout: 6000,
sslVerify: false,
withCredentials: true,
firstIpv4: false,
success: () => {
this.jest_cookie_download(false)
},
fail: () => {
this.jest_result = false;
},
});
},
jest_cookie_download(needCookie: boolean){
uni.downloadFile({
url: "https://request.dcloud.net.cn/api/http/header/download",
success: () => {
this.jest_result = needCookie ? true : false;
},
fail: () => {
this.jest_result = needCookie ? false : true;
}
});
},
jest_uts_module_invoked(){
// #ifdef APP
testInovkeDownloadFile({
success:(res: any)=>{
this.jest_result = true
},
fail:(err: any)=>{
this.jest_result = false
}
} as CommonOptions)
// #endif
},
jest_special_characters_download(){
uni.downloadFile({
url: "https://web-ext-storage.dcloud.net.cn/hello-uni-app-x/1789834995055525889-你好%23你好.png",
success: (res: DownloadFileSuccess) => {
this.jest_result = true;
},
fail: () => {
this.jest_result = false;
}
});
},
jest_downloadFile_with_uni_env() {
uni.downloadFile({
url: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app.png",
filePath: `${uni.env.CACHE_PATH}/a/b/`,
success: () => {
this.jest_result = true
},
fail: () => {
this.jest_result = false
}
});
},
jest_set_cookie() {
uni.request({
url: "https://request.dcloud.net.cn/api/http/header/setCookie",
method: "GET",
timeout: 6000,
sslVerify: false,
withCredentials: true,
firstIpv4: false,
success: () => {
this.jest_cookie_download(true)
},
fail: () => {
this.jest_result = false;
},
});
},
jest_delete_cookie() {
uni.request({
url: "https://request.dcloud.net.cn/api/http/header/deleteCookie",
method: "GET",
timeout: 6000,
sslVerify: false,
withCredentials: true,
firstIpv4: false,
success: () => {
this.jest_cookie_download(false)
},
fail: () => {
this.jest_result = false;
},
});
},
jest_cookie_download(needCookie : boolean) {
uni.downloadFile({
url: "https://request.dcloud.net.cn/api/http/header/download",
success: () => {
this.jest_result = needCookie ? true : false;
},
fail: () => {
this.jest_result = needCookie ? false : true;
}
});
},
jest_uts_module_invoked() {
// #ifdef APP
testInovkeDownloadFile({
success: (res : any) => {
this.jest_result = true
},
fail: (err : any) => {
this.jest_result = false
}
} as CommonOptions)
// #endif
},
jest_special_characters_download() {
uni.downloadFile({
url: "https://web-ext-storage.dcloud.net.cn/hello-uni-app-x/1789834995055525889-你好%23你好.png",
success: (res : DownloadFileSuccess) => {
this.jest_result = true;
},
fail: () => {
this.jest_result = false;
}
});
}
}
}
......@@ -169,4 +168,4 @@
.img {
margin: 0 auto;
}
</style>
</style>
<template>
<!-- #ifdef APP -->
<scroll-view class="page-scroll-view">
<!-- #endif -->
<view>
<view class="drawing" id="draw-text-view"></view>
<view class="drawing" id="draw-line-view"></view>
<view class="drawing" id="draw-circle-view"></view>
<view class="drawing" id="draw-dash-line"></view>
<view class="drawing" id="draw-house"></view>
<view class="drawing" id="draw-style"></view>
<view class="drawing" id="draw-odd"></view>
<view class="drawing" id="draw-arcto"></view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
var y = 160
export default {
data() {
return {
texts: [
'HBuilderX,轻巧、极速,极客编辑器',
'uni-app x,终极跨平台方案',
'uniCloud,js serverless云服务',
'uts,大一统语言',
'uniMPSdk,让你的App具备小程序能力',
'uni-admin,开源、现成的全端管理后台',
'uni-id,开源、全端的账户中心',
'uni-pay,开源、云端一体、全平台的支付',
'uni-ai,聚合ai能力',
'uni-cms,开源、云端一体、全平台的内容管理平台',
'uni-im,开源、云端一体、全平台的im即时消息',
'uni统计,开源、完善、全平台的统计报表',
'......'
] as string[]
}
},
onShow() {
},
onReady() {
this.drawText()
this.drawLines()
this.drawCircles()
this.drawStar()
this.drawhouse()
this.drawPoint()
this.drawRect()
this.drawArcTo()
},
onUnload() {
y = 160
},
methods: {
drawText() {
let element = uni.getElementById('draw-text-view')!
let ctx = element.getDrawableContext()!
let width = element.getBoundingClientRect().width
ctx.reset()
ctx.font = "15px Arial"
ctx.textAlign = "center"
for (var i = 0; i < this.texts.length; i++) {
let value = this.texts[i]
if (i % 2 == 0) {
ctx.fillText(value, width / 2, (20 * (i + 1)))
} else {
ctx.lineWidth = 0.5
ctx.strokeText(value, width / 2, (20 * (i + 1)))
}
}
ctx.update()
},
drawLines() {
let ctx = uni.getElementById('draw-line-view')!.getDrawableContext()!
ctx.reset()
ctx.lineWidth = 10;
["round", "bevel", "miter"].forEach((join, i) => {
ctx.lineJoin = join;
ctx.beginPath();
ctx.moveTo(5, 10 + i * 40);
ctx.lineTo(50, 50 + i * 40);
ctx.lineTo(90, 10 + i * 40);
ctx.lineTo(130, 50 + i * 40);
ctx.lineTo(170, 10 + i * 40);
ctx.stroke();
});
ctx.lineWidth = 1
var space = 170
ctx.strokeStyle = '#09f';
ctx.beginPath();
ctx.moveTo(10 + space, 10);
ctx.lineTo(140 + space, 10);
ctx.moveTo(10 + space, 140);
ctx.lineTo(140 + space, 140);
ctx.stroke();
// Draw lines
ctx.strokeStyle = 'black';
['butt', 'round', 'square'].forEach((lineCap, i) => {
ctx.lineWidth = 15;
ctx.lineCap = lineCap;
ctx.beginPath();
ctx.moveTo(25 + space + i * 50, 10);
ctx.lineTo(25 + space + i * 50, 140);
ctx.stroke();
});
ctx.lineWidth = 1;
this.drawDashedLine([], ctx);
this.drawDashedLine([2, 2], ctx);
this.drawDashedLine([10, 10], ctx);
this.drawDashedLine([20, 5], ctx);
this.drawDashedLine([15, 3, 3, 3], ctx);
this.drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3], ctx);
ctx.lineDashOffset = 18;
this.drawDashedLine([12, 3, 3], ctx);
ctx.lineDashOffset = 0
ctx.setLineDash([0])
ctx.update()
},
drawDashedLine(pattern : Array<number>, ctx : DrawableContext) {
ctx.beginPath();
ctx.setLineDash(pattern);
ctx.moveTo(0, y);
ctx.lineTo(300, y);
ctx.stroke();
y += 15;
},
drawCircles() {
let ctx = uni.getElementById('draw-circle-view')!.getDrawableContext()!
ctx.reset()
// Draw shapes
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 3; j++) {
ctx.beginPath();
var x = 25 + j * 50; // x coordinate
var y = 25 + i * 50; // y coordinate
var radius = 20; // Arc radius
var startAngle = 0; // Starting point on circle
var endAngle = Math.PI + (Math.PI * j) / 2; // End point on circle
var clockwise = i % 2 == 0 ? false : true; // clockwise or anticlockwise
ctx.arc(x, y, radius, startAngle, endAngle, clockwise);
if (i > 1) {
ctx.fill();
} else {
ctx.stroke();
}
}
}
ctx.update()
},
drawStar() {
let ctx = uni.getElementById('draw-dash-line')!.getDrawableContext()!
ctx.reset()
ctx.beginPath();
var horn = 5; // 画5个角
var angle = 360 / horn; // 五个角的度数
// 两个圆的半径
var R = 50;
var r = 20;
// 坐标
var x = 100;
var y = 100;
for (var i = 0; i < horn; i++) {
// 角度转弧度:角度/180*Math.PI
// 外圆顶点坐标
ctx.lineTo(Math.cos((18 + i * angle) / 180.0 * Math.PI) * R + x, -Math.sin((18 + i * angle) / 180.0 * Math.PI) * R + y);
// 內圆顶点坐标
ctx.lineTo(Math.cos((54 + i * angle) / 180.0 * Math.PI) * r + x, -Math.sin((54 + i * angle) / 180.0 * Math.PI) * r + y);
}
// closePath:关闭路径,将路径的终点与起点相连
ctx.closePath();
ctx.lineWidth = 3;
ctx.fillStyle = '#E4EF00';
ctx.strokeStyle = "red";
ctx.fill();
ctx.stroke();
ctx.lineWidth = 10;
ctx.beginPath()
ctx.moveTo(170, 100)
ctx.lineTo(255, 15)
ctx.lineTo(340, 100)
ctx.closePath()
ctx.fill()
ctx.strokeStyle = "blue"
ctx.stroke()
ctx.beginPath()
ctx.moveTo(170, 145)
ctx.lineTo(255, 45)
ctx.lineTo(340, 145)
ctx.closePath()
ctx.fill()
ctx.strokeStyle = "gray"
ctx.stroke()
// 未设置beginPath,导致上下表现一致,与前端一致
ctx.moveTo(170, 190)
ctx.lineTo(255, 90)
ctx.lineTo(340, 190)
ctx.closePath()
ctx.fillStyle = "orange"
ctx.fill()
ctx.strokeStyle = "khaki"
ctx.stroke()
ctx.update()
},
hex(num : number) : string {
if (num == 0) {
return "00"
}
let hexChars = "0123456789ABCDEF";
let result = "";
while (num > 0) {
let remainder = Math.floor(num) % 16;
result = hexChars[remainder] + result;
num = Math.floor(Math.floor(num) / 16);
}
if (result.length == 1) {
return "0" + result
}
return result
},
drawhouse() {
let ctx = uni.getElementById('draw-house')!.getDrawableContext()!
ctx.reset()
ctx.lineWidth = 10;
// Wall
ctx.strokeRect(75, 140, 150, 110);
// Door
ctx.fillRect(130, 190, 40, 60);
// Roof
ctx.beginPath();
ctx.moveTo(50, 140);
ctx.lineTo(150, 60);
ctx.lineTo(250, 140);
ctx.closePath();
ctx.stroke();
ctx.update()
},
drawPoint() {
let ctx = uni.getElementById('draw-style')!.getDrawableContext()!
ctx.reset()
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 6; j++) {
ctx.strokeStyle = `rgb(0,${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)})`;
ctx.beginPath();
ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
ctx.stroke();
}
}
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 6; j++) {
ctx.fillStyle = `rgb(${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)},0)`;
ctx.fillRect(180 + j * 25, i * 25, 25, 25);
}
}
ctx.update()
},
drawRect() {
let ctx = uni.getElementById('draw-odd')!.getDrawableContext()!
ctx.reset()
// Create path
ctx.moveTo(30, 90);
ctx.lineTo(110, 20);
ctx.lineTo(240, 130);
ctx.lineTo(60, 130);
ctx.lineTo(190, 20);
ctx.lineTo(270, 90);
ctx.closePath();
// Fill path
ctx.fillStyle = "green";
ctx.fill("evenodd");
ctx.update()
},
drawArcTo() {
let ctx = uni.getElementById('draw-arcto')!.getDrawableContext()!
ctx.reset()
ctx.beginPath();
ctx.moveTo(50, 20);
ctx.bezierCurveTo(230, 30, 150, 60, 50, 100);
ctx.stroke();
ctx.fillStyle = "blue";
// start point
ctx.fillRect(50, 20, 10, 10);
// end point
ctx.fillRect(50, 100, 10, 10);
ctx.fillStyle = "red";
// control point one
ctx.fillRect(230, 30, 10, 10);
// control point two
ctx.fillRect(150, 70, 10, 10);
ctx.update()
}
}
}
</script>
<style>
.drawing {
height: 275px;
background-color: lightgray;
margin-bottom: 15px;
}
<template>
<!-- #ifdef APP -->
<scroll-view class="page-scroll-view">
<!-- #endif -->
<view>
<view class="drawing" id="draw-text-view"></view>
<view class="drawing" id="draw-line-view"></view>
<view class="drawing" id="draw-circle-view"></view>
<view class="drawing" id="draw-dash-line"></view>
<view class="drawing" id="draw-house"></view>
<view class="drawing" id="draw-style"></view>
<view class="drawing" id="draw-odd"></view>
<view class="drawing" id="draw-arcto"></view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
var y = 160
export default {
data() {
return {
texts: [
'HBuilderX,轻巧、极速,极客编辑器',
'uni-app x,终极跨平台方案',
'uniCloud,js serverless云服务',
'uts,大一统语言',
'uniMPSdk,让你的App具备小程序能力',
'uni-admin,开源、现成的全端管理后台',
'uni-id,开源、全端的账户中心',
'uni-pay,开源、云端一体、全平台的支付',
'uni-ai,聚合ai能力',
'uni-cms,开源、云端一体、全平台的内容管理平台',
'uni-im,开源、云端一体、全平台的im即时消息',
'uni统计,开源、完善、全平台的统计报表',
'......'
] as string[]
}
},
onShow() {
},
onReady() {
this.drawText()
this.drawLines()
this.drawCircles()
this.drawStar()
this.drawhouse()
this.drawPoint()
this.drawRect()
this.drawArcTo()
},
onUnload() {
y = 160
},
methods: {
drawText() {
let element = uni.getElementById('draw-text-view')!
let ctx = element.getDrawableContext()!
let width = element.getBoundingClientRect().width
ctx.reset()
ctx.font = "15px Arial"
ctx.textAlign = "center"
for (var i = 0; i < this.texts.length; i++) {
let value = this.texts[i]
if (i % 2 == 0) {
ctx.fillText(value, width / 2, (20 * (i + 1)))
} else {
ctx.lineWidth = 0.5
ctx.strokeText(value, width / 2, (20 * (i + 1)))
}
}
ctx.update()
},
drawLines() {
let ctx = uni.getElementById('draw-line-view')!.getDrawableContext()!
ctx.reset()
ctx.lineWidth = 10;
["round", "bevel", "miter"].forEach((join, i) => {
ctx.lineJoin = join;
ctx.beginPath();
ctx.moveTo(5, 10 + i * 40);
ctx.lineTo(50, 50 + i * 40);
ctx.lineTo(90, 10 + i * 40);
ctx.lineTo(130, 50 + i * 40);
ctx.lineTo(170, 10 + i * 40);
ctx.stroke();
});
ctx.lineWidth = 1
var space = 170
ctx.strokeStyle = '#09f';
ctx.beginPath();
ctx.moveTo(10 + space, 10);
ctx.lineTo(140 + space, 10);
ctx.moveTo(10 + space, 140);
ctx.lineTo(140 + space, 140);
ctx.stroke();
// Draw lines
ctx.strokeStyle = 'black';
['butt', 'round', 'square'].forEach((lineCap, i) => {
ctx.lineWidth = 15;
ctx.lineCap = lineCap;
ctx.beginPath();
ctx.moveTo(25 + space + i * 50, 10);
ctx.lineTo(25 + space + i * 50, 140);
ctx.stroke();
});
ctx.lineWidth = 1;
this.drawDashedLine([], ctx);
this.drawDashedLine([2, 2], ctx);
this.drawDashedLine([10, 10], ctx);
this.drawDashedLine([20, 5], ctx);
this.drawDashedLine([15, 3, 3, 3], ctx);
this.drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3], ctx);
ctx.lineDashOffset = 18;
this.drawDashedLine([12, 3, 3], ctx);
ctx.lineDashOffset = 0
ctx.setLineDash([0])
ctx.update()
},
drawDashedLine(pattern : Array<number>, ctx : DrawableContext) {
ctx.beginPath();
ctx.setLineDash(pattern);
ctx.moveTo(0, y);
ctx.lineTo(300, y);
ctx.stroke();
y += 15;
},
drawCircles() {
let ctx = uni.getElementById('draw-circle-view')!.getDrawableContext()!
ctx.reset()
// Draw shapes
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 3; j++) {
ctx.beginPath();
var x = 25 + j * 50; // x coordinate
var y = 25 + i * 50; // y coordinate
var radius = 20; // Arc radius
var startAngle = 0; // Starting point on circle
var endAngle = Math.PI + (Math.PI * j) / 2; // End point on circle
var clockwise = i % 2 == 0 ? false : true; // clockwise or anticlockwise
ctx.arc(x, y, radius, startAngle, endAngle, clockwise);
if (i > 1) {
ctx.fill();
} else {
ctx.stroke();
}
}
}
ctx.update()
},
drawStar() {
let ctx = uni.getElementById('draw-dash-line')!.getDrawableContext()!
ctx.reset()
ctx.beginPath();
var horn = 5; // 画5个角
var angle = 360 / horn; // 五个角的度数
// 两个圆的半径
var R = 50;
var r = 20;
// 坐标
var x = 100;
var y = 100;
for (var i = 0; i < horn; i++) {
// 角度转弧度:角度/180*Math.PI
// 外圆顶点坐标
ctx.lineTo(Math.cos((18 + i * angle) / 180.0 * Math.PI) * R + x, -Math.sin((18 + i * angle) / 180.0 * Math.PI) * R + y);
// 內圆顶点坐标
ctx.lineTo(Math.cos((54 + i * angle) / 180.0 * Math.PI) * r + x, -Math.sin((54 + i * angle) / 180.0 * Math.PI) * r + y);
}
// closePath:关闭路径,将路径的终点与起点相连
ctx.closePath();
ctx.lineWidth = 3;
ctx.fillStyle = '#E4EF00';
ctx.strokeStyle = "red";
ctx.fill();
ctx.stroke();
ctx.lineWidth = 10;
ctx.beginPath()
ctx.moveTo(170, 100)
ctx.lineTo(255, 15)
ctx.lineTo(340, 100)
ctx.closePath()
ctx.fill()
ctx.strokeStyle = "blue"
ctx.stroke()
ctx.beginPath()
ctx.moveTo(170, 145)
ctx.lineTo(255, 45)
ctx.lineTo(340, 145)
ctx.closePath()
ctx.fill()
ctx.strokeStyle = "gray"
ctx.stroke()
// 未设置beginPath,导致上下表现一致,与前端一致
ctx.moveTo(170, 190)
ctx.lineTo(255, 90)
ctx.lineTo(340, 190)
ctx.closePath()
ctx.fillStyle = "orange"
ctx.fill()
ctx.strokeStyle = "khaki"
ctx.stroke()
ctx.update()
},
hex(num : number) : string {
if (num == 0) {
return "00"
}
let hexChars = "0123456789ABCDEF";
let result = "";
while (num > 0) {
let remainder = Math.floor(num) % 16;
result = hexChars[remainder] + result;
num = Math.floor(Math.floor(num) / 16);
}
if (result.length == 1) {
return "0" + result
}
return result
},
drawhouse() {
let ctx = uni.getElementById('draw-house')!.getDrawableContext()!
ctx.reset()
ctx.lineWidth = 10;
// Wall
ctx.strokeRect(75, 140, 150, 110);
// Door
ctx.fillRect(130, 190, 40, 60);
// Roof
ctx.beginPath();
ctx.moveTo(50, 140);
ctx.lineTo(150, 60);
ctx.lineTo(250, 140);
ctx.closePath();
ctx.stroke();
ctx.update()
},
drawPoint() {
let ctx = uni.getElementById('draw-style')!.getDrawableContext()!
ctx.reset()
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 6; j++) {
ctx.strokeStyle = `rgb(0,${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)})`;
ctx.beginPath();
ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
ctx.stroke();
}
}
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 6; j++) {
ctx.fillStyle = `rgb(${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)},0)`;
ctx.fillRect(180 + j * 25, i * 25, 25, 25);
}
}
ctx.update()
},
drawRect() {
let ctx = uni.getElementById('draw-odd')!.getDrawableContext()!
ctx.reset()
// Create path
ctx.moveTo(30, 90);
ctx.lineTo(110, 20);
ctx.lineTo(240, 130);
ctx.lineTo(60, 130);
ctx.lineTo(190, 20);
ctx.lineTo(270, 90);
ctx.closePath();
// Fill path
ctx.fillStyle = "green";
ctx.fill("evenodd");
ctx.update()
},
drawArcTo() {
let ctx = uni.getElementById('draw-arcto')!.getDrawableContext()!
ctx.reset()
ctx.beginPath();
ctx.moveTo(50, 20);
ctx.bezierCurveTo(230, 30, 150, 60, 50, 100);
ctx.stroke();
ctx.fillStyle = "blue";
// start point
ctx.fillRect(50, 20, 10, 10);
// end point
ctx.fillRect(50, 100, 10, 10);
ctx.fillStyle = "red";
// control point one
ctx.fillRect(230, 30, 10, 10);
// control point two
ctx.fillRect(150, 70, 10, 10);
ctx.update()
}
}
}
</script>
<style>
.drawing {
height: 275px;
background-color: lightgray;
margin-bottom: 15px;
}
</style>
<template>
<view id="snapshot-content">
<page-head title="对本页面根view截图"></page-head>
<view class="uni-padding-wrap">
<text>this is text</text>
</view>
<button class="uni-btn btn-TakeSnapshot" type="primary" @tap="takeSnapshotClick">
点击截图并替换显示下方图片
</button>
<image style="margin-left:auto;margin-right:auto;margin-top:20px;width:90%;" :src="snapImage" :mode="mode" @longpress="saveToAlbum"></image>
</view>
</template>
<script lang="uts">
export default {
data() {
return {
mode: "center",//aspectFit
snapImage: "/static/uni.png"
}
},
methods: {
takeSnapshotClick() {
const view = uni.getElementById('snapshot-content')!
view.takeSnapshot({
success: (res) => {
console.log(res.tempFilePath)
this.snapImage = res.tempFilePath
this.mode = 'widthFix'
uni.showToast({
title: '截图成功,路径:' + res.tempFilePath,
icon: "none"
})
},
fail: (res) => {
console.log(res)
uni.showToast({
icon: 'error',
title: '截图失败'
})
}
})
},
saveToAlbum(e : TouchEvent) {
// console.log(e.currentTarget!.getAttribute("src"));
let filePath : string = e.currentTarget!.getAttribute("src") as string
uni.showActionSheet({
itemList: ["保存"],
success: res => {
// console.log(res.tapIndex);
if (res.tapIndex == 0) {
uni.saveImageToPhotosAlbum({
filePath: filePath,
success() {
uni.showToast({
position: "center",
icon: "none",
title: "图片保存成功,请到手机相册查看"
})
},
fail(e) {
uni.showModal({
content: "保存相册失败,errCode:" + e.errCode + ",errMsg:" + e.errMsg + ",errSubject:" + e.errSubject,
showCancel: false
});
}
})
}
},
fail: () => { },
complete: () => { }
});
}
}
}
<template>
<view id="snapshot-content">
<page-head title="对本页面根view截图"></page-head>
<view class="uni-padding-wrap">
<text>this is text</text>
</view>
<button class="uni-btn btn-TakeSnapshot" type="primary" @tap="takeSnapshotClick">
点击截图并替换显示下方图片
</button>
<image style="margin-left:auto;margin-right:auto;margin-top:20px;width:90%;" :src="snapImage" :mode="mode"
@longpress="saveToAlbum"></image>
</view>
</template>
<script lang="uts">
export default {
data() {
return {
mode: "center",//aspectFit
snapImage: "/static/uni.png"
}
},
methods: {
takeSnapshotClick() {
const view = uni.getElementById('snapshot-content')!
view.takeSnapshot({
success: (res) => {
console.log(res.tempFilePath)
this.snapImage = res.tempFilePath
this.mode = 'widthFix'
uni.showToast({
title: '截图成功,路径:' + res.tempFilePath,
icon: "none"
})
},
fail: (res) => {
console.log(res)
uni.showToast({
icon: 'error',
title: '截图失败'
})
}
})
},
saveToAlbum(e : TouchEvent) {
// console.log(e.currentTarget!.getAttribute("src"));
let filePath : string = e.currentTarget!.getAttribute("src") as string
uni.showActionSheet({
itemList: ["保存"],
success: res => {
// console.log(res.tapIndex);
if (res.tapIndex == 0) {
uni.saveImageToPhotosAlbum({
filePath: filePath,
success() {
uni.showToast({
position: "center",
icon: "none",
title: "图片保存成功,请到手机相册查看"
})
},
fail(e) {
uni.showModal({
content: "保存相册失败,errCode:" + e.errCode + ",errMsg:" + e.errMsg + ",errSubject:" + e.errSubject,
showCancel: false
});
}
})
}
},
fail: () => { },
complete: () => { }
});
}
}
}
</script>
<template>
<!-- #ifdef APP -->
<text>操作日志</text><button size="mini" @click="log=''">清空日志</button>
<text style="margin: 2px; padding: 2px; border: 1px solid #000000;">{{ log }}</text>
<scroll-view style="flex: 1;">
<!-- #endif -->
<!-- #ifdef APP -->
<button class="btnstyle" type="primary" @tap="geAbsPath(sandboxPath)" id="btn-path">应用外置沙盒目录uni.env.SANDBOX_PATH</button>
<button class="btnstyle" type="primary" @tap="geAbsPath(cachePath)" id="btn-path">缓存文件目录uni.env.CACHE_PATH</button>
<button class="btnstyle" type="primary" @tap="geAbsPath(userPath)" id="btn-path">用户文件目录uni.env.USER_DATA_PATH</button>
<button class="btnstyle" type="primary" @tap="geAbsPath(internalSandboxPath)"
id="btn-path">应用内置沙盒目录uni.env.ANDROID_INTERNAL_SANDBOX_PATH</button>
<!-- #endif -->
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
export default {
data() {
return {
log: "",
userPath: uni.env.USER_DATA_PATH,
sandboxPath: uni.env.SANDBOX_PATH,
cachePath: uni.env.CACHE_PATH,
internalSandboxPath: uni.env.ANDROID_INTERNAL_SANDBOX_PATH,
}
},
onLoad() {
},
methods: {
geAbsPath(path ?: any) {
// #ifdef APP-ANDROID
this.log += UTSAndroid.convert2AbsFullPath(path as string) + '\n'
// #endif
}
}
}
</script>
<style>
.btnstyle {
margin: 4px;
}
<template>
<!-- #ifdef APP -->
<text>操作日志</text><button size="mini" @click="log=''">清空日志</button>
<text style="margin: 2px; padding: 2px; border: 1px solid #000000;">{{ log }}</text>
<scroll-view style="flex: 1;">
<!-- #endif -->
<!-- #ifdef APP -->
<button class="btnstyle" type="primary" @tap="geAbsPath(sandboxPath)"
id="btn-path">应用外置沙盒目录uni.env.SANDBOX_PATH</button>
<button class="btnstyle" type="primary" @tap="geAbsPath(cachePath)" id="btn-path">缓存文件目录uni.env.CACHE_PATH</button>
<button class="btnstyle" type="primary" @tap="geAbsPath(userPath)"
id="btn-path">用户文件目录uni.env.USER_DATA_PATH</button>
<button class="btnstyle" type="primary" @tap="geAbsPath(internalSandboxPath)"
id="btn-path">应用内置沙盒目录uni.env.ANDROID_INTERNAL_SANDBOX_PATH</button>
<!-- #endif -->
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
export default {
data() {
return {
log: "",
userPath: uni.env.USER_DATA_PATH,
sandboxPath: uni.env.SANDBOX_PATH,
cachePath: uni.env.CACHE_PATH,
internalSandboxPath: uni.env.ANDROID_INTERNAL_SANDBOX_PATH,
}
},
onLoad() {
},
methods: {
geAbsPath(path ?: any) {
// #ifdef APP-ANDROID
this.log += UTSAndroid.convert2AbsFullPath(path as string) + '\n'
// #endif
}
}
}
</script>
<style>
.btnstyle {
margin: 4px;
}
</style>
......@@ -77,4 +77,13 @@ describe('event-bus', () => {
const l3 = (await page.data()).log.length
expect(l3).toBe(0)
})
it('test return id', async () => {
await page.callMethod('clear')
expect((await page.data()).log.length).toBe(0)
await page.callMethod('testReturnId')
const logs = await page.data('log')
expect(logs.length).toBe(2)
expect(logs[0]).toBe('触发 test-return-id $on fn')
expect(logs[1]).toBe('触发 test-return-id $once fn')
})
})
......@@ -14,12 +14,13 @@
<view>
<view v-for="(item, index) in log" :key="index">{{ item }}</view>
</view>
<button @click="onObj">开始监听 obj 参数</button>
<button @click="emitWithObj">触发监听 obj 参数</button>
<view class="box">
<text>接收到的 obj 参数:</text>
<text>{{JSON.stringify(objArg)}}</text>
</view>
<button @click="onObj">开始监听 obj 参数</button>
<button @click="emitWithObj">触发监听 obj 参数</button>
<view class="box">
<text>接收到的 obj 参数:</text>
<text>{{JSON.stringify(objArg)}}</text>
</view>
<button @click="testReturnId">测试返回 id</button>
</view>
</view>
<!-- #ifdef APP -->
......@@ -49,7 +50,7 @@
uni.$on('test', this.fn2)
},
onObj() {
uni.$on('test-obj', (res: UTSJSONObject) => {
uni.$on('test-obj', (res : UTSJSONObject) => {
this.objArg = res
})
},
......@@ -71,6 +72,19 @@
clear() {
this.log.length = 0
},
testReturnId(){
const id1 = uni.$on('test-return-id', this.fn)
uni.$emit('test-return-id', '触发 test-return-id $on fn')
uni.$off('test-return-id', id1)
uni.$emit('test-return-id', '触发 test-return-id $on fn')
uni.$once('test-return-id', this.fn)
uni.$emit('test-return-id', '触发 test-return-id $once fn')
uni.$emit('test-return-id', '触发 test-return-id $once fn')
const id2 = uni.$once('test-id', this.fn)
uni.$off('test-return-id', id2)
uni.$emit('test-return-id', '触发 test-return-id $once fn')
}
},
}
</script>
......
此差异已折叠。
此差异已折叠。
<template>
<view>
<button @tap="exitAppClick">退出应用</button>
</view>
</template>
<script>
export default {
methods: {
exitAppClick:function(){
uni.exit({
success:function(res){
console.log(res)
}
})
}
}
}
</script>
<style>
</style>
\ No newline at end of file
<template>
<view>
<button @tap="exitAppClick">退出应用</button>
</view>
</template>
<script>
export default {
methods: {
exitAppClick: function () {
uni.exit({
success: function (res) {
console.log(res)
}
})
}
}
}
</script>
<style>
</style>
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册