Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
hello uni-app x
提交
9d291587
H
hello uni-app x
项目概览
DCloud
/
hello uni-app x
通知
5892
Star
88
Fork
161
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
16
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hello uni-app x
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
16
Issue
16
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
9d291587
编写于
8月 05, 2024
作者:
辛宝Otto
🥊
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'dev' into alpha
上级
6fd26c3f
ab3dfc2c
变更
34
展开全部
隐藏空白更改
内联
并排
Showing
34 changed file
with
2213 addition
and
2360 deletion
+2213
-2360
App.uvue
App.uvue
+146
-146
pages.json
pages.json
+25
-2
pages/API/cancelAnimationFrame/cancelAnimationFrame.test.js
pages/API/cancelAnimationFrame/cancelAnimationFrame.test.js
+25
-0
pages/API/cancelAnimationFrame/cancelAnimationFrame.uvue
pages/API/cancelAnimationFrame/cancelAnimationFrame.uvue
+46
-0
pages/API/canvas/canvas.uvue
pages/API/canvas/canvas.uvue
+0
-460
pages/API/create-canvas-context-async/child-canvas.uvue
pages/API/create-canvas-context-async/child-canvas.uvue
+43
-41
pages/API/create-canvas-context-async/create-canvas-context-async.test.js
...-canvas-context-async/create-canvas-context-async.test.js
+25
-25
pages/API/create-canvas-context-async/create-canvas-context-async.uvue
...ate-canvas-context-async/create-canvas-context-async.uvue
+944
-52
pages/API/create-selector-query/create-selector-query.test.js
...s/API/create-selector-query/create-selector-query.test.js
+24
-1
pages/API/create-selector-query/create-selector-query.uvue
pages/API/create-selector-query/create-selector-query.uvue
+218
-180
pages/API/get-enter-options-sync/get-enter-options-sync.test.js
...API/get-enter-options-sync/get-enter-options-sync.test.js
+10
-0
pages/API/get-enter-options-sync/get-enter-options-sync.uvue
pages/API/get-enter-options-sync/get-enter-options-sync.uvue
+26
-0
pages/API/get-launch-options-sync/get-launch-options-sync.test.js
...I/get-launch-options-sync/get-launch-options-sync.test.js
+2
-14
pages/API/get-launch-options-sync/get-launch-options-sync.uvue
.../API/get-launch-options-sync/get-launch-options-sync.uvue
+53
-76
pages/API/requestAnimationFrame/requestAnimationFrame.test.js
...s/API/requestAnimationFrame/requestAnimationFrame.test.js
+16
-0
pages/API/requestAnimationFrame/requestAnimationFrame.uvue
pages/API/requestAnimationFrame/requestAnimationFrame.uvue
+35
-0
pages/API/show-toast/show-toast.test.js
pages/API/show-toast/show-toast.test.js
+35
-153
pages/API/show-toast/show-toast.uvue
pages/API/show-toast/show-toast.uvue
+121
-64
pages/component/canvas/canvas.uvue
pages/component/canvas/canvas.uvue
+23
-855
pages/component/canvas/canvas/ball.uvue
pages/component/canvas/canvas/ball.uvue
+8
-33
pages/component/canvas/canvas/doodle.uvue
pages/component/canvas/canvas/doodle.uvue
+69
-70
pages/component/object/object.uvue
pages/component/object/object.uvue
+3
-3
pages/tabBar/API.uvue
pages/tabBar/API.uvue
+51
-40
pages/tabBar/CSS.uvue
pages/tabBar/CSS.uvue
+61
-52
pages/tabBar/component.uvue
pages/tabBar/component.uvue
+59
-50
pages/tabBar/generateMenu.uts
pages/tabBar/generateMenu.uts
+36
-25
pages/tabBar/template.uvue
pages/tabBar/template.uvue
+7
-5
uni_modules/uni-time-picker/utssdk/app-ios/config.json
uni_modules/uni-time-picker/utssdk/app-ios/config.json
+3
-0
uni_modules/uni-time-picker/utssdk/app-ios/index.uts
uni_modules/uni-time-picker/utssdk/app-ios/index.uts
+84
-0
uni_modules/uni-upgrade-center-app/changelog.md
uni_modules/uni-upgrade-center-app/changelog.md
+2
-0
uni_modules/uni-upgrade-center-app/components/uni-upgrade-center-app/uni-upgrade-center-app.uvue
...onents/uni-upgrade-center-app/uni-upgrade-center-app.uvue
+1
-1
uni_modules/uni-upgrade-center-app/package.json
uni_modules/uni-upgrade-center-app/package.json
+1
-1
uni_modules/uni-upgrade-center-app/utils/check-update.ts
uni_modules/uni-upgrade-center-app/utils/check-update.ts
+1
-1
windows/top-window.uvue
windows/top-window.uvue
+10
-10
未找到文件。
App.uvue
浏览文件 @
9d291587
<script lang="uts">
import { state, setLifeCycleNum } from '@/store/index.uts'
// #ifdef APP-ANDROID
let firstBackTime = 0
// #endif
export default {
globalData: {
str: 'default globalData str',
num: 0,
bool: false,
obj: {
str: 'default globalData obj str',
num: 0,
bool: false,
},
null: null as string | null,
arr: [] as number[],
mySet: new Set<string>(),
myMap: new Map<string, any>(),
func: () : string => {
return 'globalData func'
},
launchOptions: {
path: '',
} as OnLaunchOptions,
onShowOption: {
path: ''
} as OnShowOptions
},
onLaunch: function (res : OnLaunchOptions) {
this.globalData.launchOptions = res
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1000)
console.log('App Launch')
// 页面性能分析
// const performance = uni.getPerformance()
// const observer1: PerformanceObserver = performance.createObserver(
// (entryList: PerformanceObserverEntryList) => {
// console.log('observer1:entryList.getEntries()' +JSON.stringify(entryList.getEntries()))
// }
// )
// observer1.observe({
// entryTypes: ['render', 'navigation'],
// } as PerformanceObserverOptions)
},
onShow: function (res : OnShowOptions) {
this.globalData.onShowOption = res
<script lang="uts">
import { state, setLifeCycleNum } from '@/store/index.uts'
// 处理scheme或通用链接直达
let url = this.getRedirectUrl(res.appScheme, res.appLink);
if (null != url) {
uni.navigateTo({
url: url
})
}
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 100)
console.log('App Show')
},
onHide: function () {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 100)
console.log('App Hide')
},
// #ifdef APP-ANDROID
onLastPageBackPress: function () {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 1000)
console.log('App LastPageBackPress')
if (firstBackTime == 0) {
uni.showToast({
title: '再按一次退出应用',
position: 'bottom',
})
firstBackTime = Date.now()
setTimeout(() => {
firstBackTime = 0
}, 2000)
} else if (Date.now() - firstBackTime < 2000) {
firstBackTime = Date.now()
uni.exit()
}
},
onExit() {
console.log('App Exit')
},
// #endif
methods: {
increasetLifeCycleNum() {
setLifeCycleNum(state.lifeCycleNum + 100)
console.log('App increasetLifeCycleNum')
},
getRedirectUrl(scheme : string | null, ulink : string | null) : string | null {
//解析scheme或universal link启动直达页面:
//scheme格式:uniappx://redirect/pages/component/view/view?key=value //其中redirect后为页面路径
//universal link格式:https://uniappx.dcloud.net.cn/ulink/redirect.html?url=%2Fpages%2Fcomponent%2Fview%2Fview%3Fkey%3Dvalue //通用链接路径需固定,?后面的url参数为直达页面路径,注意url字段值需做url编码(可使用encodeURIComponent方法)
let url : string | null = null;
if (null != scheme && scheme.length > 0) {
const PATHPRE = 'redirect';
let parts : string | null = null;
let pos = scheme.search('//');
if (pos > 0) {
parts = scheme.substring(pos + 2);
}
if (null != parts && parts.startsWith(PATHPRE)) {
url = parts.substring(PATHPRE.length);
}
} else if (null != ulink && ulink.length > 0) {
const PATH = 'ulink/redirect.html';
let parts = ulink.split('?');
if (parts.length > 1 && parts[0].endsWith(PATH) && parts[1].length > 0) {
parts[1].split('&').forEach((e) => {
let params = e.split('=');
if (params.length > 1 && params[0].length > 0 && params[1].length > 0) {
if ('url' == params[0]) {
if (null == url) {
url = decodeURIComponent(params[1]);
}
}
}
});
}
}
return url;
}
}
}
</script>
<style>
/*每个页面公共css */
@import "./common/uni.css";
/* #ifdef WEB */
.uni-top-window uni-tabbar .uni-tabbar {
background-color: #fff !important;
}
.uni-app--showleftwindow .uni-page-head-btn {
display: none !important;
}
/* #endif */
// #ifdef APP-ANDROID
let firstBackTime = 0
// #endif
export default {
globalData: {
str: 'default globalData str',
num: 0,
bool: false,
obj: {
str: 'default globalData obj str',
num: 0,
bool: false,
},
null: null as string | null,
arr: [] as number[],
mySet: new Set<string>(),
myMap: new Map<string, any>(),
func: () : string => {
return 'globalData func'
},
launchOptions: {
path: '',
} as OnLaunchOptions,
onShowOption: {
path: ''
} as OnShowOptions
},
onLaunch: function (res : OnLaunchOptions) {
this.globalData.launchOptions = res
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1000)
console.log('App Launch')
// 页面性能分析
// const performance = uni.getPerformance()
// const observer1: PerformanceObserver = performance.createObserver(
// (entryList: PerformanceObserverEntryList) => {
// console.log('observer1:entryList.getEntries()' +JSON.stringify(entryList.getEntries()))
// }
// )
// observer1.observe({
// entryTypes: ['render', 'navigation'],
// } as PerformanceObserverOptions)
},
onShow: function (res : OnShowOptions) {
this.globalData.onShowOption = res
// 处理scheme或通用链接直达
let url = this.getRedirectUrl(res.appScheme, res.appLink);
if (null != url) {
uni.navigateTo({
url: url
})
}
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 100)
console.log('App Show')
},
onHide: function () {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 100)
console.log('App Hide')
},
// #ifdef APP-ANDROID
onLastPageBackPress: function () {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 1000)
console.log('App LastPageBackPress')
if (firstBackTime == 0) {
uni.showToast({
title: '再按一次退出应用',
position: 'bottom',
})
firstBackTime = Date.now()
setTimeout(() => {
firstBackTime = 0
}, 2000)
} else if (Date.now() - firstBackTime < 2000) {
firstBackTime = Date.now()
uni.exit()
}
},
onExit() {
console.log('App Exit')
},
// #endif
methods: {
increasetLifeCycleNum() {
setLifeCycleNum(state.lifeCycleNum + 100)
console.log('App increasetLifeCycleNum')
},
getRedirectUrl(scheme : string | null, ulink : string | null) : string | null {
//解析scheme或universal link启动直达页面:
//scheme格式:uniappx://redirect/pages/component/view/view?key=value //其中redirect后为页面路径
//universal link格式:https://uniappx.dcloud.net.cn/ulink/redirect.html?url=%2Fpages%2Fcomponent%2Fview%2Fview%3Fkey%3Dvalue //通用链接路径需固定,?后面的url参数为直达页面路径,注意url字段值需做url编码(可使用encodeURIComponent方法)
let url : string | null = null;
if (null != scheme && scheme.length > 0) {
const PATHPRE = 'redirect';
let parts : string | null = null;
let pos = scheme.search('//');
if (pos > 0) {
parts = scheme.substring(pos + 2);
}
if (null != parts && parts.startsWith(PATHPRE)) {
url = parts.substring(PATHPRE.length);
}
} else if (null != ulink && ulink.length > 0) {
const PATH = 'ulink/redirect.html';
let parts = ulink.split('?');
if (parts.length > 1 && parts[0].endsWith(PATH) && parts[1].length > 0) {
parts[1].split('&').forEach((e) => {
let params = e.split('=');
if (params.length > 1 && params[0].length > 0 && params[1].length > 0) {
if ('url' == params[0]) {
if (null == url) {
url = decodeURIComponent(params[1]);
}
}
}
});
}
}
return url;
}
}
}
</script>
<style>
/*每个页面公共css */
@import "./common/uni.css";
/* #ifdef WEB */
.uni-top-window uni-tabbar .uni-tabbar {
background-color: #fff !important;
}
.uni-app--showleftwindow .uni-page-head-btn {
display: none !important;
}
/* #endif */
</style>
pages.json
浏览文件 @
9d291587
...
...
@@ -543,6 +543,25 @@
"navigationBarTitleText"
:
"getLaunchOptionsSync | 获取启动参数"
}
},
{
"path"
:
"pages/API/get-enter-options-sync/get-enter-options-sync"
,
"group"
:
"1,1,4,1"
,
"style"
:
{
"navigationBarTitleText"
:
"getEnterOptionsSync | 获取本次启动时的参数"
}
},
{
"path"
:
"pages/API/requestAnimationFrame/requestAnimationFrame"
,
"style"
:
{
"navigationBarTitleText"
:
"requestAnimationFrame | 请求帧动画队列"
}
},
{
"path"
:
"pages/API/cancelAnimationFrame/cancelAnimationFrame"
,
"style"
:
{
"navigationBarTitleText"
:
"cancelAnimationFrame | 取消已加入的帧动画队列"
}
},
{
"path"
:
"pages/API/navigator/navigator"
,
"group"
:
"1,2,0"
,
...
...
@@ -1787,7 +1806,7 @@
"pagePath"
:
"pages/tabBar/component"
,
"iconPath"
:
"@tabBarComponentIconPath"
,
"selectedIconPath"
:
"@tabBarComponentSelectedIconPath"
,
"text"
:
"
内置
组件"
"text"
:
"组件"
},
{
"pagePath"
:
"pages/tabBar/API"
,
...
...
@@ -2067,6 +2086,10 @@
{
"id"
:
"api.base.launch.getLaunchOptionsSync"
,
"name"
:
"getLaunchOptionsSync"
},
{
"id"
:
"api.base.launch.getEnterOptionsSync"
,
"name"
:
"getEnterOptionsSync"
}
]
},
...
...
@@ -2736,4 +2759,4 @@
]
}
]
}
\ No newline at end of file
}
pages/API/cancelAnimationFrame/cancelAnimationFrame.test.js
0 → 100644
浏览文件 @
9d291587
const
PAGE_PATH
=
'
/pages/API/cancelAnimationFrame/cancelAnimationFrame
'
describe
(
'
API-cancelAnimationFrame
'
,
()
=>
{
let
page
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
PAGE_PATH
)
await
page
.
waitFor
(
600
);
});
it
(
'
cancelAnimationFrame
'
,
async
()
=>
{
await
page
.
callMethod
(
'
startRequestAnimationFrame
'
)
await
page
.
waitFor
(
100
)
const
data1
=
await
page
.
data
()
expect
(
data1
.
testFrameCount
>
0
).
toBe
(
true
)
await
page
.
callMethod
(
'
stopRequestAnimationFrame
'
)
await
page
.
waitFor
(
100
)
const
data2
=
await
page
.
data
()
const
testFrameCount
=
data2
.
testFrameCount
await
page
.
waitFor
(
100
)
const
data3
=
await
page
.
data
()
expect
(
data3
.
testFrameCount
).
toBe
(
testFrameCount
)
});
});
pages/API/cancelAnimationFrame/cancelAnimationFrame.uvue
0 → 100644
浏览文件 @
9d291587
<template>
<view class="page">
<page-head :title="title"></page-head>
<button @click="startRequestAnimationFrame">requestAnimationFrame</button>
<button @click="stopRequestAnimationFrame">cancelAnimationFrame</button>
<text class="frame-count">{{testFrameCount}}</text>
</view>
</template>
<script>
export default {
data() {
return {
title: 'cancelAnimationFrame',
taskId: 0,
testFrameCount: 0
}
},
onUnload() {
if (this.taskId > 0) {
this.stopRequestAnimationFrame()
}
},
methods: {
startRequestAnimationFrame() {
this.taskId = uni.requestAnimationFrame((_ : number) => {
this.testFrameCount++
this.startRequestAnimationFrame()
})
},
stopRequestAnimationFrame() {
uni.cancelAnimationFrame(this.taskId)
}
}
}
</script>
<style>
.page {
padding: 15px;
}
.frame-count {
margin-top: 15px;
}
</style>
pages/API/canvas/canvas.uvue
已删除
100644 → 0
浏览文件 @
6fd26c3f
<template>
<view class="page">
<page-head :title="title"></page-head>
<canvas class="canvas-element" canvas-id="canvas" id="canvas"></canvas>
<scroll-view class="scroll-view">
<view class="grid-view">
<view class="grid-item" v-for="(name, index) in names" :key="index">
<button class="canvas-drawing-button" @click="handleCanvasButton(name)">{{name}}</button>
</view>
</view>
<button class="btn-to-image" @click="toTempFilePath" type="primary">toTempFilePath</button>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'createContext',
names: ["rotate", "scale", "reset", "translate", "save", "restore", "drawImage", "fillText", "fill",
"stroke", "clearRect", "beginPath", "closePath", "moveTo", "lineTo", "rect", "arc",
"quadraticCurveTo", "bezierCurveTo", "setFillStyle", "setStrokeStyle", "setGlobalAlpha",
"setShadow", "setFontSize", "setLineCap", "setLineJoin", "setLineWidth", "setMiterLimit"
],
// TODO 缺失 CanvasContext
canvasContext: null as any | null
}
},
onReady() {
// @ts-ignore
this.canvasContext = uni.createCanvasContext('canvas', this)
},
methods: {
toTempFilePath() {
// TODO 缺失
// uni.canvasToTempFilePath({
// canvasId: 'canvas',
// success: (res) => {
// console.log(res.tempFilePath)
// },
// fail: (err) => {
// console.error(JSON.stringify(err))
// }
// })
},
handleCanvasButton(name : string) {
switch (name) {
case "rotate":
this.rotate();
break;
case "scale":
this.scale();
break;
case "reset":
this.reset();
break;
case "translate":
this.translate();
break;
case "save":
this.save();
break;
case "restore":
this.restore();
break;
case "drawImage":
this.drawImage();
break;
case "fillText":
this.fillText();
break;
case "fill":
this.fill();
break;
case "stroke":
this.stroke();
break;
case "clearRect":
this.clearRect();
break;
case "beginPath":
this.beginPath();
break;
case "closePath":
this.closePath();
break;
case "moveTo":
this.moveTo();
break;
case "lineTo":
this.lineTo();
break;
case "rect":
this.rect();
break;
case "arc":
this.arc();
break;
case "quadraticCurveTo":
this.quadraticCurveTo();
break;
case "bezierCurveTo":
this.bezierCurveTo();
break;
case "setFillStyle":
this.setFillStyle();
break;
case "setStrokeStyle":
this.setStrokeStyle();
break;
case "setGlobalAlpha":
this.setGlobalAlpha();
break;
case "setShadow":
this.setShadow();
break;
case "setFontSize":
this.setFontSize();
break;
case "setLineCap":
this.setLineCap();
break;
case "setLineJoin":
this.setLineJoin();
break;
case "setLineWidth":
this.setLineWidth();
break;
case "setMiterLimit":
this.setMiterLimit();
break;
default:
break;
}
},
rotate() {
this.canvasContext!.beginPath()
this.canvasContext!.rotate(10 * Math.PI / 180)
this.canvasContext!.rect(225, 75, 20, 10)
this.canvasContext!.fill()
this.canvasContext!.draw()
},
scale() {
this.canvasContext!.beginPath()
this.canvasContext!.rect(25, 25, 50, 50)
this.canvasContext!.stroke()
this.canvasContext!.scale(2, 2)
this.canvasContext!.beginPath()
this.canvasContext!.rect(25, 25, 50, 50)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
reset() {
this.canvasContext!.beginPath()
this.canvasContext!.setFillStyle('#000000')
this.canvasContext!.setStrokeStyle('#000000')
this.canvasContext!.setFontSize(10)
this.canvasContext!.setGlobalAlpha(1)
this.canvasContext!.setShadow(0, 0, 0, 'rgba(0, 0, 0, 0)')
this.canvasContext!.setLineCap('butt')
this.canvasContext!.setLineJoin('miter')
this.canvasContext!.setLineWidth(1)
this.canvasContext!.setMiterLimit(10)
this.canvasContext!.draw()
},
translate() {
this.canvasContext!.beginPath()
this.canvasContext!.rect(10, 10, 100, 50)
this.canvasContext!.fill()
this.canvasContext!.translate(70, 70)
this.canvasContext!.beginPath()
this.canvasContext!.fill()
this.canvasContext!.draw()
},
save() {
this.canvasContext!.beginPath()
this.canvasContext!.setStrokeStyle('#00ff00')
this.canvasContext!.save()
this.canvasContext!.scale(2, 2)
this.canvasContext!.setStrokeStyle('#ff0000')
this.canvasContext!.rect(0, 0, 100, 100)
this.canvasContext!.stroke()
this.canvasContext!.restore()
this.canvasContext!.rect(0, 0, 50, 50)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
restore() {
[3, 2, 1].forEach((item) => {
this.canvasContext!.beginPath()
this.canvasContext!.save()
this.canvasContext!.scale(item, item)
this.canvasContext!.rect(10, 10, 100, 100)
this.canvasContext!.stroke()
this.canvasContext!.restore()
});
this.canvasContext!.draw()
},
drawImage() {
// #ifdef APP-PLUS
this.canvasContext!.drawImage('../../../static/app-plus/uni@2x.png', 0, 0)
// #endif
// #ifndef APP-PLUS
this.canvasContext!.drawImage('../../../static/uni.png', 0, 0)
// #endif
this.canvasContext!.draw()
},
fillText() {
this.canvasContext!.setStrokeStyle('#ff0000')
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(0, 10)
this.canvasContext!.lineTo(300, 10)
this.canvasContext!.stroke()
// this.canvasContext!.save()
// this.canvasContext!.scale(1.5, 1.5)
// this.canvasContext!.translate(20, 20)
this.canvasContext!.setFontSize(10)
this.canvasContext!.fillText('Hello World', 0, 30)
this.canvasContext!.setFontSize(20)
this.canvasContext!.fillText('Hello World', 100, 30)
// this.canvasContext!.restore()
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(0, 30)
this.canvasContext!.lineTo(300, 30)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
fill() {
this.canvasContext!.beginPath()
this.canvasContext!.rect(20, 20, 150, 100)
this.canvasContext!.setStrokeStyle('#00ff00')
this.canvasContext!.fill()
this.canvasContext!.draw()
},
stroke() {
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(20, 20)
this.canvasContext!.lineTo(20, 100)
this.canvasContext!.lineTo(70, 100)
this.canvasContext!.setStrokeStyle('#00ff00')
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
clearRect() {
this.canvasContext!.setFillStyle('#ff0000')
this.canvasContext!.beginPath()
this.canvasContext!.rect(0, 0, 300, 150)
this.canvasContext!.fill()
this.canvasContext!.clearRect(20, 20, 100, 50)
this.canvasContext!.draw()
},
beginPath() {
this.canvasContext!.beginPath()
this.canvasContext!.setLineWidth(5)
this.canvasContext!.setStrokeStyle('#ff0000')
this.canvasContext!.moveTo(0, 75)
this.canvasContext!.lineTo(250, 75)
this.canvasContext!.stroke()
this.canvasContext!.beginPath()
this.canvasContext!.setStrokeStyle('#0000ff')
this.canvasContext!.moveTo(50, 0)
this.canvasContext!.lineTo(150, 130)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
closePath() {
this.canvasContext!.beginPath()
this.canvasContext!.setLineWidth(1)
this.canvasContext!.moveTo(20, 20)
this.canvasContext!.lineTo(20, 100)
this.canvasContext!.lineTo(70, 100)
this.canvasContext!.closePath()
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
moveTo() {
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(0, 0)
this.canvasContext!.lineTo(300, 150)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
lineTo() {
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(20, 20)
this.canvasContext!.lineTo(20, 100)
this.canvasContext!.lineTo(70, 100)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
rect() {
this.canvasContext!.beginPath()
this.canvasContext!.rect(20, 20, 150, 100)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
arc() {
this.canvasContext!.beginPath()
this.canvasContext!.setLineWidth(2)
this.canvasContext!.arc(75, 75, 50, 0, Math.PI * 2, true)
this.canvasContext!.moveTo(110, 75)
this.canvasContext!.arc(75, 75, 35, 0, Math.PI, false)
this.canvasContext!.moveTo(65, 65)
this.canvasContext!.arc(60, 65, 5, 0, Math.PI * 2, true)
this.canvasContext!.moveTo(95, 65)
this.canvasContext!.arc(90, 65, 5, 0, Math.PI * 2, true)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
quadraticCurveTo() {
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(20, 20)
this.canvasContext!.quadraticCurveTo(20, 100, 200, 20)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
bezierCurveTo() {
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(20, 20)
this.canvasContext!.bezierCurveTo(20, 100, 200, 100, 200, 20)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
setFillStyle() {
['#fef957', 'rgb(242,159,63)', 'rgb(242,117,63)', '#e87e51'].forEach((item : string, index : number) => {
this.canvasContext!.setFillStyle(item)
this.canvasContext!.beginPath()
this.canvasContext!.rect(0 + 75 * index, 0, 50, 50)
this.canvasContext!.fill()
})
this.canvasContext!.draw()
},
setStrokeStyle() {
['#fef957', 'rgb(242,159,63)', 'rgb(242,117,63)', '#e87e51'].forEach((item : string, index : number) => {
this.canvasContext!.setStrokeStyle(item)
this.canvasContext!.beginPath()
this.canvasContext!.rect(0 + 75 * index, 0, 50, 50)
this.canvasContext!.stroke()
})
this.canvasContext!.draw()
},
setGlobalAlpha() {
this.canvasContext!.setFillStyle('#000000');
[1, 0.5, 0.1].forEach((item : number, index : number) => {
this.canvasContext!.setGlobalAlpha(item)
this.canvasContext!.beginPath()
this.canvasContext!.rect(0 + 75 * index, 0, 50, 50)
this.canvasContext!.fill()
})
this.canvasContext!.draw()
this.canvasContext!.setGlobalAlpha(1)
},
setShadow() {
this.canvasContext!.beginPath()
this.canvasContext!.setShadow(10, 10, 10, 'rgba(0, 0, 0, 199)')
this.canvasContext!.rect(10, 10, 100, 100)
this.canvasContext!.fill()
this.canvasContext!.draw()
},
setFontSize() {
[10, 20, 30, 40].forEach((item : number, index : number) => {
this.canvasContext!.setFontSize(item)
this.canvasContext!.fillText('Hello, world', 20, 20 + 40 * index)
})
this.canvasContext!.draw()
},
setLineCap() {
this.canvasContext!.setLineWidth(10);
['butt', 'round', 'square'].forEach((item : string, index : number) => {
this.canvasContext!.beginPath()
this.canvasContext!.setLineCap(item)
this.canvasContext!.moveTo(20, 20 + 20 * index)
this.canvasContext!.lineTo(100, 20 + 20 * index)
this.canvasContext!.stroke()
})
this.canvasContext!.draw()
},
setLineJoin() {
this.canvasContext!.setLineWidth(10);
['bevel', 'round', 'miter'].forEach((item : string, index : number) => {
this.canvasContext!.beginPath()
this.canvasContext!.setLineJoin(item)
this.canvasContext!.moveTo(20 + 80 * index, 20)
this.canvasContext!.lineTo(100 + 80 * index, 50)
this.canvasContext!.lineTo(20 + 80 * index, 100)
this.canvasContext!.stroke()
})
this.canvasContext!.draw()
},
setLineWidth() {
[2, 4, 6, 8, 10].forEach((item : number, index : number) => {
this.canvasContext!.beginPath()
this.canvasContext!.setLineWidth(item)
this.canvasContext!.moveTo(20, 20 + 20 * index)
this.canvasContext!.lineTo(100, 20 + 20 * index)
this.canvasContext!.stroke()
})
this.canvasContext!.draw()
},
setMiterLimit() {
this.canvasContext!.setLineWidth(4);
[2, 4, 6, 8, 10].forEach((item : number, index : number) => {
this.canvasContext!.beginPath()
this.canvasContext!.setMiterLimit(item)
this.canvasContext!.moveTo(20 + 80 * index, 20)
this.canvasContext!.lineTo(100 + 80 * index, 50)
this.canvasContext!.lineTo(20 + 80 * index, 100)
this.canvasContext!.stroke()
})
this.canvasContext!.draw()
}
}
}
</script>
<style>
.page {
flex: 1;
height: 100%;
overflow: hidden;
}
.scroll-view {
flex: 1;
padding-bottom: 50px;
}
.canvas-element {
width: 100%;
height: 250px;
background-color: #ffffff;
}
.grid-view {
padding: 10px;
flex-direction: row;
flex-wrap: wrap;
}
.grid-item {
width: 50%;
padding: 5px;
}
.btn-to-image {
margin: 10px;
}
</style>
pages/API/create-canvas-context-async/child-canvas.uvue
浏览文件 @
9d291587
<template>
<view>
<canvas class="child-canvas" id="canvas" style="height: 100px;border: 1px solid red;"></canvas> <view>isCanvasContextNull: {{isCanvasContextNull}}</view>
</view>
</template>
<script>
type getContext = {
ctx : boolean,
hasFillRect : boolean
}
export default {
data() {
return { isCanvasContextNull : false
}
},
mounted() {
this.$nextTick(() => {
uni.createCanvasContextAsync({
id: 'canvas',
component: this,
success: (res : CanvasContext) => {
const context = res.getContext('2d')!; this.isCanvasContextNull = true
// 若干绘制调用
// 绘制红色正方形
context.fillStyle = "rgb(200, 0, 0)";
context.fillRect(10, 10, 50, 50);
// 绘制蓝色半透明正方形
context.fillStyle = "rgba(0, 0, 200, 0.5)";
context.fillRect(30, 30, 50, 50);
context.draw();
}
})
})
}
}
</script>
\ No newline at end of file
<template>
<view>
<canvas class="child-canvas" id="canvas" style="height: 100px;border: 1px solid red;"></canvas>
<view>isCanvasContextNull: {{isCanvasContextNull}}</view>
</view>
</template>
<script>
type getContext = {
ctx : boolean,
hasFillRect : boolean
}
export default {
data() {
return {
isCanvasContextNull : false
}
},
mounted() {
this.$nextTick(() => {
uni.createCanvasContextAsync({
id: 'canvas',
component: this,
success: (res : CanvasContext) => {
const context = res.getContext('2d')!;
this.isCanvasContextNull = true
// 若干绘制调用
// 绘制红色正方形
context.fillStyle = "rgb(200, 0, 0)";
context.fillRect(10, 10, 50, 50);
// 绘制蓝色半透明正方形
context.fillStyle = "rgba(0, 0, 200, 0.5)";
context.fillRect(30, 30, 50, 50);
context.draw();
}
})
})
}
}
</script>
pages/API/create-canvas-context-async/create-canvas-context-async.test.js
浏览文件 @
9d291587
const
PAGE_PATH
=
'
/pages/API/create-canvas-context-async/create-canvas-context-async
'
describe
(
'
create-canvas-context-async
'
,
()
=>
{
let
page
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
PAGE_PATH
)
await
page
.
waitFor
(
'
view
'
)
})
it
(
'
page canvas
'
,
async
()
=>
{
await
page
.
waitFor
(
100
)
const
data
=
await
page
.
data
()
expect
(
data
.
isCanvasContextNull
).
toBe
(
true
)
})
it
(
'
component canvas
'
,
async
()
=>
{
// child-canvas
await
page
.
waitFor
(
100
)
// const element = await page.$('.node-child-component')
const
element
=
await
page
.
$
(
'
child-canvas
'
)
const
data
=
await
page
.
data
()
expect
(
data
.
isCanvasContextNull
).
toBe
(
true
)
})
})
\ No newline at end of file
const
PAGE_PATH
=
'
/pages/API/create-canvas-context-async/create-canvas-context-async
'
describe
(
'
create-canvas-context-async
'
,
()
=>
{
let
page
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
PAGE_PATH
)
await
page
.
waitFor
(
'
view
'
)
})
it
(
'
page canvas
'
,
async
()
=>
{
await
page
.
waitFor
(
100
)
const
data
=
await
page
.
data
()
expect
(
data
.
testCreateCanvasContextAsyncSuccess
).
toBe
(
true
)
})
it
(
'
component canvas
'
,
async
()
=>
{
// child-canvas
await
page
.
waitFor
(
100
)
// const element = await page.$('.node-child-component')
const
element
=
await
page
.
$
(
'
child-canvas
'
)
const
data
=
await
page
.
data
()
expect
(
data
.
isCanvasContextNull
).
toBe
(
true
)
})
})
pages/API/create-canvas-context-async/create-canvas-context-async.uvue
浏览文件 @
9d291587
此差异已折叠。
点击以展开。
pages/API/create-selector-query/create-selector-query.test.js
浏览文件 @
9d291587
...
...
@@ -66,6 +66,12 @@ describe('nodes-info', () => {
expect
(
pageData
.
selectAllCount
).
toBe
(
2
)
})
it
(
'
multi-child
'
,
async
()
=>
{
const
pageData
=
await
page
.
data
()
expect
(
pageData
.
selectCount
).
toBe
(
1
)
expect
(
pageData
.
selectAllCount
).
toBe
(
2
)
})
// #ifdef APP
//检测onResize获取BoundingClientRect信息是否有效
/* it('check_resizeRectValid', async () => {
...
...
@@ -74,6 +80,23 @@ describe('nodes-info', () => {
}) */
// #endif
it
(
'
test filelds
'
,
async
()
=>
{
if
(
process
.
env
.
uniTestPlatformInfo
.
startsWith
(
'
web
'
))
{
expect
(
true
).
toBe
(
true
)
}
else
{
const
pageData
=
await
page
.
data
()
expect
(
pageData
.
fieldsResultContainNode
).
toBe
(
true
)
}
})
it
(
'
test node
'
,
async
()
=>
{
if
(
process
.
env
.
uniTestPlatformInfo
.
startsWith
(
'
web
'
))
{
expect
(
true
).
toBe
(
true
)
}
else
{
const
pageData
=
await
page
.
data
()
expect
(
pageData
.
nodeResultContainNode
).
toBe
(
true
)
}
})
})
async
function
getRootNode
(
selector
)
{
...
...
@@ -89,4 +112,4 @@ async function getRootNode(selector) {
const
data
=
await
page
.
data
()
expect
(
data
.
rootNodeInfo
!=
null
).
toBe
(
true
)
}
}
pages/API/create-selector-query/create-selector-query.uvue
浏览文件 @
9d291587
<template>
<!-- #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>
</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>
</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>
<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 -->
</template>
<script>
<!-- #endif -->
</template>
<script>
import nodeChild from './nodes-info-child.uvue'
import multiChild from './selector-query-child-multi.uvue'
type NodeInfoType = {
left : number | null,
top : number | null,
right : number | null,
bottom : number | null,
width : number | null,
height : number | null,
}
export default {
components: {
import multiChild from './selector-query-child-multi.uvue'
type NodeInfoType = {
left : number | null,
top : number | null,
right : number | null,
bottom : number | null,
width : number | null,
height : number | null,
}
export default {
components: {
nodeChild,
multiChild
},
data() {
return {
title: 'createSelectorQuery',
nodeInfoList: [] as NodeInfoType[],
// 仅用于自动化测试
rootNodeInfo: null as NodeInfoType | null,
//供自动化测试使用
multiChild
},
data() {
return {
title: 'createSelectorQuery',
nodeInfoList: [] as NodeInfoType[],
// 仅用于自动化测试
rootNodeInfo: null as NodeInfoType | null,
//供自动化测试使用
// resizeRectValid: false
// TODO
selectCount: 0,
selectAllCount: 0,
}
selectAllCount: 0,
fieldsResultContainNode: false,
nodeResultContainNode: false
}
},
onReady() {
const instance2 = (this.$refs['multi-child'] as ComponentPublicInstance)
this.selectCount = instance2.$data['selectCount'] as Number
this.selectAllCount = instance2.$data['selectAllCount'] as Number
console.log('selectCount', selectCount, selectAllCount)
},
onResize() {
//供自动化测试使用
/* var rect12Element = uni.getElementById("rect-1-2")
if(rect12Element != null) {
var domRect = rect12Element.getBoundingClientRect()
if(domRect.width > 100) {
this.resizeRectValid = true
}
} */
},
methods: {
// 仅用于自动化测试
getRootNodeInfo(selector : string) {
uni.createSelectorQuery().select(selector).boundingClientRect().exec((ret) => {
if (ret.length == 1) {
const nodeInfo = ret[0] as NodeInfo;
const nodeType = {
left: nodeInfo.left,
top: nodeInfo.top,
right: nodeInfo.right,
bottom: nodeInfo.bottom,
width: nodeInfo.width,
height: nodeInfo.height,
} as NodeInfoType;
this.rootNodeInfo = nodeType
}
})
},
getNodeInfo() {
uni.createSelectorQuery().select('.rect1').boundingClientRect().exec((ret) => {
this.nodeInfoList.length = 0
const i = ret[0] as NodeInfo
this.nodeInfoList.push({
left: i.left,
top: i.top,
right: i.right,
bottom: i.bottom,
width: i.width,
height: i.height,
} as NodeInfoType)
})
},
getAllNodeInfo() {
uni.createSelectorQuery().selectAll('.rect').boundingClientRect().exec((ret) => {
this.nodeInfoList.length = 0
const array = ret[0] as NodeInfo[]
array.forEach((i) => {
this.nodeInfoList.push({
left: i.left,
top: i.top,
right: i.right,
bottom: i.bottom,
width: i.width,
height: i.height,
} as NodeInfoType)
})
})
}
}
}
</script>
<style>
.page {
padding: 15px;
}
.btn {
margin-top: 15px;
}
.rect-1-2 {
flex-direction: row;
margin-top: 15px;
}
.rect {
width: 150px;
height: 100px;
}
.rect1 {
background-color: dodgerblue;
}
.rect2 {
margin-left: auto;
background-color: seagreen;
}
.rect-info-1-2 {
flex-direction: row;
margin-top: 15px;
}
.rect-info {
flex: 1;
flex-direction: column;
}
.node-info-item {
flex-direction: row;
}
.node-info-item-k {
width: 72px;
line-height: 2;
}
.node-info-item-v {
font-weight: bold;
line-height: 2;
}
this.testFields()
this.testNode()
},
onResize() {
//供自动化测试使用
/* var rect12Element = uni.getElementById("rect-1-2")
if(rect12Element != null) {
var domRect = rect12Element.getBoundingClientRect()
if(domRect.width > 100) {
this.resizeRectValid = true
}
} */
},
methods: {
// 仅用于自动化测试
getRootNodeInfo(selector : string) {
uni.createSelectorQuery().select(selector).boundingClientRect().exec((ret) => {
if (ret.length == 1) {
const nodeInfo = ret[0] as NodeInfo;
const nodeType = {
left: nodeInfo.left,
top: nodeInfo.top,
right: nodeInfo.right,
bottom: nodeInfo.bottom,
width: nodeInfo.width,
height: nodeInfo.height,
} as NodeInfoType;
this.rootNodeInfo = nodeType
}
})
},
getNodeInfo() {
uni.createSelectorQuery().select('.rect1').boundingClientRect().exec((ret) => {
this.nodeInfoList.length = 0
const i = ret[0] as NodeInfo
this.nodeInfoList.push({
left: i.left,
top: i.top,
right: i.right,
bottom: i.bottom,
width: i.width,
height: i.height,
} as NodeInfoType)
})
},
getAllNodeInfo() {
uni.createSelectorQuery().selectAll('.rect').boundingClientRect().exec((ret) => {
this.nodeInfoList.length = 0
const array = ret[0] as NodeInfo[]
array.forEach((i) => {
this.nodeInfoList.push({
left: i.left,
top: i.top,
right: i.right,
bottom: i.bottom,
width: i.width,
height: i.height,
} as NodeInfoType)
})
})
},
// test .fields
testFields() {
uni.createSelectorQuery().select('.rect1').fields({
node: true
} as NodeField, (ret) => {
const isElement = (ret as NodeInfo).node instanceof UniElement
if(isElement){
this.fieldsResultContainNode = true
} else {
this.fieldsResultContainNode = false
}
}).exec()
},
// test .node
testNode() {
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
}
}).exec()
},
}
}
</script>
<style>
.page {
padding: 15px;
}
.btn {
margin-top: 15px;
}
.rect-1-2 {
flex-direction: row;
margin-top: 15px;
}
.rect {
width: 150px;
height: 100px;
}
.rect1 {
background-color: dodgerblue;
}
.rect2 {
margin-left: auto;
background-color: seagreen;
}
.rect-info-1-2 {
flex-direction: row;
margin-top: 15px;
}
.rect-info {
flex: 1;
flex-direction: column;
}
.node-info-item {
flex-direction: row;
}
.node-info-item-k {
width: 72px;
line-height: 2;
}
.node-info-item-v {
font-weight: bold;
line-height: 2;
}
</style>
pages/API/get-enter-options-sync/get-enter-options-sync.test.js
0 → 100644
浏览文件 @
9d291587
const
PAGE_PATH
=
'
/pages/API/get-enter-options-sync/get-enter-options-sync
'
describe
(
'
getEnterOptionsSync
'
,
()
=>
{
it
(
'
app onShow 和 getEnterOptionsSync 结果一致
'
,
async
()
=>
{
const
page
=
await
program
.
navigateTo
(
PAGE_PATH
)
await
page
.
waitFor
(
'
view
'
)
const
pageData
=
await
page
.
data
()
expect
(
pageData
.
testResult
).
toBe
(
true
)
})
})
pages/API/get-enter-options-sync/get-enter-options-sync.uvue
0 → 100644
浏览文件 @
9d291587
<template>
<page-head title="getEnterOptionsSync"></page-head>
<view class="uni-padding-wrap">
<view class="uni-common-mt">
<text>应用本次启动路径:</text>
<text style="margin-top: 5px">{{ enterOptionsString }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
enterOptionsString: '',
testResult: false }
},
onReady() {
const app = getApp()
const appOnShow = app.globalData.onShowOption
const onShowOption = uni.getEnterOptionsSync()
this.enterOptionsString = JSON.stringify(onShowOption, null, 2)
this.testResult = (onShowOption.path == appOnShow.path && onShowOption.appScheme == appOnShow.appScheme && onShowOption.appLink == appOnShow.appLink)
}
}
</script>
pages/API/get-launch-options-sync/get-launch-options-sync.test.js
浏览文件 @
9d291587
...
...
@@ -9,21 +9,9 @@ describe('getLaunchOptionsSync', () => {
expect
(
data
.
checked
).
toBe
(
true
)
})
it
(
'
app onLaunch 和 getLaunchOptionsSync 结果一致
'
,
async
()
=>
{
const
page
=
await
program
.
navigateTo
(
PAGE_PATH
)
await
page
.
waitFor
(
'
view
'
)
const
res
=
await
page
.
callMethod
(
'
compareOnLaunchRes
'
)
expect
(
res
.
appOnLaunch
).
toEqual
(
res
.
launchOptions
)
})
it
(
'
app onShow 和 getEnterOptionsSync 结果一致
'
,
async
()
=>
{
const
page
=
await
program
.
navigateTo
(
PAGE_PATH
)
await
page
.
waitFor
(
'
view
'
)
const
res
=
await
page
.
callMethod
(
'
compareOnShowRes
'
)
if
(
process
.
env
.
uniTestPlatformInfo
.
toLowerCase
().
startsWith
(
'
android
'
))
{
// if android return
expect
(
true
).
toBe
(
true
)
}
expect
(
res
.
appOnShow
).
toEqual
(
res
.
onShowOption
)
const
pageData
=
await
page
.
data
()
expect
(
pageData
.
testResult
).
toBe
(
true
)
})
})
pages/API/get-launch-options-sync/get-launch-options-sync.uvue
浏览文件 @
9d291587
<template>
<page-head title="getLaunchOptionsSync"></page-head>
<view class="uni-padding-wrap">
<button @click="getLaunchOptionsSync">getLaunchOptionsSync</button>
<view v-if="launchOptionsPath.length > 0" class="uni-common-mt">
<text>应用启动路径:</text>
<text style="margin-top: 5px">{{ launchOptionsPath }}</text>
</view>
</view>
</template>
<script lang="uts">
type OnShowReturn = {
appOnShow : OnShowOptions,
onShowOption : OnShowOptions
}
type IOnLaunchOptions = {
appOnLaunch : OnLaunchOptions,
launchOptions : OnLaunchOptions
}
export default {
data() {
return {
checked: false,
homePagePath: 'pages/tabBar/component',
launchOptionsPath: '',
}
},
methods: {
// 自动化测试
compareOnLaunchRes() : IOnLaunchOptions {
const launchOptions = uni.getLaunchOptionsSync();
const app = getApp()
const appOnLaunch = app.globalData.launchOptions as OnLaunchOptions
const res : IOnLaunchOptions = {
appOnLaunch,
launchOptions
}
return res
},
compareOnShowRes() : OnShowReturn {
// #ifdef APP-ANDROID
const res : OnShowReturn = {
appOnShow: {
path: ''
} as OnShowOptions,
onShowOption: {
path: ''
} as OnShowOptions
}
return res
// #endif
// #ifndef APP-ANDROID
const onShowOption = uni.getEnterOptionsSync();
const app = getApp()
const appOnShow = app.globalData.onShowOption as OnShowOptions
return {
appOnShow,
onShowOption
}
// #endif
},
getLaunchOptionsSync() {
const launchOptions = uni.getLaunchOptionsSync()
this.launchOptionsPath = launchOptions.path
if (launchOptions.path == this.homePagePath) {
this.checked = true
}
},
},
}
<template>
<page-head title="getLaunchOptionsSync"></page-head>
<view class="uni-padding-wrap">
<button @click="getLaunchOptionsSync">getLaunchOptionsSync</button>
<view class="uni-common-mt">
<text>应用本次启动路径:</text>
<text style="margin-top: 5px">{{ launchOptionsPath }}</text>
</view>
<view class="uni-common-mt">
<text>应用本次启动:</text>
<text style="margin-top: 5px">{{ launchOptionsString }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
checked: false,
homePagePath: 'pages/tabBar/component',
launchOptionsPath: '',
launchOptionsString: '',
testResult: false
}
},
onReady(){
this.compareOnLaunchRes()
},
methods: {
compareOnLaunchRes() {
const launchOptions = uni.getLaunchOptionsSync();
this.launchOptionsString = JSON.stringify(launchOptions, null, 2)
const app = getApp()
const appOnLaunch = app.globalData.launchOptions
const isPathSame = launchOptions.path == appOnLaunch.path
const isAppSchemeSame = launchOptions.appScheme == appOnLaunch.appScheme
const isAppLinkSame = launchOptions.appLink == appOnLaunch.appLink
this.testResult = isPathSame && isAppSchemeSame && isAppLinkSame
},
getLaunchOptionsSync() {
const launchOptions = uni.getLaunchOptionsSync()
this.launchOptionsPath = launchOptions.path
if (launchOptions.path == this.homePagePath) {
this.checked = true
}
},
},
}
</script>
pages/API/requestAnimationFrame/requestAnimationFrame.test.js
0 → 100644
浏览文件 @
9d291587
const
PAGE_PATH
=
'
/pages/API/requestAnimationFrame/requestAnimationFrame
'
describe
(
'
API-requestAnimationFrame
'
,
()
=>
{
let
page
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
PAGE_PATH
)
await
page
.
waitFor
(
600
);
});
it
(
'
requestAnimationFrame
'
,
async
()
=>
{
await
page
.
callMethod
(
'
startRequestAnimationFrame
'
)
await
page
.
waitFor
(
100
)
const
data
=
await
page
.
data
()
expect
(
data
.
testFrameCount
>
0
).
toBe
(
true
)
});
});
pages/API/requestAnimationFrame/requestAnimationFrame.uvue
0 → 100644
浏览文件 @
9d291587
<template>
<view class="page">
<page-head :title="title"></page-head>
<button @click="startRequestAnimationFrame">requestAnimationFrame</button>
<text class="frame-count">{{testFrameCount}}</text>
</view>
</template>
<script>
export default {
data() {
return {
title: 'requestAnimationFrame',
testFrameCount: 0
}
},
methods: {
startRequestAnimationFrame() {
uni.requestAnimationFrame((_ : number) => {
this.testFrameCount++;
})
}
}
}
</script>
<style>
.page {
padding: 15px;
}
.frame-count {
margin-top: 15px;
}
</style>
pages/API/show-toast/show-toast.test.js
浏览文件 @
9d291587
// uni-app自动化测试教程: uni-app自动化测试教程: https://uniapp.dcloud.net.cn/worktile/auto/hbuilderx-extension/
describe
(
'
API-toast
'
,
()
=>
{
let
page
;
const
isApp
=
process
.
env
.
UNI_OS_NAME
===
"
android
"
||
process
.
env
.
UNI_OS_NAME
===
"
ios
"
;
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
'
/pages/API/show-toast/show-toast
'
)
await
page
.
waitFor
(
600
);
await
page
.
waitFor
(
"
view
"
);
});
it
(
"
onload-toast-test
"
,
async
()
=>
{
async
function
toScreenshot
(
imgName
)
{
if
(
isApp
)
{
await
page
.
waitFor
(
500
);
const
res
=
await
page
.
callMethod
(
'
jest_getWindowInfo
'
)
const
windowHeight
=
res
.
windowHeight
*
res
.
pixelRatio
;
const
windowWidth
=
res
.
windowWidth
*
res
.
pixelRatio
;
const
image
=
await
program
.
screenshot
({
deviceShot
:
true
,
area
:
{
...
...
@@ -31,163 +23,53 @@ describe('API-toast', () => {
width
:
windowWidth
},
});
expect
(
image
).
toSaveImageSnapshot
();
expect
(
image
).
toSaveImageSnapshot
({
customSnapshotIdentifier
()
{
return
imgName
}})
}
else
{
const
image
=
await
program
.
screenshot
({
deviceShot
:
true
,
fullPage
:
true
});
expect
(
image
).
toSaveImageSnapshot
()
expect
(
image
).
toSaveImageSnapshot
({
customSnapshotIdentifier
()
{
return
imgName
}})
}
})
await
page
.
waitFor
(
500
);
}
it
(
"
btn-toast-default-1
"
,
async
()
=>
{
const
btnToastDefaultButton
=
await
page
.
$
(
'
#btn-toast-default
'
)
await
btnToastDefaultButton
.
tap
()
await
page
.
waitFor
(
200
)
if
(
isApp
)
{
const
res
=
await
page
.
callMethod
(
'
jest_getWindowInfo
'
)
const
windowHeight
=
res
.
windowHeight
*
res
.
pixelRatio
;
const
windowWidth
=
res
.
windowWidth
*
res
.
pixelRatio
;
const
image
=
await
program
.
screenshot
({
deviceShot
:
true
,
area
:
{
x
:
0
,
y
:
200
,
height
:
windowHeight
-
200
,
width
:
windowWidth
},
});
expect
(
image
).
toSaveImageSnapshot
();
}
else
{
const
image
=
await
program
.
screenshot
({
deviceShot
:
true
,
fullPage
:
true
});
expect
(
image
).
toSaveImageSnapshot
()
}
it
(
"
onload-toast-test
"
,
async
()
=>
{
await
toScreenshot
(
'
toast-onload
'
)
})
it
(
"
btn-toast-duration-1
"
,
async
()
=>
{
const
btnToastDurationButton
=
await
page
.
$
(
'
#btn-toast-duration
'
)
await
btnToastDurationButton
.
tap
()
await
page
.
waitFor
(
2000
)
if
(
isApp
)
{
const
res
=
await
page
.
callMethod
(
'
jest_getWindowInfo
'
)
const
windowHeight
=
res
.
windowHeight
*
res
.
pixelRatio
;
const
windowWidth
=
res
.
windowWidth
*
res
.
pixelRatio
;
const
image
=
await
program
.
screenshot
({
deviceShot
:
true
,
area
:
{
x
:
0
,
y
:
200
,
height
:
windowHeight
-
200
,
width
:
windowWidth
},
});
expect
(
image
).
toSaveImageSnapshot
();
}
else
{
const
image
=
await
program
.
screenshot
({
deviceShot
:
true
,
fullPage
:
true
});
expect
(
image
).
toSaveImageSnapshot
()
it
(
"
icon-toast-test
"
,
async
()
=>
{
const
icons
=
await
page
.
$$
(
'
.radio-icon
'
)
for
(
let
i
=
0
;
i
<
icons
.
length
;
i
++
)
{
await
icons
[
i
].
tap
()
const
iconText
=
await
icons
[
i
].
text
()
await
page
.
callMethod
(
'
toast1Tap
'
)
await
page
.
waitFor
(
100
);
await
toScreenshot
(
`
${
iconText
}
`
)
}
})
it
(
"
btn-toast-errorIcon-1
"
,
async
()
=>
{
const
btnToastErrorIconButton
=
await
page
.
$
(
'
#btn-toast-errorIcon
'
)
await
btnToastErrorIconButton
.
tap
()
await
page
.
waitFor
(
200
)
if
(
isApp
)
{
const
res
=
await
page
.
callMethod
(
'
jest_getWindowInfo
'
)
const
windowHeight
=
res
.
windowHeight
*
res
.
pixelRatio
;
const
windowWidth
=
res
.
windowWidth
*
res
.
pixelRatio
;
const
image
=
await
program
.
screenshot
({
deviceShot
:
true
,
area
:
{
x
:
0
,
y
:
200
,
height
:
windowHeight
-
200
,
width
:
windowWidth
},
});
expect
(
image
).
toSaveImageSnapshot
();
}
else
{
const
image
=
await
program
.
screenshot
({
deviceShot
:
true
,
fullPage
:
true
});
expect
(
image
).
toSaveImageSnapshot
()
}
it
(
"
image-toast-test
"
,
async
()
=>
{
await
page
.
setData
({
imageSelect
:
true
})
await
page
.
waitFor
(
300
);
await
page
.
callMethod
(
'
toast1Tap
'
)
await
page
.
waitFor
(
300
);
await
toScreenshot
(
'
toast-image
'
)
})
it
(
"
btn-toast-loading-1
"
,
async
()
=>
{
const
btnToastLoadingButton
=
await
page
.
$
(
'
#btn-toast-loading
'
)
await
btnToastLoadingButton
.
tap
()
await
page
.
waitFor
(
200
)
const
btnToastHideButton
=
await
page
.
$
(
'
#btn-toast-hide
'
)
await
btnToastHideButton
.
tap
()
await
page
.
waitFor
(
1000
)
if
(
isApp
)
{
const
res
=
await
page
.
callMethod
(
'
jest_getWindowInfo
'
)
const
windowHeight
=
res
.
windowHeight
*
res
.
pixelRatio
;
const
windowWidth
=
res
.
windowWidth
*
res
.
pixelRatio
;
const
image
=
await
program
.
screenshot
({
deviceShot
:
true
,
area
:
{
x
:
0
,
y
:
200
,
height
:
windowHeight
-
200
,
width
:
windowWidth
},
});
expect
(
image
).
toSaveImageSnapshot
();
}
else
{
const
image
=
await
program
.
screenshot
({
deviceShot
:
true
,
fullPage
:
true
});
expect
(
image
).
toSaveImageSnapshot
()
}
it
(
"
duration-toast-test
"
,
async
()
=>
{
await
page
.
setData
({
intervalSelect
:
4000
})
await
page
.
callMethod
(
'
toast1Tap
'
)
await
page
.
waitFor
(
2000
);
await
toScreenshot
(
'
toast-duration-2000
'
)
await
page
.
waitFor
(
1000
);
await
page
.
callMethod
(
'
hideToast
'
)
await
page
.
waitFor
(
300
);
await
toScreenshot
(
'
toast-duration-end
'
)
})
// it("btn-toast-postion-bottom-1", async () => {
// const btnToastButton = await page.$('#btn-toast-postion-bottom')
// await btnToastButton.tap()
// await page.waitFor(200)
// if (isApp) {
// const windowHeight = uni.getWindowInfo().windowHeight;
// const windowWidth = uni.getWindowInfo().windowWidth;
// const image = await program.screenshot({
// deviceShot: true,
// area: {
// x: 0,
// y: 200,
// height: windowHeight,
// width:windowWidth
// },
// });
// expect(image).toSaveImageSnapshot();
// }else{
// const image = await program.screenshot({
// deviceShot: true,
// fullPage: true
// });
// expect(image).toSaveImageSnapshot()
// }
// })
});
pages/API/show-toast/show-toast.uvue
浏览文件 @
9d291587
<template>
<view>
<!-- #ifdef APP -->
<scroll-view direction="vertical" style="flex:1">
<!-- #endif -->
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<view class="uni-padding-wrap">
<text class="uni-title-text uni-common-mb">设置icon</text>
</view>
<view class="uni-list uni-common-pl">
<radio-group @change="radioChangeIcon">
<radio class="uni-list-cell uni-list-cell-pd radio-icon" v-for="(icon, index) in icon_enum" :key="icon.value"
:class="index < icon_enum.length - 1 ? 'uni-list-cell-line' : ''" :value="icon.value"
:checked="index === icon_current">{{icon.name}}</radio>
</radio-group>
</view>
<view class="uni-list-cell uni-list-cell-padding">
<view class="uni-list-cell-db">是否显示自定义图标</view>
<switch :checked="imageSelect" @change="change_image_boolean" />
</view>
<view class="uni-list-cell uni-list-cell-padding">
<view class="uni-list-cell-db">是否显示透明蒙层-屏蔽点击事件</view>
<switch :checked="maskSelect" @change="change_mask_boolean" />
</view>
<view class="uni-title uni-list-cell-padding">提示的延迟时间,默认:1500(单位毫秒)</view>
<view class="uni-list-cell-padding">
<slider @change="sliderChange" foreColor="#007AFF" :value="intervalSelect" :min="1500" :max="5000" :show-value="true" />
</view>
<view class="uni-btn-v">
<button class="uni-btn-v" type="default" @tap="toast1Tap" id="btn-toast-default" >点击弹出默认toast</button>
<button class="uni-btn-v" type="default" @tap="toastTapIconError" id="btn-toast-errorIcon">点击弹出设置icon的toast</button>
<button class="uni-btn-v" type="default" @tap="toast2Tap" id="btn-toast-duration">点击弹出设置duration的toast</button>
<button class="uni-btn-v" type="default" @tap="toast3Tap" id="btn-toast-loading">点击弹出显示loading的toast</button>
<!-- #ifndef MP-ALIPAY -->
<button class="uni-btn-v" type="default" @tap="toast4Tap">点击弹出显示自定义图片的toast</button>
<!-- #endif -->
<!-- #ifdef APP -->
<button class="uni-btn-v" type="default" @tap="toast5Tap" id="btn-toast-postion-bottom">点击显示无图标的居底toast</button>
<!-- #endif -->
<button class="uni-btn-v" type="default" @tap="toast1Tap" id="btn-toast-default">点击弹出toast</button>
<button class="uni-btn-v" type="default" @tap="hideToast" id="btn-toast-hide">点击隐藏toast</button>
</view>
<!-- #ifdef APP -->
<view class="uni-padding-wrap uni-common-mt">
<text class="uni-title-text uni-common-mb"> 设置position,仅App生效 </text>
</view>
<view class="uni-list uni-common-pl">
<radio-group @change="radioChangePosition">
<radio class="uni-list-cell uni-list-cell-pd radio-position" v-for="(position, index) in position_enum" :key="position.value"
:class="index < position_enum.length - 1 ? 'uni-list-cell-line' : ''" :value="position.value"
:checked="index === position_current">{{position.name}}</radio>
</radio-group>
</view>
<button class="uni-btn uni-btn-v uni-common-mb" type="default" @tap="toast2Tap">点击弹出设置position的toast</button>
<!-- #endif -->
<text>{{exeRet}}</text>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
<script lang="uts">
type IconItemType = {
value : "success" | "error" | "fail" | "exception" | "loading" | "none";
name : string
}
type PositionItemType = {
value : "top" | "center" | "bottom";
name : string
}
export default {
data() {
return {
title: 'toast',
exeRet: ''
exeRet: '',
imageSelect:false,
maskSelect: false,
intervalSelect: 1500,
position_current:0,
position_enum: [
{ "value": "top", "name": "top: 居上显示" },
{ "value": "center", "name": "center: 居中显示" },
{ "value": "bottom", "name": "bottom: 居底显示" },
] as PositionItemType[],
icon_current:0,
icon_enum: [
{
value: 'success',
name: '显示成功图标',
},
{
value: 'error',
name: '显示错误图标',
},
// {
// value: 'fail',
// name: '显示错误图标',
// },
// {
// value: 'exception',
// name: '显示异常图标,此时title文本无长度显示',
// },
{
value: 'loading',
name: '显示加载图标',
},
{
value: 'none',
name: '不显示图标',
},
] as IconItemType[],
}
},
onLoad() {
...
...
@@ -41,59 +115,40 @@
jest_getWindowInfo() : GetWindowInfoResult {
return uni.getWindowInfo();
},
toast1Tap: function () {
uni.showToast({
title: "默认",
success: (res) => {
this.exeRet = "success:" + JSON.stringify(res)
},
fail: (res) => {
this.exeRet = "fail:" + JSON.stringify(res)
},
})
radioChangeIcon(e : UniRadioGroupChangeEvent) {
for (let i = 0; i < this.icon_enum.length; i++) {
if (this.icon_enum[i].value === e.detail.value) {
this.icon_current = i;
break;
}
}
},
toastTapIconError: function () {
uni.showToast({
title: "默认",
icon: 'error',
success: (res) => {
this.exeRet = "success:" + JSON.stringify(res)
},
fail: (res) => {
this.exeRet = "fail:" + JSON.stringify(res)
},
})
change_image_boolean: function (e : UniSwitchChangeEvent) {
this.imageSelect = e.detail.value
},
toast2Tap: function () {
uni.showToast({
title: "duration 3000",
duration: 3000,
success: (res) => {
this.exeRet = "success:" + JSON.stringify(res)
},
fail: (res) => {
this.exeRet = "fail:" + JSON.stringify(res)
},
})
change_mask_boolean: function (e : UniSwitchChangeEvent) {
this.maskSelect = e.detail.value
},
toast3Tap: function () {
uni.showToast({
title: "loading",
icon: "loading",
duration: 5000,
success: (res) => {
this.exeRet = "success:" + JSON.stringify(res)
},
fail: (res) => {
this.exeRet = "fail:" + JSON.stringify(res)
},
})
sliderChange(e : UniSliderChangeEvent) {
this.intervalSelect = e.detail.value
},
radioChangePosition(e : UniRadioGroupChangeEvent) {
for (let i = 0; i < this.position_enum.length; i++) {
if (this.position_enum[i].value === e.detail.value) {
this.position_current = i;
break;
}
}
},
toast
4
Tap: function () {
toast
1
Tap: function () {
uni.showToast({
title: "logo",
image: "/static/uni.png",
title: "默认",
icon: this.icon_enum[this.icon_current].value,
duration: this.intervalSelect,
image: this.imageSelect? "/static/uni.png" : null ,
mask: this.maskSelect,
success: (res) => {
console.log('success:',res)
this.exeRet = "success:" + JSON.stringify(res)
},
fail: (res) => {
...
...
@@ -102,10 +157,11 @@
})
},
// #ifdef APP
toast5Tap: function () {
toast2Tap: function () {
let positionValue = this.position_enum[this.position_current].value
uni.showToast({
title: "显示一段轻提示
"
,
position:
'bottom'
,
title: "显示一段轻提示
,position:" + positionValue
,
position:
positionValue
,
success: (res) => {
this.exeRet = "success:" + JSON.stringify(res)
},
...
...
@@ -121,3 +177,4 @@
}
}
</script>
pages/component/canvas/canvas.uvue
浏览文件 @
9d291587
此差异已折叠。
点击以展开。
pages/component/canvas/canvas/ball.uvue
浏览文件 @
9d291587
...
...
@@ -39,7 +39,7 @@
this.vy = Math.abs(this.vy)
return
}
if (this.y > this.
width
- this.radius) {
if (this.y > this.
height
- this.radius) {
this.vy = -Math.abs(this.vy)
}
}
...
...
@@ -50,13 +50,10 @@
private ballList : Array<Ball> = []
private speed = 3
private layer = 3
private ballInlayer = 20
private interval : number = 0
private ballInlayer = 20
private runningFlag : boolean = false
// #ifdef WEB
private _animateResult: number = 0
// #endif
constructor(ctx : CanvasRenderingContext2D) {
this.ctx = ctx
...
...
@@ -95,46 +92,24 @@
// this.ctx.ellipse(item.x, item.y, item.radius, item.radius, 0, 0, Math.PI * 2)
this.ctx.fill()
})
// #ifdef APP
this.ctx.draw()
// #endif
// #ifdef WEB
if (!this.runningFlag) {
return
}
this._animateResult =
requestAnimationFrame((
) => {
this._animateResult =
uni.requestAnimationFrame((_: number
) => {
this.animate()
})
// #endif
}
start() {
// #ifdef WEB
cancelAnimationFrame(this._animateResult)
start() {
uni.cancelAnimationFrame(this._animateResult)
this.runningFlag = true
this.animate()
// #endif
// #ifdef APP
//Todo.. requestAnimationFrame
clearInterval(this.interval)
this.interval = setInterval(() => {
this.animate()
}, 17)
// #endif
}
stop() {
// #ifdef WEB
stop() {
this.runningFlag = false
cancelAnimationFrame(this._animateResult)
// #endif
// #ifdef APP
//Todo.. requestAnimationFrame
clearInterval(this.interval)
// #endif
uni.cancelAnimationFrame(this._animateResult)
}
}
...
...
pages/component/canvas/canvas/doodle.uvue
浏览文件 @
9d291587
<template>
<canvas class="drawing" id="tablet" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd"></canvas>
<button @click="doClear()">清空</button>
<canvas class="drawing" id="tablet" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd"></canvas>
<button @click="doClear()">清空</button>
</template>
<script>
export default {
data() {
return {
lastPointX : 0,
lastPointY : 0
}
},
onShow() {
},
type Point = {
x : number
y : number
};
onReady() {
let element = uni.getElementById('tablet') as UniCanvasElement
let ctx = element.getContext("2d")
if ( ctx != null) {
const dpr = uni.getDeviceInfo().devicePixelRatio ?? 1;
element.width = element.offsetWidth * dpr
element.height = element.offsetHeight * dpr
ctx.scale(dpr, dpr)
export default {
data() {
return {
lastPointX: 0,
lastPointY: 0,
canvasElement: null as UniCanvasElement | null,
renderingContext: null as CanvasRenderingContext2D | null,
}
},
methods: {
touchStart(event: TouchEvent){
let element = uni.getElementById('tablet') as UniCanvasElement
const elRect = element.getBoundingClientRect();
const touch = event.touches[0];
const x = touch.clientX - elRect.left
const y = touch.clientY - elRect.top
this.lastPointX = x
this.lastPointY = y
},
touchMove(event: TouchEvent){
let element = uni.getElementById('tablet') as UniCanvasElement
const elRect = element.getBoundingClientRect();
const touch = event.touches[0];
const x = touch.clientX - elRect.left
const y = touch.clientY - elRect.top
let ctx = element.getContext("2d")
if ( null != ctx) {
ctx.lineWidth = 5;
ctx.lineCap = "round";
ctx.lineJoin = "square";
ctx.beginPath()
ctx.moveTo(this.lastPointX, this.lastPointY)
ctx.lineTo(x, y)
ctx.stroke()
}
this.lastPointX = x
this.lastPointY = y
},
touchEnd(event: TouchEvent){
},
doClear(){
let element = uni.getElementById('tablet') as UniCanvasElement
let ctx = element.getContext("2d")
if (null != ctx ) {
ctx.clearRect(0, 0, element.width, element.height)
}
}
}
}
},
onReady() {
this.canvasElement = uni.getElementById('tablet') as UniCanvasElement
this.renderingContext = this.canvasElement!.getContext("2d")!
const dpr = uni.getDeviceInfo().devicePixelRatio ?? 1;
this.canvasElement!.width = this.canvasElement!.offsetWidth * dpr
this.canvasElement!.height = this.canvasElement!.offsetHeight * dpr
this.renderingContext!.scale(dpr, dpr)
},
methods: {
touchStart(event : TouchEvent) {
const position = this.getPosition(event)
this.lastPointX = position.x
this.lastPointY = position.y
},
touchMove(event : TouchEvent) {
const position = this.getPosition(event)
const x = position.x
const y = position.y
const ctx = this.renderingContext!
ctx.lineWidth = 5
ctx.lineCap = "round"
ctx.lineJoin = "square"
ctx.beginPath()
ctx.moveTo(this.lastPointX, this.lastPointY)
ctx.lineTo(x, y)
ctx.stroke()
this.lastPointX = x
this.lastPointY = y
},
touchEnd(_ : TouchEvent) {
},
doClear() {
if (this.renderingContext != null) {
this.renderingContext!.clearRect(0, 0, this.canvasElement!.width, this.canvasElement!.height)
}
},
getPosition(event : TouchEvent) : Point {
const elRect = this.canvasElement!.getBoundingClientRect()
const touch = event.touches[0]
return {
x: touch.clientX - elRect.left,
y: touch.clientY - elRect.top
} as Point
}
}
}
</script>
<style>
.drawing {
width: 100%;
height: 500px;
background-color: lightgray;
margin-bottom: 15px;
}
.drawing {
width: 100%;
height: 500px;
background-color: lightgray;
margin-bottom: 15px;
}
</style>
pages/component/object/object.uvue
浏览文件 @
9d291587
<template>
<view>
<native-button class="native-button" style="width: 200px; height: 100px;" :text="buttonText" @buttonTap="ontap"
@load="onload"></native-button>
<view>
<!-- #ifdef APP-ANDROID -->
<native-button class="native-button" style="width: 200px; height: 100px;" :text="buttonText" @buttonTap="ontap"
@load="onload"></native-button>
<time-picker class="native-time-picker" :hour=2 :minute=3 @changed="onChanged"></time-picker>
<!-- #endif -->
</view>
...
...
pages/tabBar/API.uvue
浏览文件 @
9d291587
...
...
@@ -11,32 +11,39 @@
<u-link :href="'https://uniapp.dcloud.io/uni-app-x/api/'" :text="'https://uniapp.dcloud.io/uni-app-x/api/'"
:inWhiteList="true"></u-link>
</view>
<uni-collapse>
<uni-collapse-item ref="category" v-for="menuItem in menu" :key="menuItem!.id" :title="menuItem.name"
class="item">
<view v-for="page in menuItem.pages" :key="page!.path" class="uni-navigate-item" hover-class="is--active"
@click="goPage(`/${page.path}`)">
<text class="uni-navigate-text" :class="{'left-win-active': leftWinActive === page.path && hasLeftWin}">{{page.style["navigationBarTitleText"]}}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
</view>
<uni-collapse style="width: 100%" v-for="childMenu in menuItem.children" :key="childMenu!.id">
<uni-collapse-item :title="childMenu.name" class="item" style="margin-bottom: 0">
<view class="uni-navigate-item" hover-class="is--active" v-for="childPage in childMenu.pages"
:key="childPage!.path" @click="goPage(`/${childPage.path}`)">
<text class="uni-navigate-text">{{
childPage.style["navigationBarTitleText"]
}}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
</view>
</uni-collapse-item>
</uni-collapse>
</uni-collapse-item>
</uni-collapse>
<view v-if="!hasLeftWin" ref="pop" @click="hidePop()" class="popup">
<view style="width: 90%; background-color: white" @click="stopClickPop">
<api-set-tabbar></api-set-tabbar>
</view>
</view>
<uni-collapse>
<uni-collapse-item ref="category" v-for="menuItem in menu" :key="menuItem!.id" :title="menuItem.name"
class="item">
<template v-for="childMenuItem in menuItem.items" :key="childMenuItem!.id">
<view v-if="childMenuItem.items.length==0" style="padding-left: 18px" class="uni-navigate-item"
hover-class="is--active" @click="goPage(`/${childMenuItem.path}`)">
<text class="uni-navigate-text" :class="{
'left-win-active': leftWinActive === childMenuItem.path && hasLeftWin,
}">{{ childMenuItem.style["navigationBarTitleText"] }}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
</view>
<uni-collapse v-else style="width: 100%">
<uni-collapse-item :title="childMenuItem.name" class="item"
style="margin-bottom: 0; padding-left: 5px; padding-right: 5px">
<view style="padding-left: 18px" class="uni-navigate-item" hover-class="is--active"
v-for="grandChildMenuItem in childMenuItem.items" :key="grandChildMenuItem!.path"
@click="goPage(`/${grandChildMenuItem.path}`)">
<text class="uni-navigate-text" :class="{
'left-win-active':
leftWinActive === grandChildMenuItem.path && hasLeftWin,
}">{{ grandChildMenuItem.style["navigationBarTitleText"] }}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
</view>
</uni-collapse-item>
</uni-collapse>
</template>
</uni-collapse-item>
</uni-collapse>
<view v-if="!hasLeftWin" ref="pop" @click="hidePop()" class="popup">
<view style="width: 90%; background-color: white" @click="stopClickPop">
<api-set-tabbar></api-set-tabbar>
</view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
...
...
@@ -56,10 +63,10 @@
}
},
computed: {
hasLeftWin()
:boolean
{
hasLeftWin()
: boolean
{
return !state.noMatchLeftWindow
},
leftWinActive()
:string
{
leftWinActive()
: string
{
return state.leftWinActive.slice(1)
}
},
...
...
@@ -67,8 +74,12 @@
goPage(url : string) {
if (url == '/set-tab-bar') {
this.showPop()
} else {
uni.navigateTo({ url })
} else {
if(this.hasLeftWin) {
uni.reLaunch({ url })
} else {
uni.navigateTo({ url })
}
}
},
showPop: function () {
...
...
@@ -82,20 +93,20 @@
}
},
// #ifdef WEB
watch:{
$route: {
immediate: true,
handler(newRoute) {
if (newRoute.matched.length) {
const activeCategoryIndex = this.menu.findIndex(menuItem => menuItem?.
pages.some(page => this.leftWinActive && this.leftWinActive === page
?.path))
watch:
{
$route: {
immediate: true,
handler(newRoute) {
if (newRoute.matched.length) {
const activeCategoryIndex = this.menu.findIndex(menuItem => menuItem?.
items.some(item => this.leftWinActive && this.leftWinActive === item
?.path))
if (activeCategoryIndex > -1) {
this.$nextTick(() => {
((this.$refs.category as ComponentPublicInstance[])[activeCategoryIndex])?.$callMethod('openCollapse', true)
})
}
}
}
}
}
}
}
},
// #endif
}
...
...
@@ -122,4 +133,4 @@
display: none;
background-color: rgba(16, 16, 16, 0.5);
}
</style>
</style>
pages/tabBar/CSS.uvue
浏览文件 @
9d291587
...
...
@@ -11,28 +11,33 @@
<u-link :href="'https://uniapp.dcloud.io/uni-app-x/css/'" :text="'https://uniapp.dcloud.io/uni-app-x/css/'"
:inWhiteList="true"></u-link>
</view>
<uni-collapse>
<uni-collapse-item ref="category" v-for="menuItem in menu" :key="menuItem!.id" :title="menuItem.name"
class="item">
<view v-for="page in menuItem.pages" :key="page!.path" class="uni-navigate-item" hover-class="is--active"
@click="goPage(`/${page.path}`)">
<text class="uni-navigate-text" :class="{'left-win-active': leftWinActive === page.path && hasLeftWin}">{{
page.style["navigationBarTitleText"]
}}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
</view>
<uni-collapse style="width: 100%" v-for="childMenu in menuItem.children" :key="childMenu!.id">
<uni-collapse-item :title="childMenu.name" class="item" style="margin-bottom: 0">
<view class="uni-navigate-item" hover-class="is--active" v-for="childPage in childMenu.pages"
:key="childPage!.path" @click="goPage(`/${childPage.path}`)">
<text class="uni-navigate-text">{{
childPage.style["navigationBarTitleText"]
}}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
</view>
</uni-collapse-item>
</uni-collapse>
</uni-collapse-item>
<uni-collapse>
<uni-collapse-item ref="category" v-for="menuItem in menu" :key="menuItem!.id" :title="menuItem.name"
class="item">
<template v-for="childMenuItem in menuItem.items" :key="childMenuItem!.id">
<view v-if="childMenuItem.items.length==0" style="padding-left: 18px" class="uni-navigate-item"
hover-class="is--active" @click="goPage(`/${childMenuItem.path}`)">
<text class="uni-navigate-text" :class="{
'left-win-active': leftWinActive === childMenuItem.path && hasLeftWin,
}">{{ childMenuItem.style["navigationBarTitleText"] }}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
</view>
<uni-collapse v-else style="width: 100%">
<uni-collapse-item :title="childMenuItem.name" class="item"
style="margin-bottom: 0; padding-left: 5px; padding-right: 5px">
<view style="padding-left: 18px" class="uni-navigate-item" hover-class="is--active"
v-for="grandChildMenuItem in childMenuItem.items" :key="grandChildMenuItem!.path"
@click="goPage(`/${grandChildMenuItem.path}`)">
<text class="uni-navigate-text" :class="{
'left-win-active':
leftWinActive === grandChildMenuItem.path && hasLeftWin,
}">{{ grandChildMenuItem.style["navigationBarTitleText"] }}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
</view>
</uni-collapse-item>
</uni-collapse>
</template>
</uni-collapse-item>
</uni-collapse>
</view>
<!-- #ifdef APP -->
...
...
@@ -41,9 +46,9 @@
</template>
<script lang="uts">
import { generateMenu } from './generateMenu.uts'
import { MenuItem } from './generateMenu.uts'
const menu = generateMenu('pages/CSS')
import { generateMenu } from './generateMenu.uts'
import { MenuItem } from './generateMenu.uts'
const menu = generateMenu('pages/CSS')
import { state } from '@/store/index.uts'
export default {
data() {
...
...
@@ -51,36 +56,40 @@
menu: menu as (MenuItem | null)[],
arrowRightIcon: '/static/icons/arrow-right.png',
}
},
computed: {
hasLeftWin()
:boolean{
return !state.noMatchLeftWindow
},
leftWinActive()
:string{
return state.leftWinActive.slice(1)
}
},
computed: {
hasLeftWin()
: boolean {
return !state.noMatchLeftWindow
},
leftWinActive()
: string {
return state.leftWinActive.slice(1)
}
},
methods: {
goPage(url : string) {
uni.navigateTo({ url })
goPage(url : string) {
if(this.hasLeftWin) {
uni.reLaunch({ url })
} else {
uni.navigateTo({ url })
}
},
},
// #ifdef WEB
watch:
{
$route: {
immediate: true,
handler(newRoute) {
if (newRoute.matched.length) {
const activeCategoryIndex = this.menu.findIndex(menuItem => menuItem?.
pages.some(page => this.leftWinActive && this.leftWinActive === page?.path))
if (activeCategoryIndex > -1) {
this.$nextTick(() => {
((this.$refs.category as ComponentPublicInstance[])[activeCategoryIndex]).$callMethod('openCollapse', true)
})
}
}
}
}
},
},
// #ifdef WEB
watch:
{
$route: {
immediate: true,
handler(newRoute) {
if (newRoute.matched.length) {
const activeCategoryIndex = this.menu.findIndex(menuItem => menuItem?.
items.some(item => this.leftWinActive && this.leftWinActive === item?.path))
if (activeCategoryIndex > -1) {
this.$nextTick(() => {
((this.$refs.category as ComponentPublicInstance[])[activeCategoryIndex]).$callMethod('openCollapse', true)
})
}
}
}
}
},
// #endif
}
</script>
...
...
pages/tabBar/component.uvue
浏览文件 @
9d291587
...
...
@@ -11,28 +11,33 @@
<u-link :href="'https://uniapp.dcloud.io/uni-app-x/component/'"
:text="'https://uniapp.dcloud.io/uni-app-x/component/'" :inWhiteList="true"></u-link>
</view>
<uni-collapse>
<uni-collapse-item ref="category" v-for="menuItem in menu" :key="menuItem!.id" :title="menuItem.name"
class="item">
<view v-for="page in menuItem.pages" :key="page!.path" class="uni-navigate-item" hover-class="is--active"
@click="goPage(`/${page.path}`)">
<text class="uni-navigate-text" :class="{'left-win-active': leftWinActive === page.path && hasLeftWin}">{{
page.style["navigationBarTitleText"]
}}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
</view>
<uni-collapse style="width: 100%" v-for="childMenu in menuItem.children" :key="childMenu!.id">
<uni-collapse-item :title="childMenu.name" class="item" style="margin-bottom: 0">
<view class="uni-navigate-item" hover-class="is--active" v-for="childPage in childMenu.pages"
:key="childPage!.path" @click="goPage(`/${childPage.path}`)">
<text class="uni-navigate-text" :class="{'left-win-active': leftWinActive === childPage.path && hasLeftWin}">{{
childPage.style["navigationBarTitleText"]
}}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
</view>
</uni-collapse-item>
</uni-collapse>
</uni-collapse-item>
<uni-collapse>
<uni-collapse-item ref="category" v-for="menuItem in menu" :key="menuItem!.id" :title="menuItem.name"
class="item">
<template v-for="childMenuItem in menuItem.items" :key="childMenuItem!.id">
<view v-if="childMenuItem.items.length==0" style="padding-left: 18px" class="uni-navigate-item"
hover-class="is--active" @click="goPage(`/${childMenuItem.path}`)">
<text class="uni-navigate-text" :class="{
'left-win-active': leftWinActive === childMenuItem.path && hasLeftWin,
}">{{ childMenuItem.style["navigationBarTitleText"] }}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
</view>
<uni-collapse v-else style="width: 100%">
<uni-collapse-item :title="childMenuItem.name" class="item"
style="margin-bottom: 0; padding-left: 5px; padding-right: 5px">
<view style="padding-left: 18px" class="uni-navigate-item" hover-class="is--active"
v-for="grandChildMenuItem in childMenuItem.items" :key="grandChildMenuItem!.path"
@click="goPage(`/${grandChildMenuItem.path}`)">
<text class="uni-navigate-text" :class="{
'left-win-active':
leftWinActive === grandChildMenuItem.path && hasLeftWin,
}">{{ grandChildMenuItem.style["navigationBarTitleText"] }}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
</view>
</uni-collapse-item>
</uni-collapse>
</template>
</uni-collapse-item>
</uni-collapse>
<!-- #ifdef UNI-APP-X && APP -->
...
...
@@ -59,18 +64,22 @@
arrowRightIcon: '/static/icons/arrow-right.png' as string.ImageURIString,
pageHiden: false
}
},
computed: {
hasLeftWin()
:boolean{
return !state.noMatchLeftWindow
},
leftWinActive()
:string{
return state.leftWinActive.slice(1)
}
},
},
computed: {
hasLeftWin()
: boolean {
return !state.noMatchLeftWindow
},
leftWinActive()
: string {
return state.leftWinActive.slice(1)
}
},
methods: {
goPage(url : string) {
uni.navigateTo({ url })
goPage(url : string) {
if(this.hasLeftWin) {
uni.reLaunch({ url })
} else {
uni.navigateTo({ url })
}
},
// #ifdef UNI-APP-X && APP
upgradePopupShow() {
...
...
@@ -84,23 +93,23 @@
uni.showTabBar()?.catch(_ => { })
}
// #endif
},
// #ifdef WEB
watch:
{
$route: {
immediate: true,
handler(newRoute) {
if (newRoute.matched.length) {
const activeCategoryIndex = this.menu.findIndex(menuItem => menuItem?.
pages.some(page => this.leftWinActive && this.leftWinActive === page?.path))
if (activeCategoryIndex > -1) {
this.$nextTick(() => {
((this.$refs.category as ComponentPublicInstance[])[activeCategoryIndex])?.$callMethod('openCollapse', true)
})
}
}
}
}
},
},
// #ifdef WEB
watch:
{
$route: {
immediate: true,
handler(newRoute) {
if (newRoute.matched.length) {
const activeCategoryIndex = this.menu.findIndex(menuItem => menuItem?.
items.some(item => this.leftWinActive && this.leftWinActive === item?.path))
if (activeCategoryIndex > -1) {
this.$nextTick(() => {
((this.$refs.category as ComponentPublicInstance[])[activeCategoryIndex])?.$callMethod('openCollapse', true)
})
}
}
}
}
},
// #endif
onReady() {
// #ifdef UNI-APP-X && APP
...
...
pages/tabBar/generateMenu.uts
浏览文件 @
9d291587
...
...
@@ -15,15 +15,17 @@ type PageGroup = {
type Page = {
path : string,
style : UTSJSONObject,
group ?: string | null
group ?: string | null
,
}
export type MenuItem = {
id : string,
name : string,
index : number,
children : (MenuItem | null)[],
pages : (Page | null)[]
path : string,
style : UTSJSONObject,
group ?: string | null,
items : (MenuItem | null)[]
}
export function generateMenu(tabBarType : string) : (MenuItem | null)[] {
...
...
@@ -37,6 +39,7 @@ export function generateMenu(tabBarType : string) : (MenuItem | null)[] {
let currentGroups : (Group | null)[] | null = groupTree
const pageGroups : PageGroup[] = []
groupIndexList.forEach((groupIndex, index) => {
// 跳过第一层 component API CSS
if (index > 0) {
pageGroups.push({ id: currentGroups![groupIndex]!.id, name: currentGroups![groupIndex]!.name, index: groupIndex } as PageGroup)
}
...
...
@@ -60,27 +63,39 @@ export function generateMenu(tabBarType : string) : (MenuItem | null)[] {
id: id.split('.').slice(-1)[0],
name,
index: validIndex,
children: [] as (MenuItem | null)[],
pages: [] as (Page | null)[]
path: '',
style: {},
group: '',
items: [] as (MenuItem | null)[],
} as MenuItem
}
currentMenu = menuItemArr[validIndex]
if (groupIndex < groupLength - 1) {
menuItemArr = menuItemArr[validIndex]!.
children
as (MenuItem | null)[]
menuItemArr = menuItemArr[validIndex]!.
items
as (MenuItem | null)[]
}
})
const pageMenuItem : MenuItem = {
id: page.path,
name: page.style["navigationBarTitleText"] as string,
index: lastGroup.index,
path: page.path,
style: page.style,
group: page.group,
items: [] as (MenuItem | null)[],
}
if (hasPageGroup) {
const pageIndex = lastGroup.index
fill
PageArrayWithNull(currentMenu!.page
s, pageIndex)
if (currentMenu!.
page
s[pageIndex] == null) {
currentMenu!.
pages[pageIndex] = page
fill
MenuArrayWithNull(currentMenu!.item
s, pageIndex)
if (currentMenu!.
item
s[pageIndex] == null) {
currentMenu!.
items[pageIndex] = pageMenuItem
} else {
currentMenu!.
pages.push(page
)
currentMenu!.
items.push(pageMenuItem
)
}
} else {
currentMenu!.
pages.push(page
)
currentMenu!.
items.push(pageMenuItem
)
}
})
...
...
@@ -116,24 +131,15 @@ function fillMenuArrayWithNull(arr : (MenuItem | null)[], index : number) : void
}
}
function fillPageArrayWithNull(arr : (Page | null)[], index : number) : void {
const len = arr.length
for (let i = 0; i <= index - (len - 1); i++) {
arr.push(null)
}
}
function removeNullItem(arr : (MenuItem | null)[]) : (MenuItem | null)[] {
const res = arr.filter((item : MenuItem | null) : boolean => item !== null)
res.forEach(menuItem => {
addSetTabBarPage(menuItem!)
// #ifdef APP-ANDROID
menuItem.children = removeNullItem(menuItem.children)
menuItem.pages = menuItem.pages.filter((item : Page | null) : boolean => item !== null)
menuItem.items = removeNullItem(menuItem.items)
// #endif
// #ifndef APP-ANDROID
menuItem!.children = removeNullItem(menuItem!.children)
menuItem!.pages = menuItem!.pages.filter((item : Page | null) : boolean => item !== null)
menuItem!.items = removeNullItem(menuItem!.items)
// #endif
})
return res
...
...
@@ -142,11 +148,16 @@ function removeNullItem(arr : (MenuItem | null)[]) : (MenuItem | null)[] {
function addSetTabBarPage(menuItem : MenuItem) {
const { id, name } = menuItem
if (id == 'page' && name == '页面和路由' && !state.noMatchLeftWindow) {
menuItem.pages.push({
menuItem.items.push({
id: 'set-tab-bar',
name: '设置 TabBar',
index: 0,
path: 'set-tab-bar',
style: {
navigationBarTitleText: '设置 TabBar'
}
} as Page)
},
group: null,
items: []
} as MenuItem)
}
}
pages/tabBar/template.uvue
浏览文件 @
9d291587
...
...
@@ -23,7 +23,7 @@
</image>
</view>
<view v-if="item.open">
<view class="uni-navigate-item" :hover-class="page.enable == false ? '' : 'is--active'"
<view
style="padding-left: 18px;"
class="uni-navigate-item" :hover-class="page.enable == false ? '' : 'is--active'"
v-for="(page, key) in item.pages" :key="key" @click="goDetailPage(page)">
<text class="uni-navigate-text" :class="{'left-win-active': leftWinActive === page.url && hasLeftWin,'text-disabled' : page.enable == false}">{{ page.name }}</text>
<image :src="arrowRightIcon" class="uni-icon-size"></image>
...
...
@@ -262,10 +262,12 @@
const url =
e.url.indexOf('platform') > -1
? e.url
: `/pages/template/${e.url}/${e.url}`
uni.navigateTo({
url,
})
: `/pages/template/${e.url}/${e.url}`
if(this.hasLeftWin) {
uni.reLaunch({ url })
} else {
uni.navigateTo({ url })
}
},
},
// #ifdef WEB
...
...
uni_modules/uni-time-picker/utssdk/app-ios/config.json
0 → 100644
浏览文件 @
9d291587
{
"deploymentTarget"
:
"12"
}
uni_modules/uni-time-picker/utssdk/app-ios/index.uts
0 → 100644
浏览文件 @
9d291587
import { UIDatePicker, UIControl, UIDatePickerStyle } from "UIKit"
import { DateFormatter } from "CoreFoundation"
export class NativeTimePicker {
element : UniNativeViewElement
timePicker : UIDatePicker
h : number
m : number
constructor(element : UniNativeViewElement, hour : number, minute : number) {
this.element = element
this.timePicker = new UIDatePicker()
this.h = hour
this.m = minute
super.init()
// 在 swift target-action 对应的方法需要以OC的方式来调用,那么OC语言中用Selector来表示一个方法的名称(又称方法选择器),创建一个Selector可以使用 Selector("functionName") 的方式。
const method = Selector("timeChange")
// 监听时间变化回调
this.timePicker.addTarget(this, action = method, for = UIControl.Event.valueChanged)
// 设置为时间选择模式
this.timePicker.datePickerMode = UIDatePicker.Mode.time
// 设置外观样式为 wheels
if (UTSiOS.available("iOS 13.4, *")) {
this.timePicker.preferredDatePickerStyle = UIDatePickerStyle.wheels
}
this.updateTime()
this.bindView(hour, minute)
}
// element 绑定原生view
bindView(hour : number, minute : number) {
this.element.bindIOSView(this.timePicker);
}
// 设置时
setHour(hour : number) {
this.h = hour
this.updateTime()
}
// 设置分
setMinute(minute : number) {
this.m = minute
this.updateTime()
}
updateTime() {
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm"
let date = formatter.date(from = `${this.h}:${this.m}`)
if (date != null) {
this.timePicker.date = date!
}
}
/**
* 按钮点击回调方法
* 在 swift 中,所有target-action (例如按钮的点击事件,NotificationCenter 的通知事件等)对应的 action 函数前面都要使用 @objc 进行标记。
*/
@objc timeChange() {
// 发送事件
console.log("timeChange")
let formatter = DateFormatter()
formatter.dateFormat = "HH"
let hourString = formatter.string(from = this.timePicker.date)
formatter.dateFormat = "mm"
let minuteString = formatter.string(from = this.timePicker.date)
const detail = { "hour": hourString, "minute": minuteString }
const event = new UniObjectCustomEvent("timechanged", detail)
this.element.dispatchEvent(event)
}
destroy() {
UTSiOS.destroyInstance(self)
}
}
uni_modules/uni-upgrade-center-app/changelog.md
浏览文件 @
9d291587
## 0.8.3(2024-07-31)
-
修复 部分类型报错
## 0.8.2(2024-07-15)
-
更新 static 下的静态图片放入 static/app 目录下,防止编译除 app 平台以外的平台时带入
## 0.8.1(2024-04-28)
...
...
uni_modules/uni-upgrade-center-app/components/uni-upgrade-center-app/uni-upgrade-center-app.uvue
浏览文件 @
9d291587
...
...
@@ -228,7 +228,7 @@
.sort((cur: StoreListItem, next: StoreListItem): number => next.priority - cur.priority)
.map((item: StoreListItem): string => item.scheme)
.reduce((promise: Promise<boolean>, cur: string): Promise<boolean> => {
openSchemePromise = promise.catch((): Promise<boolean> => openSchema(cur))
openSchemePromise = promise.catch
<boolean>
((): Promise<boolean> => openSchema(cur))
return openSchemePromise!
}, openSchemePromise!)
return openSchemePromise!
...
...
uni_modules/uni-upgrade-center-app/package.json
浏览文件 @
9d291587
{
"id"
:
"uni-upgrade-center-app"
,
"displayName"
:
"升级中心 uni-upgrade-center - App"
,
"version"
:
"0.8.
2
"
,
"version"
:
"0.8.
3
"
,
"description"
:
"uni升级中心 - 客户端检查更新"
,
"keywords"
:
[
"uniCloud"
,
...
...
uni_modules/uni-upgrade-center-app/utils/check-update.ts
浏览文件 @
9d291587
...
...
@@ -177,7 +177,7 @@ function updateUseModal(packageInfo : UniUpgradeCenterResult) : void {
fail
:
err
=>
{
uni
.
showModal
({
title
:
'
更新失败
'
,
content
:
err
.
message
,
content
:
err
.
errMsg
,
showCancel
:
false
});
}
...
...
windows/top-window.uvue
浏览文件 @
9d291587
...
...
@@ -2,8 +2,8 @@
<view class="top-window-header">
<view class="left-header">
<navigator class="left-header" open-type="reLaunch" url="/pages/component/global-properties/global-properties">
<image src="/static/
logo
.png" class="logo" mode="heightFix"></image>
<text>hello uni-app</text>
<image src="/static/
uni
.png" class="logo" mode="heightFix"></image>
<text>hello uni-app
x
</text>
</navigator>
</view>
<custom-tab-bar class="tab-bar-flex" direction="horizontal" :show-icon="false" :selected="current"
...
...
@@ -13,8 +13,8 @@
<script lang="uts">
type IndexPageItem = {
tabBar : string;
index
: s
tring;
tabBar : string
.PageURIString
;
index
PageUrl : string.PageURIS
tring;
}
type OnTabItemTapEvent = {
pagePath : string;
...
...
@@ -33,16 +33,16 @@
current: 0,
indexPage: [{
tabBar: '/pages/tabBar/component',
index: '/pages/component/global-properties/global-properties'
index
PageUrl
: '/pages/component/global-properties/global-properties'
}, {
tabBar: '/pages/tabBar/API',
index: '/pages/API/get-app/get-app'
index
PageUrl
: '/pages/API/get-app/get-app'
}, {
tabBar: '/pages/tabBar/CSS',
index: '/pages/CSS/layout/width'
index
PageUrl
: '/pages/CSS/layout/width'
}, {
tabBar: '/pages/tabBar/template',
index
: '/pages/template/long-list/long-list
'
index
PageUrl: '/pages/template/slider-100/slider-100
'
}] as IndexPageItem[]
}
},
...
...
@@ -69,7 +69,7 @@
return
}
uni.redirectTo({
url: indexPageItem.index
url: indexPageItem.index
PageUrl
})
return
} else {
...
...
@@ -86,7 +86,7 @@
for (const item of this.indexPage) {
if (activeTabBar === item.tabBar) {
uni.redirectTo({
url: item.index
url: item.index
PageUrl
})
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录