提交 bb209b71 编写于 作者: DCloud-yyl's avatar DCloud-yyl

Merge branch 'dev' into alpha

# Conflicts:
#	manifest.json
#	pages/API/get-battery-info/get-battery-info.test.js
#	pages/API/get-current-pages/get-current-pages.test.js
#	pages/API/get-current-pages/get-current-pages.uvue
#	pages/API/get-file-system-manager/get-file-system-manager.uvue
#	pages/API/request-payment/request-payment.uvue
#	pages/API/request/request.uvue
#	pages/API/save-image-to-photos-album/save-image-to-photos-album.uvue
#	pages/component/textarea/textarea.uvue
#	pages/tabBar/API.uvue
#	pages/template/schema/schema.uvue
#	uni_modules/uni-upgrade-center-app/package.json
......@@ -8,6 +8,17 @@
<application>
<!-- 注册 url schemes -->
<activity android:name="io.dcloud.uniapp.UniLaunchProxyActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="hellouniappx"></data> <!-- 注册 hellouniappx:// 链接打开应用 -->
<data android:scheme="uniappxhello"></data> <!-- 注册 uniappxhello:// 链接打开应用 -->
</intent-filter>
</activity>
</application>
......
<template name="page-head">
<template>
<view class="common-page-head">
<view class="common-page-head-title-box">
<text class="common-page-head-title">{{title}}</text>
......
@font-face {
font-family: "UniIconsLight";
src: url('./uniicons.ttf') format('truetype');
}
.uni-icons {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
}
.uniui-back:before {
content: "\e600";
}
<template>
<view class="uni-navbar">
<view class="uni-navbar-inner" :style="navbarStyle">
<view class="uni-navbar">
<view v-if="statusBar" class="status-bar"></view>
<view class="uni-navbar-inner">
<view class="left-content" @click="back">
<text :style="{ color: textColor }" class="uni-icons">{{
unicode
......@@ -34,7 +35,11 @@
textColor: {
type: String,
default: "#000",
},
},
statusBar: {
type: Boolean,
default: false,
}
},
data() {
return {
......@@ -42,9 +47,6 @@
};
},
computed: {
navbarStyle() : string {
return `margin-top:${this.statusBarHeight}px`;
},
unicode() : string {
return "\ue600";
},
......@@ -59,9 +61,6 @@
console.log(err);
},
});
const sys = uni.getSystemInfoSync();
const statusBarHeight = sys.statusBarHeight;
this.statusBarHeight = statusBarHeight;
},
mounted() {
uni.setNavigationBarColor({
......@@ -84,7 +83,10 @@
font-style: normal;
color: #333;
}
.status-bar {
height: var(--status-bar-height);
}
.uni-navbar {
background-color: #007aff;
}
......
<template>
<view class="uni-navbar">
<view class="uni-navbar-inner" :style="navbarStyle">
<view class="left-content" @click="back">
<text class="uni-icons uniui-back"></text>
</view>
<view class="uni-navbar-content">
<slot>{{title}}</slot>
</view>
<view class="right-content">
<slot name="right"></slot>
</view>
</view>
</view>
</template>
<script>
export default {
name: "uni-navbar",
props: {
title: {
type: String,
default: ''
}
},
data() {
return {
statusBarHeight: 0
};
},
computed: {
navbarStyle() {
return `margin-top:${this.statusBarHeight}px`
},
},
created() {
const sys = uni.getSystemInfoSync()
const statusBarHeight = sys.statusBarHeight
this.statusBarHeight = statusBarHeight
},
methods: {
back() {
uni.navigateBack({})
}
},
}
</script>
<style>
@import './uni-icons.css';
.uni-icons {
font-family: UniIconsLight;
text-decoration: none;
text-align: center;
font-size: 22px;
font-style: normal;
color: #333;
}
.uni-navbar {
border: 1px #eee solid;
background-color: #fff;
}
.uni-navbar-inner {
position: relative;
flex-direction: row;
justify-content: space-between;
height: 45px;
}
.left-content,
.right-content {
justify-content: center;
align-items: center;
width: 45px;
height: 100%;
}
.uni-navbar-content {
position: absolute;
height: 100%;
top: 0;
bottom: 0;
left: 45px;
right: 45px;
justify-content: center;
align-items: center;
}
</style>
......@@ -46,6 +46,8 @@
<input type="file" />
<p style="font-size: 14px;">&lt;input type="file" accept="image/*" multiple /&gt;</p>
<input type="file" accept="image/*" multiple />
<p style="font-size: 14px;">普通input</p>
<input placeholder="底部输入框"/>
</div>
<!-- uni 的 SDK -->
<script type="text/javascript" src="uni.webview.1.5.5.js"></script>
......
......@@ -6,9 +6,6 @@ import App from './App.uvue'
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
app.config.errorHandler = (err, vm, info) => {
console.log(err, vm, info)
}
// app.mixin({
// onReady() {
// setTimeout(() => {
......
......@@ -33,7 +33,13 @@
"modules": {
"uni-payment":{
"alipay":{},
"wxpay":{}
"wxpay":{
"android": {},
"ios": {
"appid": "wxd1b990d3136e369c",
"universalLink": "https://hellouniappx.dcloud.net.cn/ulink/"
}
}
},
"uni-ad": {
"gdt": {}
......@@ -50,6 +56,13 @@
"h5": {
"router": {
"base": "/web/"
},
"sdkConfigs" : {
"maps" : {
"qqmap" : {
"key" : "TKUBZ-D24AF-GJ4JY-JDVM2-IBYKK-KEBCU"
}
}
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:hellouniappx.dcloud.net.cn</string>
</array>
</dict>
</plist>
......@@ -599,25 +599,77 @@
"navigationBarTitleText": "get-app-authorize-setting"
}
},
// #endif
{
"path": "pages/API/preview-image/preview-image",
"style": {
"navigationBarTitleText": "图片预览"
}
},
{
"path": "pages/API/choose-image/choose-image",
"style": {
"navigationBarTitleText": "拍摄图片或从相册中选择图片"
}
},
// #ifdef APP-ANDROID || WEB
{
"path" : "pages/API/get-image-info/get-image-info",
"style" :
{
"navigationBarTitleText" : "获取图片信息"
}
},
// #endif
// #ifdef APP-ANDROID
{
"path" : "pages/API/compress-image/compress-image",
"style" :
{
"navigationBarTitleText" : "压缩图片"
}
},
// #endif
{
"path" : "pages/API/choose-video/choose-video",
"style" :
{
"navigationBarTitleText" : "拍摄视频或从相册中选择视频"
}
},
// #ifndef WEB
{
"path": "pages/API/save-image-to-photos-album/save-image-to-photos-album",
"style": {
"navigationBarTitleText": "保存图片到相册"
}
},
{
"path" : "pages/API/save-video-to-photos-album/save-video-to-photos-album",
"style" :
{
"navigationBarTitleText" : "保存视频到相册"
}
},
// #endif
// #ifdef APP-ANDROID || WEB
{
"path": "pages/API/preview-image/preview-image",
"style": {
"navigationBarTitleText": "图片预览"
"path" : "pages/API/get-video-info/get-video-info",
"style" :
{
"navigationBarTitleText" : "获取视频信息"
}
},
// #endif
// #ifdef APP-ANDROID
{
"path": "pages/API/choose-image/choose-image",
"style": {
"navigationBarTitleText": "图片"
"path" : "pages/API/compress-video/compress-video",
"style" :
{
"navigationBarTitleText" : "压缩视频"
}
},
// #endif
{
"path": "pages/API/get-network-type/get-network-type",
"style": {
......@@ -1179,6 +1231,48 @@
"navigationBarTitleText": "如何使用浏览器 canvas"
}
},
{
"path" : "pages/component/movable-view/movable-view",
"style" :
{
"navigationBarTitleText" : "movable-view"
}
},
{
"path" : "pages/component/label/label",
"style" :
{
"navigationBarTitleText" : "label"
}
},
{
"path" : "pages/component/picker/picker",
"style" :
{
"navigationBarTitleText" : "picker"
}
},
{
"path" : "pages/component/map/map",
"style" :
{
"navigationBarTitleText" : "map"
}
},
{
"path" : "pages/component/cover-view/cover-view",
"style" :
{
"navigationBarTitleText" : "cover-view"
}
},
{
"path" : "pages/component/editor/editor",
"style" :
{
"navigationBarTitleText" : "editor"
}
},
// #endif
// #ifdef APP
{
......@@ -1258,6 +1352,13 @@
"enablePullDownRefresh": false
}
},
{
"path": "pages/API/theme-change/theme-change",
"style": {
"navigationBarTitleText": "主题切换",
"enablePullDownRefresh": false
}
},
{
"path": "uni_modules/uni-pay-x/pages/success/success",
"style": {
......
......@@ -182,16 +182,17 @@ describe('API-loading', () => {
await page.waitFor(500);
if (isApp) {
const image = await program.screenshot({
deviceShot: true,
area: {
x: 0,
y: 200,
height: windowHeight - 100,
width:windowWidth
},
});
expect(image).toSaveImageSnapshot();
// add since 2024-04-22 app 不再截图,避免跨平台对比失败
// const image = await program.screenshot({
// deviceShot: true,
// area: {
// x: 0,
// y: 200,
// height: windowHeight - 100,
// width:windowWidth
// },
// });
// expect(image).toSaveImageSnapshot();
}else{
const image = await program.screenshot({
deviceShot: true,
......
......@@ -113,7 +113,7 @@
export default {
data() {
return {
title: 'choose/previewImage',
title: 'chooseImage',
imageList: [] as Array<string>,
sourceTypeIndex: 2,
sourceType: ['拍照', '相册', '拍照或相册'],
......
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<video class="video" :src="src" :controls="true"></video>
<view class="uni-title">
<text class="uni-subtitle-text">视频信息</text>
</view>
<text>{{videoInfo}}</text>
<view class="uni-btn-v">
<button type="primary" @click="chooseVideo">选取视频</button>
</view>
<enum-data title="视频来源" :items="sourceTypeItemTypes" @change="onSourceTypeChange"></enum-data>
<enum-data title="摄像头" :items="cameraItemTypes" @change="onCameraChange"></enum-data>
</view>
<input-data title="最长拍摄时间,单位秒" defaultValue="60" type="number" @confirm="onMaxDurationConfirm"></input-data>
<!-- #ifdef APP -->
<view class="uni-padding-wrap">
<boolean-data title="是否压缩" :defaultValue="true" @change="onCompressedChange"></boolean-data>
</view>
<!-- #endif -->
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
import { ItemType } from '@/components/enum-data/enum-data';
export default {
data() {
return {
title: "chooseVideo",
src: "",
sourceTypeItemTypes: [{ "value": 0, "name": "从相册中选择视频" }, { "value": 1, "name": "拍摄视频" }, { "value": 2, "name": "从相册中选择视频或拍摄视频" }] as ItemType[],
sourceTypeItems: [["album"], ["camera"], ["album", "camera"]],
cameraItemTypes: [{ "value": 0, "name": "后置摄像头" }, { "value": 1, "name": "前置摄像头" }] as ItemType[],
cameraItems: ["back", "front"],
sourceType: ["album", "camera"],
compressed: true,
maxDuration: 60,
camera: "back",
videoInfo: ""
}
},
methods: {
chooseVideo() {
uni.chooseVideo({
sourceType: this.sourceType,
// #ifdef APP
compressed: this.compressed,
// #endif
maxDuration: this.maxDuration,
camera: this.camera,
success: (res) => {
console.log("chooseVideo success", JSON.stringify(res));
this.src = res.tempFilePath;
this.videoInfo = `视频长度: ${res.duration}s\n视频大小: ${Math.ceil(res.size / 1024)}KB\n视频宽度: ${res.width}\n视频高度: ${res.height}\n`;
},
fail: (err) => {
uni.showModal({
title: "选择视频失败",
content: JSON.stringify(err),
showCancel: false
});
}
});
},
onSourceTypeChange(value : number) {
this.sourceType = this.sourceTypeItems[value];
},
onCompressedChange(value : boolean) {
this.compressed = value;
},
onMaxDurationConfirm(value : number) {
this.maxDuration = value;
},
onCameraChange(value : number) {
this.camera = this.cameraItems[value];
}
}
}
</script>
<style>
.video {
align-self: center;
width: 300px;
height: 225px;
}
</style>
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<view class="image-container">
<image class="image" :src="beforeCompressPath" mode="aspectFit"></image>
<image class="image" :src="afterCompressPath" mode="aspectFit"></image>
</view>
<view class="uni-title">
<text class="uni-subtitle-text">压缩前图片信息</text>
</view>
<text>{{beforeCompressImageInfo}}</text>
<view class="uni-title">
<text class="uni-subtitle-text">压缩后图片信息</text>
</view>
<text>{{afterCompressImageInfo}}</text>
<view class="uni-btn-v">
<button type="primary" @click="chooseImage">从相册中选取待压缩的图片</button>
</view>
<view class="uni-btn-v">
<button type="primary" @click="compressImage">压缩图片</button>
</view>
</view>
<input-data defaultValue="80" title="压缩质量,范围0~100,数值越小,质量越低,压缩率越高(仅对jpg有效)" type="number"
@confirm="onQualityConfirm"></input-data>
<input-data title="压缩后图片的宽度,单位px" type="string" @confirm="onCompressedWidthConfirm"></input-data>
<input-data title="压缩后图片的高度,单位px" type="string" @confirm="onCompressedHeightConfirm"></input-data>
<input-data defaultValue="auto" title="压缩后图片的宽度,支持px、%、auto" type="string" @confirm="onWidthConfirm"></input-data>
<input-data defaultValue="auto" title="压缩后图片的高度,支持px、%、auto" type="string" @confirm="onHeightConfirm"></input-data>
<input-data defaultValue="0" title="旋转度数,范围0~360" type="number" @confirm="onRotateConfirm"></input-data>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
// #ifdef APP-ANDROID
import FileInputStream from 'java.io.FileInputStream';
// #endif
export default {
data() {
return {
title: "compressImage",
beforeCompressImageInfo: "",
afterCompressImageInfo: "",
beforeCompressPath: "",
afterCompressPath: "",
quality: 80,
compressedWidth: null as number | null,
compressedHeight: null as number | null,
width: "auto",
height: "auto",
rotate: 0
}
},
methods: {
compressImage() {
if (this.beforeCompressPath == "") {
uni.showToast({
title: "请先选择图片",
icon: "error"
});
return;
}
uni.showLoading({
title: "图片压缩中"
});
uni.compressImage({
src: this.beforeCompressPath,
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));
this.afterCompressPath = res.tempFilePath;
uni.showToast({
title: "压缩成功",
icon: null
});
uni.getImageInfo({
src: res.tempFilePath,
success: (_res) => {
this.afterCompressImageInfo = `图片宽度: ${_res.width}\n图片高度: ${_res.height}\n`;
// #ifdef APP-ANDROID
const size = new FileInputStream(res.tempFilePath.substring("file://".length)).available() / 1024;
this.afterCompressImageInfo = this.afterCompressImageInfo.concat(`图片大小: ${size}KB`);
// #endif
}
});
},
fail: (err) => {
uni.showModal({
title: "压缩图片失败",
content: JSON.stringify(err),
showCancel: false
});
},
complete: (_) => {
uni.hideLoading();
}
})
},
chooseImage() {
uni.chooseImage({
count: 1,
sizeType: ["original"],
sourceType: ["album"],
success: (res) => {
this.beforeCompressPath = res.tempFilePaths[0];
uni.getImageInfo({
src: res.tempFilePaths[0],
success: (_res) => {
this.beforeCompressImageInfo = `图片宽度: ${_res.width}\n图片高度: ${_res.height}\n`;
// #ifdef APP-ANDROID
const size = new FileInputStream(res.tempFilePaths[0].substring("file://".length)).available() / 1024;
this.beforeCompressImageInfo = this.beforeCompressImageInfo.concat(`图片大小: ${size}KB`);
// #endif
}
});
}
});
},
onQualityConfirm(value : number) {
this.quality = value;
},
onCompressedWidthConfirm(value : string) {
this.compressedWidth = parseInt(value);
},
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;
}
}
}
</script>
<style>
.image {
flex: 1;
}
.image-container {
flex-direction: row;
}
</style>
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<video class="video" :src="beforeCompressPath" :controls="true"></video>
<view class="uni-title">
<text class="uni-subtitle-text">压缩前视频信息</text>
</view>
<text>{{beforeCompressVideoInfo}}</text>
<video class="video" :src="afterCompressPath" :controls="true"></video>
<view class="uni-title">
<text class="uni-subtitle-text">压缩后视频信息</text>
</view>
<text>{{afterCompressVideoInfo}}</text>
<view class="uni-btn-v">
<button type="primary" @click="chooseVideo">从相册中选取待压缩的视频</button>
</view>
<view class="uni-btn-v">
<button type="primary" @click="compressVideo">压缩视频</button>
</view>
<enum-data title="压缩质量" :items="qualityItemTypes" @change="onQualityChange"></enum-data>
<view class="uni-common-mt">
<text class="uni-title uni-title-text">相对于原视频的分辨率比例,取值范围(0, 1]</text>
<slider :min="0.1" :max="1" :step="0.1" :show-value="true" @change="onResolutionChange"></slider>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
import { ItemType } from '@/components/enum-data/enum-data';
export default {
data() {
return {
title: "compressVideo",
beforeCompressVideoInfo: "",
afterCompressVideoInfo: "",
beforeCompressPath: "",
afterCompressPath: "",
quality: null as string | null,
bitrate: null as number | null,
fps: null as number | null,
resolution: null as number | null,
qualityItemTypes: [{ "value": 0, "name": "low(低)" }, { "value": 1, "name": "medium(中)" }, { "value": 2, "name": "high(高)" }] as ItemType[],
qualityItems: ["low", "medium", "high"]
}
},
methods: {
compressVideo() {
if (this.beforeCompressPath == "") {
uni.showToast({
title: "请先选择视频",
icon: "error"
});
return;
}
uni.showLoading({
title: "视频压缩中"
});
uni.compressVideo({
src: this.beforeCompressPath,
quality: this.quality,
resolution: this.resolution,
success: (res) => {
console.log("compressVideo success", JSON.stringify(res));
this.afterCompressPath = res.tempFilePath;
uni.showToast({
title: "压缩成功",
icon: null
});
uni.getVideoInfo({
src: res.tempFilePath,
success: (_res) => {
this.afterCompressVideoInfo = `视频画面方向: ${_res.orientation}\n视频格式: ${_res.type}\n视频长度: ${_res.duration}s\n视频大小: ${_res.size}KB\n视频宽度: ${_res.width}\n视频高度: ${_res.height}\n视频帧率: ${_res.fps}fps\n视频码率: ${_res.bitrate}kbps`;
}
});
},
fail: (err) => {
uni.showModal({
title: "压缩视频失败",
content: JSON.stringify(err),
showCancel: false
});
},
complete: (_) => {
uni.hideLoading();
}
});
},
chooseVideo() {
uni.chooseVideo({
sourceType: ["album"],
compressed: false,
success: (res) => {
this.beforeCompressPath = res.tempFilePath;
uni.getVideoInfo({
src: res.tempFilePath,
success: (_res) => {
this.beforeCompressVideoInfo = `视频画面方向: ${_res.orientation}\n视频格式: ${_res.type}\n视频长度: ${_res.duration}s\n视频大小: ${_res.size}KB\n视频宽度: ${_res.width}\n视频高度: ${_res.height}\n视频帧率: ${_res.fps}fps\n视频码率: ${_res.bitrate}kbps`;
}
});
}
});
},
onQualityChange(value : number) {
this.quality = this.qualityItems[value];
},
onResolutionChange(event : UniSliderChangeEvent) {
this.resolution = event.detail.value;
}
}
}
</script>
<style>
.video {
align-self: center;
}
.image-container {
flex-direction: row;
}
</style>
......@@ -20,7 +20,25 @@ describe('ExtApi-DownloadFile', () => {
it('Check ', async () => {
expect(res).toBe(true);
});
});
if (!process.env.uniTestPlatformInfo.startsWith('web')) {
it('Check uni.env', async () => {
await page.callMethod('jest_downloadFile_with_uni_env');
await page.waitFor(2000);
res = await page.data('jest_result');
expect(res).toBe(true);
});
it('Check Download File In UTS Module', async () => {
res = await page.callMethod('jest_uts_module_invoked')
await page.waitFor(2000);
res = await page.data('jest_result');
expect(res).toBe(true)
})
}
let shouldTestCookie = false
if (process.env.uniTestPlatformInfo.startsWith('android') && !process.env.UNI_AUTOMATOR_APP_WEBVIEW) {
......
......@@ -18,7 +18,12 @@
</scroll-view>
<!-- #endif -->
</template>
<script>
<script>
import {
testInovkeDownloadFile,
CommonOptions
} from '@/uni_modules/test-invoke-network-api'
export default {
data() {
return {
......@@ -71,6 +76,19 @@
});
},
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",
......@@ -114,6 +132,18 @@
this.jest_result = needCookie ? false : true;
}
});
},
jest_uts_module_invoked(){
testInovkeDownloadFile({
success:(res: any)=>{
console.log("success :", res);
this.jest_result = true
},
fail:(err: any)=>{
console.log("fail :", err);
this.jest_result = false
}
} as CommonOptions)
}
}
}
......
......@@ -52,21 +52,21 @@ describe('event-bus', () => {
expect(l3).toBe(0)
})
// it('off-all', async () => {
// await page.callMethod('clear')
// await page.callMethod('on')
// await page.callMethod('on2')
// await page.callMethod('emit')
// const l1 = (await page.data()).log.length
// expect(l1).toBe(2)
it('off-all', async () => {
await page.callMethod('clear')
await page.callMethod('on')
await page.callMethod('on2')
await page.callMethod('emit')
const l1 = (await page.data()).log.length
expect(l1).toBe(2)
// await page.callMethod('clear')
// const l2 = (await page.data()).log.length
// expect(l2).toBe(0)
await page.callMethod('clear')
const l2 = (await page.data()).log.length
expect(l2).toBe(0)
// await page.callMethod('offAll')
// await page.callMethod('emit')
// const l3 = (await page.data()).log.length
// expect(l3).toBe(0)
// })
await page.callMethod('offAll')
await page.callMethod('emit')
const l3 = (await page.data()).log.length
expect(l3).toBe(0)
})
})
......@@ -48,8 +48,7 @@
uni.$off('test', this.fn)
},
offAll() {
// TODO 第二个参数为可选,后续优化后可不传递
//uni.$off('test', null)
uni.$off('test')
},
emit() {
uni.$emit('test', 'msg:' + Date.now())
......
......@@ -10,6 +10,16 @@ describe('ExtApi-GetAppBaseInfo', () => {
]
const numberProperties = [
'uniCompilerVersionCode', 'uniRuntimeVersionCode'
]
const booleanProperties = [
'isUniAppX'
]
const requiredProperties = [
'uniCompilerVersion',
'uniCompilerVersionCode',
'uniRuntimeVersion',
'uniRuntimeVersionCode',
'isUniAppX'
]
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
......@@ -28,6 +38,19 @@ describe('ExtApi-GetAppBaseInfo', () => {
expect(value).not.toBeNull();
expect(value).toBeGreaterThanOrEqual(3.90);
}
if (booleanProperties.indexOf(key) != -1) {
expect(value).not.toBeNull();
expect(typeof value).toBe('boolean');
}
if (key == "appTheme") {
expect(['light', 'dark', 'auto']).toContain(value);
}
}
});
});
it('Check GetSystemInfoSync required properties', async () => {
for (let i = 0; i < requiredProperties.length; i++) {
const key = requiredProperties[i]
expect(`${key} not null: ${res[key] != null}`).toBe(`${key} not null: true`)
}
})
});
......@@ -7,12 +7,13 @@ describe('ExtApi-GetBatteryInfo', () => {
})
return
}
if (process.env.uniTestPlatformInfo.toLowerCase().startsWith('ios')) {
if(process.env.uniTestPlatformInfo.toLowerCase().startsWith('ios')) {
it('dummyTest', () => {
expect(1).toBe(1)
})
return
}
let page;
let res;
......@@ -22,7 +23,7 @@ describe('ExtApi-GetBatteryInfo', () => {
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
await page.waitFor(600);
res = await uni.getBatteryInfo();
res = await page.data();
});
it('Check properties', async () => {
......
......@@ -33,12 +33,15 @@ describe('getCurrentPages', () => {
expect(isEnablePullDownRefresh1).toBe(true)
// setPageStyle
await page.callMethod('setPageStyle', false)
await page.callMethod('setPageStyle', {
enablePullDownRefresh: false
})
await page.waitFor(200)
await page.callMethod('getPageStyle')
await page.waitFor(200)
const isEnablePullDownRefresh2 = (await page.data()).currentPageStyle.enablePullDownRefresh
const data2 = await page.data()
const isEnablePullDownRefresh2 = data2.currentPageStyle.enablePullDownRefresh
expect(isEnablePullDownRefresh2).toBe(false)
await page.callMethod('startPullDownRefresh')
......@@ -47,7 +50,9 @@ describe('getCurrentPages', () => {
expect(image2).toSaveImageSnapshot();
await page.waitFor(3500)
await page.callMethod('setPageStyle', true)
await page.callMethod('setPageStyle', {
enablePullDownRefresh: true
})
await page.waitFor(200)
await page.callMethod('startPullDownRefresh')
await page.waitFor(500)
......
<template>
<page-head title="getCurrentPages"></page-head>
<view class="uni-padding-wrap">
<button @click="_getCurrentPages">getCurrentPages</button>
<view v-if="pages.length" style="padding: 15px 0px">
<text>当前页面栈中 {{ pages.length }} 个页面,列表如下:</text>
<template v-for="(page, index) in pages" :key="page.route">
<text style="margin-top: 5px">index: {{ index }}, route: {{ page.route }}</text>
</template>
<!-- #ifdef APP -->
<scroll-view class="page-scroll-view">
<!-- #endif -->
<page-head title="getCurrentPages"></page-head>
<view class="uni-padding-wrap">
<button @click="_getCurrentPages">getCurrentPages</button>
<view v-if="pages.length" style="padding: 15px 0px">
<text>当前页面栈中 {{ pages.length }} 个页面,列表如下:</text>
<template v-for="(page, index) in pages" :key="page.route">
<text style="margin-top: 5px">index: {{ index }}, route: {{ page.route }}</text>
</template>
</view>
</view>
<button class="btn btn-get-page-style" type="default" @click="getPageStyle">getPageStyle</button>
<button class="btn btn-set-page-style-1" type="default" @click="setPageStyle(true)">setPageStyle(true)</button>
<button class="btn btn-set-page-style-0" type="default" @click="setPageStyle(false)">setPageStyle(false)</button>
<text class="page-style">当前 PageStyle</text>
<text class="page-style-value">{{pageStyleText}}</text>
<text class="status">状态:</text>
<view class="status-list">
<text>enablePullDownRefresh: {{enablePullDownRefreshStatus}}</text>
</view>
<text class="tips">当前版本仅支持设置属性 enablePullDownRefresh</text>
</view>
<page-head title="currentPageStyle"></page-head>
<template v-for="(item, index) in PageStyleArray">
<view class="page-style-item" v-if="currentPageStyle[item.key]!=null" :key="index">
<view class="item-text">
<text class="item-text-key">{{item.key}}:</text>
<text class="item-text-value">{{currentPageStyle[item.key]}}</text>
</view>
<view class="set-value" v-if="item.type == 'boolean'">
<switch :checked="currentPageStyle.getBoolean(item.key)"
@change="switchChange(item.key, $event as UniSwitchChangeEvent)">
</switch>
</view>
<view class="set-value" v-else-if="item.type == 'number'">
<slider :value="currentPageStyle.getNumber(item.key)" :show-value="true"
@change="sliderChange(item.key, $event as UniSliderChangeEvent)" />
</view>
<view class="set-value" v-else-if="item.type == 'string'">
<radio-group class="radio-set-value" @change="radioChange(item.key, $event as RadioGroupChangeEvent)">
<radio class="radio-value" v-for="(item2, index2) in item.value" :key="index2" :value="item2" >{{item2}}</radio>
</radio-group>
</view>
</view>
</template>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
import { PageStyleItem, PageStyleArray } from './page-style.uts';
class Page {
constructor(public route : string) {
}
......@@ -32,9 +54,8 @@
return {
checked: false,
pages: [] as Page[],
currentPageStyle: {} as UTSJSONObject,
// TODO
enablePullDownRefreshStatus: true
PageStyleArray: PageStyleArray as PageStyleItem[],
currentPageStyle: {} as UTSJSONObject,
}
},
computed: {
......@@ -42,12 +63,18 @@
return JSON.stringify(this.currentPageStyle)
}
},
onLoad() {
this.getPageStyle();
},
onPullDownRefresh() {
setTimeout(() => {
uni.stopPullDownRefresh()
}, 3000)
}, 2000)
},
methods: {
startPullDownRefresh() {
uni.startPullDownRefresh()
},
_getCurrentPages: function () {
this.pages.length = 0
const pages = getCurrentPages()
......@@ -62,23 +89,34 @@
}
}
},
getPageStyle() {
/// get-set-page-style
radioChange(key : string, e : RadioGroupChangeEvent) {
this.setStyleValue(key, e.detail.value);
},
sliderChange(key : string, e : UniSliderChangeEvent) {
this.setStyleValue(key, e.detail.value);
},
switchChange(key : string, e : UniSwitchChangeEvent) {
this.setStyleValue(key, e.detail.value);
},
setStyleValue(key : string, value : any) {
const style = {}
style[key] = value
this.setPageStyle(style)
this.getPageStyle()
},
getPageStyle() : UTSJSONObject {
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
this.currentPageStyle = currentPage.$getPageStyle();
this.currentPageStyle = currentPage.$getPageStyle()
return this.currentPageStyle;
},
setPageStyle(enable : boolean) {
// 目前仅支持 enablePullDownRefresh
setPageStyle(style : UTSJSONObject) {
console.log('setPageStyle:', style);
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
currentPage.$setPageStyle({
enablePullDownRefresh: enable
});
this.enablePullDownRefreshStatus = enable
},
startPullDownRefresh() {
uni.startPullDownRefresh()
}
currentPage.$setPageStyle(style);
},
// getCurrentPage(): Page {
// const pages = getCurrentPages();
// const currentPage = pages[pages.length - 1];
......@@ -88,37 +126,44 @@
}
</script>
<style>
.btn {
.page {
flex: 1;
padding: 10px;
}
.page-style {
margin-top: 15px;
}
.page-style-item {
padding: 10px;
margin-top: 10px;
}
.page-style {
margin-top: 15px;
background-color: #ffffff;
border-radius: 5px;
}
.page-style-value {
margin-top: 5px;
padding: 5px;
background-color: #fff;
width: 100%;
/* #ifdef WEB */
overflow-wrap: break-word;
/* #endif */
}
.status {
margin-top: 20px;
}
.status-list {
margin-top: 5px;
.item-text {
flex-direction: row;
}
.tips {
font-size: 12px;
margin-top: 15px;
opacity: .8;
.item-text-key {
font-weight: bold;
}
.item-text-value {
margin-left: 5px;
}
.set-value {
margin-top: 10px;
}
.radio-set-value {
flex-direction: row;
}
.radio-value {
margin-left: 10px;
}
</style>
export type PageStyleItem = {
key : string
type : string
value: Array<any>
}
export const PageStyleArray = [
{
key: "navigationBarBackgroundColor",
type: "string",
value: ["#007AFF", "#FFFFFF", "#000000"]
},
{
key: "navigationBarTextStyle",
type: "string",
value: ["white", "black"]
},
{
key: "navigationBarTitleText",
type: "string",
value: ["title1", "title2", "title3"]
},
{
key: "navigationStyle",
type: "string",
value: ["default", "custom"]
},
{
key: "backgroundColor",
type: "string",
value: ["#FFFFFF", "#000000"]
},
{
key: "backgroundColorContent",
type: "string",
value: ["#FFFFFF", "#F0F0F0", "#000000"]
},
{
key: "backgroundTextStyle",
type: "string",
value: ["dark", "light"]
},
{
key: "enablePullDownRefresh",
type: "boolean",
value: [true, false]
},
{
key: "onReachBottomDistance",
type: "number",
value: [50, 100]
},
{
key: "pageOrientation",
type: "string",
value: ["auto", "portrait", "landscape"]
},
{
key: "backgroundColorTop",
type: "string",
value: ["#FFFFFF", "#000000"]
},
{
key: "backgroundColorBottom",
type: "string",
value: ["#FFFFFF", "#000000"]
},
{
key: "navigationBarAutoBackButton",
type: "boolean",
value: [true, false]
}] as PageStyleItem[]
......@@ -6,7 +6,8 @@ describe('ExtApi-GetDeviceInfo', () => {
let res;
const stringProperties = [
'brand', 'deviceBrand', 'deviceId', 'model', 'deviceModel',
'deviceType', 'devicePixelRatio', 'system', 'platform', 'uniRuntimeVersion',
'deviceType', 'devicePixelRatio', 'system', 'platform', 'uniRuntimeVersion',
'osName', 'osVersion', 'osLanguage', 'osTheme', 'romName', 'romVersion'
]
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
......
......@@ -164,12 +164,12 @@
this.statsRet = res.stats
console.log('this.statsRet', this.statsRet)
},
fail: (res : UniError) => {
fail: (res:IUniError ) => {
if (this.logAble) {
this.log += 'statFileInfoTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('statFileInfoTest fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
console.log("statFileInfoTest complete", res)
......@@ -195,12 +195,12 @@
this.getFileInfoSize = res.size
this.getFileInfoDigest = res.digest
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'getFileInfoTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
console.log("complete", res)
......@@ -224,12 +224,12 @@
}
console.log('success', res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'copyFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
console.log("complete", res)
......@@ -253,12 +253,12 @@
}
console.log('success', res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'renameFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
this.done = true
......@@ -281,12 +281,12 @@
console.log("success", res)
this.fileListSuccess = res.files
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'readDirTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
console.log("complete", res)
......@@ -313,12 +313,12 @@
}
console.log('success', res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'writeFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail')
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
this.done = true
......@@ -344,12 +344,12 @@
console.log('success', res)
this.readFileRet = res.data
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'readFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
console.log("complete", res)
......@@ -372,12 +372,12 @@
}
console.log('success', res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'rmdirTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
console.log("complete", res)
......@@ -402,12 +402,13 @@
}
console.log('success', res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'mkdirTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
if (res instanceof UniError) {
......@@ -431,12 +432,13 @@
console.log('success', res)
this.accessFileRet = res.errMsg
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'accessFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
if (res instanceof UniError) {
......@@ -459,12 +461,13 @@
}
console.log('success', res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'unlinkTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
if (res instanceof UniError) {
......@@ -497,12 +500,13 @@
}
console.log('success unlink', res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'unlinkAllFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail unlink', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
if (res instanceof UniError) {
......@@ -514,12 +518,13 @@
} as UnLinkOptions)
});
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'unlinkAllFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail to readdir', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
console.log("complete readdir", res)
......@@ -544,12 +549,13 @@
}
console.log('success', res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'copyFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
console.log("complete", res)
......@@ -573,12 +579,13 @@
}
console.log('success', res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'appendFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail')
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
this.done = true
......@@ -757,12 +764,13 @@
this.saveFileRet = res.savedFilePath
this.done = true
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'saveFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('saveFileTest fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
this.done = true
},
complete: (_) => {
......@@ -801,12 +809,13 @@
}
console.log('success', res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'unzipFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (_) => {
this.done = true
......@@ -825,12 +834,13 @@
this.fileListSuccess = res.fileList
this.getSavedFileListRet = "getSavedFileList:ok"
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'getSavedFileListTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('getSavedFileListTest fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
this.getSavedFileListRet = JSON.stringify(res)
},
complete: (res : any) => {
......@@ -855,12 +865,13 @@
}
console.log("success", res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'truncateFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
console.log("complete", res)
......@@ -894,12 +905,13 @@
}
console.log("success", res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'readCompressedFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (_) => {
this.done = true
......@@ -937,7 +949,7 @@
this.removeSavedFileRet = res.errMsg
console.log("removeSavedFileTest success", res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'removeSavedFileTest fail:' + JSON.stringify(res) + '\n\n'
}
......@@ -981,12 +993,13 @@
console.log("success", res)
this.fd = res.fd
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'openFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (_) => {
this.done = true
......@@ -1047,12 +1060,13 @@
this.closeFileRet = res.errMsg
console.log("success", res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'closeTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (_) => {
this.done = true
......@@ -1079,12 +1093,13 @@
console.log("success", res)
this.bytesWritten = res.bytesWritten
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'writeTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (_) => {
this.done = true
......@@ -1128,12 +1143,13 @@
this.done = true
}
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'openFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
this.done = true
}
} as OpenFileOptions)
......@@ -1150,12 +1166,13 @@
console.log("success", res)
this.fstat = res.stats
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'fstatTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (_) => {
this.done = true
......@@ -1193,12 +1210,13 @@
}
this.ftruncateRet = res.errMsg
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'ftruncateFileTest fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
},
complete: (res : any) => {
console.log("complete", res)
......@@ -1239,12 +1257,13 @@
}
console.log("success", res)
},
fail: (res : UniError) => {
fail: (res : IUniError) => {
if (this.logAble) {
this.log += 'readZipEntry fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg)
}
} as ReadZipEntryOptions)
},
......
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<view class="uni-title">
<text class="uni-subtitle-text">获取本地相对路径图片信息</text>
</view>
<image class="image" :src="relativeImagePath" mode="aspectFit"></image>
<text class="margin-top-10">{{absoluteImageInfo}}</text>
<view class="uni-title">
<text class="uni-subtitle-text">获取网络路径图片信息</text>
</view>
<image class="image" :src="remoteImagePath" mode="aspectFit"></image>
<text class="margin-top-10">{{remoteImageInfo}}</text>
<view class="uni-title">
<text class="uni-subtitle-text">获取本地绝对路径图片信息</text>
</view>
<image class="image" :src="absoluteImagePath" mode="aspectFit"></image>
<text class="margin-top-10">{{relativeImageInfo}}</text>
<view class="uni-btn-v">
<button type="primary" @click="chooseImage">拍摄照片或从相册中选择照片</button>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
export default {
data() {
return {
title: "getImageInfo",
relativeImagePath: "/static/test-image/logo.png",
relativeImageInfo: "",
absoluteImagePath: "",
absoluteImageInfo: "",
remoteImagePath: "https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/img/building.jpg",
remoteImageInfo: "",
}
},
methods: {
chooseImage() {
uni.chooseImage({
count: 1,
success: (res) => {
this.absoluteImagePath = res.tempFilePaths[0];
uni.getImageInfo({
src: res.tempFilePaths[0],
success: (_res) => {
console.log("getImageInfo success", JSON.stringify(res));
this.relativeImageInfo = `图片宽度: ${_res.width}\n图片高度: ${_res.height}\n图片路径: ${_res.path}\n图片方向: ${_res.orientation}\n图片格式: ${_res.type}`;
},
fail: (err) => {
uni.showModal({
title: "获取图片信息失败",
content: JSON.stringify(err),
showCancel: false
});
}
});
}
});
}
},
onReady() {
uni.getImageInfo({
src: this.relativeImagePath,
success: (res) => {
console.log("getImageInfo success", JSON.stringify(res));
this.absoluteImageInfo = `图片宽度: ${res.width}\n图片高度: ${res.height}\n图片路径: ${res.path}\n图片方向: ${res.orientation}\n图片格式: ${res.type}`;
},
fail: (err) => {
uni.showModal({
title: "获取图片信息失败",
content: JSON.stringify(err),
showCancel: false
});
}
});
uni.getImageInfo({
src: this.remoteImagePath,
success: (res) => {
console.log("getImageInfo success", JSON.stringify(res));
this.remoteImageInfo = `图片宽度: ${res.width}\n图片高度: ${res.height}\n图片路径: ${res.path}\n图片方向: ${res.orientation}\n图片格式: ${res.type}`;
},
fail: (err) => {
uni.showModal({
title: "获取图片信息失败",
content: JSON.stringify(err),
showCancel: false
});
}
});
}
}
</script>
<style>
.image {
align-self: center;
}
.margin-top-10 {
margin-top: 10px;
}
</style>
......@@ -15,6 +15,16 @@ describe('ExtApi-GetSystemInfo', () => {
'windowWidth',
'windowHeight', 'windowTop', 'windowBottom', 'screenTop',
'uniCompilerVersionCode', 'uniRuntimeVersionCode'
]
const booleanProperties = [
'isUniAppX'
]
const requiredProperties = [
'uniCompilerVersion',
'uniCompilerVersionCode',
'uniRuntimeVersion',
'uniRuntimeVersionCode',
'isUniAppX'
]
beforeAll(async () => {
......@@ -34,9 +44,25 @@ describe('ExtApi-GetSystemInfo', () => {
expect(value).not.toBeNull();
expect(value).toBeGreaterThanOrEqual(0);
}
if (booleanProperties.indexOf(key) != -1) {
expect(value).not.toBeNull();
expect(typeof value).toBe('boolean');
}
if (key == 'deviceOrientation') {
expect(['portrait', 'landscape']).toContain(value);
}
}
if (key == "osTheme") {
expect(['light', 'dark']).toContain(value);
}
if (key == "appTheme") {
expect(['light', 'dark', 'auto']).toContain(value);
}
}
});
});
it('Check GetSystemInfoSync required properties', async () => {
for (let i = 0; i < requiredProperties.length; i++) {
const key = requiredProperties[i]
expect(`${key} not null: ${res[key] != null}`).toBe(`${key} not null: true`)
}
})
});
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<view class="uni-title">
<text class="uni-subtitle-text">获取本地绝对路径视频信息</text>
</view>
<video class="video" :src="absoluteVideoPath" :controls="true"></video>
<text class="margin-top-10">{{absoluteVideoInfo}}</text>
<view class="uni-btn-v">
<button type="primary" @click="chooseVideo">拍摄视频或从相册中选择视频</button>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
export default {
data() {
return {
title: "getVideoInfo",
absoluteVideoPath: "",
absoluteVideoInfo: "",
}
},
methods: {
chooseVideo() {
uni.chooseVideo({
compressed: false,
success: (res) => {
this.absoluteVideoPath = res.tempFilePath;
uni.getVideoInfo({
src: res.tempFilePath,
success: (_res) => {
console.log("getVideoInfo success", JSON.stringify(res));
this.absoluteVideoInfo = `视频画面方向: ${_res.orientation}\n视频格式: ${_res.type}\n视频长度: ${_res.duration}s\n视频大小: ${_res.size}KB\n视频宽度: ${_res.width}\n视频高度: ${_res.height}\n视频帧率: ${_res.fps}fps\n视频码率: ${_res.bitrate}kbps`;
},
fail: (err) => {
uni.showModal({
title: "获取视频信息失败",
content: JSON.stringify(err),
showCancel: false
});
}
});
}
});
}
}
}
</script>
<style>
.video {
align-self: center;
}
.margin-top-10 {
margin-top: 10px;
}
</style>
......@@ -12,7 +12,15 @@ describe('interceptor', () => {
await newPage.waitFor('text')
const num = (await newPage.data()).page
await program.navigateBack()
expect(num).toBe(1)
expect(num).toBe(1)
// 新增 navigator 元素
const elementNavigatorButton = await page.$('.navigatorButton')
await elementNavigatorButton.tap()
await page.waitFor(300)
const currentPage = await program.currentPage()
expect(currentPage.path).toBe('pages/API/interceptor/page1')
await program.navigateBack()
})
it('addInterceptor', async () => {
......@@ -22,6 +30,14 @@ describe('interceptor', () => {
const num = (await newPage.data()).page
await program.navigateBack()
expect(num).toBe(2)
// 新增 navigator 元素
const elementNavigatorButton = await page.$('.navigatorButton')
await elementNavigatorButton.tap()
await page.waitFor(300)
const currentPage = await program.currentPage()
expect(currentPage.path).toBe('pages/API/interceptor/page2')
await program.navigateBack()
})
it('removeInterceptor', async () => {
......@@ -31,5 +47,13 @@ describe('interceptor', () => {
const num = (await newPage.data()).page
await program.navigateBack()
expect(num).toBe(1)
// 新增 navigator 元素
const elementNavigatorButton = await page.$('.navigatorButton')
await elementNavigatorButton.tap()
await page.waitFor(300)
const currentPage = await program.currentPage()
expect(currentPage.path).toBe('pages/API/interceptor/page1')
await program.navigateBack()
})
})
\ No newline at end of file
})
......@@ -3,7 +3,8 @@
<button @click="addInterceptor">添加路由拦截器</button>
<button @click="removeInterceptor">移除路由拦截器</button>
<text>点击下方按钮{{msg}}</text>
<button @click="navigateTo">跳转到测试页面</button>
<button @click="navigateTo">navigatorTo API跳转到测试页面</button>
<navigator url="./page1"><button class="navigatorButton">navigator组件跳转到测试页面</button></navigator>
</view>
</template>
......
<template>
<page-head title="发起支付"></page-head>
<page-head title="发起支付"></page-head>
<template v-if="providerList.length > 0">
<button style="margin-top: 20px;" type="primary" v-for="(item,index) in providerList" :key="index"
@click="requestPayment(item)">{{item.name}}支付</button>
</template>
<template v-if="providerList.length > 0">
<button style="margin-top: 20px;" type="primary" v-for="(item,index) in providerList" :key="index"
@click="requestPayment(item)">{{item.name}}支付</button>
</template>
</template>
<script>
export type PayItem = { id : string, name : string }
export default {
data() {
return {
btnText: "支付宝支付",
btnType: "primary",
orderInfo: "",
errorCode: 0,
errorMsg: "",
complete: false,
providerList: [] as PayItem[]
}
},
onLoad: function () {
uni.getProvider({
service: "payment",
success: (e) => {
console.log("payment success:" + JSON.stringify(e));
let array = e.provider as string[]
array.forEach((value : string) => {
switch (value) {
case 'alipay':
this.providerList.push({
name: '支付宝',
id: "alipay",
} as PayItem);
break;
case 'wxpay':
this.providerList.push({
name: '微信',
id: "wxpay",
} as PayItem);
break;
default:
break;
}
})
},
fail: (e) => {
console.log("获取支付通道失败:", e);
}
});
},
methods: {
requestPayment(e : PayItem) {
const provider = e.id
if (provider == "alipay") {
this.payAli()
} else if (provider == "wxpay") {
this.payWX()
}
},
payAli() {
uni.showLoading({
title: "请求中..."
})
uni.request({
url: 'https://demo.dcloud.net.cn/payment/alipay/?total=0.01',
method: 'GET',
timeout: 6000,
success: (res) => {
this.orderInfo = JSON.stringify(res.data);
console.log("====" + this.orderInfo)
uni.hideLoading()
uni.requestPayment({
provider: "alipay",
orderInfo: res.data as string,
fail: (res) => {
console.log(JSON.stringify(res))
this.errorCode = res.errCode
uni.showToast({
icon: 'error',
title: 'errorCode:' + this.errorCode
});
},
success: (res) => {
console.log(JSON.stringify(res))
uni.showToast({
icon: 'success',
title: '支付成功'
});
}
})
},
fail: (e) => {
console.log(e)
uni.hideLoading()
},
});
},
payWX() {
uni.showLoading({
title: "请求中..."
})
let url = 'https://demo.dcloud.net.cn/payment/wxpayv3.__UNI__uniappx/?total=1'
const res = uni.getAppBaseInfo();
if (res.packageName == 'io.dcloud.hellouniappx') {//hello uniappx
url = 'https://demo.dcloud.net.cn/payment/wxpayv3.__UNI__HelloUniAppX/?total=1'
}
uni.request({
url: url,
method: 'GET',
timeout: 6000,
header: {
"Content-Type": "application/json"
} as UTSJSONObject,
success: (res) => {
console.log(res.data)
uni.hideLoading()
uni.requestPayment({
provider: "wxpay",
orderInfo: JSON.stringify(res.data),
fail: (res) => {
console.log(JSON.stringify(res))
this.errorCode = res.errCode
uni.showToast({
duration: 5000,
icon: 'error',
title: 'errorCode:' + this.errorCode,
});
},
success: (res) => {
console.log(JSON.stringify(res))
uni.showToast({
duration: 5000,
icon: 'success',
title: '支付成功'
});
}
})
},
fail: (res) => {
uni.hideLoading()
console.log(res)
},
});
},
export type PayItem = { id : string, name : string, provider ?: UniProvider }
export default {
data() {
return {
btnText: "支付宝支付",
btnType: "primary",
orderInfo: "",
errorCode: 0,
errorMsg: "",
complete: false,
providerList: [] as PayItem[]
}
},
onLoad: function () {
uni.getProvider({
service: "payment",
success: (e) => {
console.log("payment success:" + JSON.stringify(e));
let array = e.provider as string[]
array.forEach((value : string) => {
switch (value) {
case 'alipay':
this.providerList.push({
name: '支付宝',
id: "alipay",
provider: e.providers.find((item) : boolean => {
return item.id == 'alipay'
})
} as PayItem);
break;
case 'wxpay':
this.providerList.push({
name: '微信',
id: "wxpay",
provider: e.providers.find((item) : boolean => {
return item.id == 'wxpay'
})
} as PayItem);
break;
default:
break;
}
})
},
fail: (e) => {
console.log("获取支付通道失败:", e);
}
});
},
methods: {
requestPayment(e : PayItem) {
const provider = e.id
if (provider == "alipay") {
this.payAli()
} else if (provider == "wxpay") {
//自动化测试使用
jest_pay() {
uni.requestPayment({
provider: "alipay",
orderInfo: this.orderInfo,
fail: (res : RequestPaymentFail) => {
this.errorCode = res.errCode
this.complete = true
},
success: (res : RequestPaymentSuccess) => {
console.log(JSON.stringify(res))
this.complete = true
}
} as RequestPaymentOptions)
}
}
}
if (e.provider != null && e.provider?.isAppExist==false) {
uni.showToast({
title: "微信没有安装",
icon:'error'
})
} else {
this.payWX()
}
}
},
payAli() {
uni.showLoading({
title: "请求中..."
})
uni.request({
url: 'https://demo.dcloud.net.cn/payment/alipay/?total=0.01',
method: 'GET',
timeout: 6000,
success: (res) => {
this.orderInfo = JSON.stringify(res.data);
console.log("====" + this.orderInfo)
uni.hideLoading()
uni.requestPayment({
provider: "alipay",
orderInfo: res.data as string,
fail: (res) => {
console.log(JSON.stringify(res))
this.errorCode = res.errCode
uni.showToast({
icon: 'error',
title: 'errorCode:' + this.errorCode
});
},
success: (res) => {
console.log(JSON.stringify(res))
uni.showToast({
icon: 'success',
title: '支付成功'
});
}
})
},
fail: (e) => {
console.log(e)
uni.hideLoading()
},
});
},
payWX() {
uni.showLoading({
title: "请求中..."
})
let url = 'https://demo.dcloud.net.cn/payment/wxpayv3.__UNI__uniappx/?total=0.01'
const res = uni.getAppBaseInfo();
let packageName:string | null
// #ifdef APP-ANDROID
packageName = res.packageName
// #endif
// #ifdef APP-IOS
packageName = res.bundleId
// #endif
if (packageName == 'io.dcloud.hellouniappx') {//hello uniappx
url = 'https://demo.dcloud.net.cn/payment/wxpayv3.__UNI__HelloUniAppX/?total=0.01'
}
uni.request({
url: url,
method: 'GET',
timeout: 6000,
header: {
"Content-Type": "application/json"
} as UTSJSONObject,
success: (res) => {
console.log(res.data)
uni.hideLoading()
uni.requestPayment({
provider: "wxpay",
orderInfo: JSON.stringify(res.data),
fail: (res) => {
console.log(JSON.stringify(res))
this.errorCode = res.errCode
uni.showToast({
duration: 5000,
icon: 'error',
title: 'errorCode:' + this.errorCode,
});
},
success: (res) => {
console.log(JSON.stringify(res))
uni.showToast({
duration: 5000,
icon: 'success',
title: '支付成功'
});
}
})
},
fail: (res) => {
uni.hideLoading()
console.log(res)
},
});
},
//自动化测试使用
jest_pay() {
uni.requestPayment({
provider: "alipay",
orderInfo: this.orderInfo,
fail: (res : RequestPaymentFail) => {
this.errorCode = res.errCode
this.complete = true
},
success: (res : RequestPaymentSuccess) => {
console.log(JSON.stringify(res))
this.complete = true
}
} as RequestPaymentOptions)
}
}
}
</script>
<style>
......
......@@ -129,5 +129,11 @@ describe('ExtApi-Request', () => {
await page.waitFor(2000);
res = await page.data('jest_result');
expect(res).toBe(true)
})
it('Check Post In UTS Module', async () => {
res = await page.callMethod('jest_uts_module_invoked')
await page.waitFor(2000);
res = await page.data('jest_result');
expect(res).toBe(true)
})
});
......@@ -69,6 +69,12 @@
</view>
</template>
<script>
import {
testInovkeRequest,
CommonOptions
} from '@/uni_modules/test-invoke-network-api'
class GETDataType {
data: UTSJSONObject | null = null
}
......@@ -275,7 +281,7 @@
sslVerify: false,
withCredentials: false,
firstIpv4: false,
success: (res) => {
success: (res) => {
const requestCookie = (res.data as UTSJSONObject).getJSON("data")?.getAny("requestCookie")
console.log("requestCookie ", requestCookie);
if (requestCookie instanceof Array) {
......@@ -357,6 +363,18 @@
this.jest_result = false
}
});
},
jest_uts_module_invoked(){
testInovkeRequest({
success:(res: any)=>{
console.log("success :", res);
this.jest_result = true
},
fail:(err: any)=>{
console.log("fail :", err);
this.jest_result = false
}
} as CommonOptions)
}
}
}
......
......@@ -2,8 +2,11 @@
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<image src="/static/uni.png" style="margin: 15px 100px;height:196px;width:196px;align-self:center;"></image>
<button style="margin: 15px;" @click="saveImage">将图片保存到手机相册</button>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<image class="image" src="/static/uni.png"></image>
<button class="margin-top-10" type="primary" @click="saveImage">将图片保存到手机相册</button>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
......@@ -13,22 +16,25 @@
export default {
data() {
return {
title: "saveImageToPhotosAlbum"
}
},
methods: {
saveImage() {
uni.saveImageToPhotosAlbum({
filePath: "/static/uni.png",
success() {
success: (res) => {
console.log("saveImageToPhotosAlbum success", JSON.stringify(res));
uni.showToast({
position: "center",
icon: "none",
title: "图片保存成功,请到手机相册查看"
})
},
fail(e) {
fail: (err) => {
uni.showModal({
content: "保存相册失败,errCode:" + e.errCode + ",errMsg:" + e.errMsg + ",errSubject:" + e.errSubject,
title: "保存图片到相册失败",
content: JSON.stringify(err),
showCancel: false
});
}
......@@ -39,4 +45,13 @@
</script>
<style>
.margin-top-10 {
margin-top: 10px;
}
.image {
width: 196px;
height: 196px;
align-self: center;
}
</style>
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<video class="video" :src="src" :controls="true"></video>
<button type="primary" class="margin-top-10" @click="saveVideo">将视频保存到手机相册</button>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
export default {
data() {
return {
title: 'saveVideoToPhotosAlbum',
src: ''
}
},
methods: {
saveVideo() {
uni.saveVideoToPhotosAlbum({
filePath: this.src,
success: (_) => {
console.log("saveVideoToPhotosAlbum success");
uni.showToast({
position: "center",
icon: "none",
title: "视频保存成功,请到手机相册查看"
});
},
fail: (err) => {
uni.showModal({
title: "保存视频到相册失败",
content: JSON.stringify(err),
showCancel: false
});
}
});
}
},
onReady() {
uni.showLoading({
title: '视频下载中'
});
uni.downloadFile({
url: 'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/video/swiper-vertical-video/uts.mp4',
success: (res) => {
console.log("download video success", res.tempFilePath);
this.src = res.tempFilePath;
uni.hideLoading();
}
});
}
}
</script>
<style>
.video {
align-self: center;
}
.margin-top-10 {
margin-top: 10px;
}
</style>
<template>
<view class="uni-padding-wrap">
<view class="uni-common-mt flex justify-between flex-row">
<text>theme:</text>
<text id="theme">{{ dataInfo.theme }}</text>
</view>
<view class="uni-common-mt flex justify-between flex-row">
<text>fn1 trigger num:</text>
<text id="fn1-trigger-num">{{ dataInfo.fn1TriggerNum }}</text>
</view>
<view class="uni-common-mt flex justify-between flex-row">
<text>fn2 trigger num:</text>
<text id="fn2-trigger-num">{{ dataInfo.fn2TriggerNum }}</text>
</view>
<button class="uni-common-mt" id="bind-fn1" @click="bindFn1">
bind fn1
</button>
<button class="uni-common-mt" id="remove-fn1" @click="removeFn1">
remove fn1
</button>
<button class="uni-common-mt" id="bind-fn2" @click="bindFn2">
bind fn2
</button>
<button class="uni-common-mt" id="remove-fn2" @click="removeFn2">
remove fn2
</button>
</view>
</template>
<script setup lang="uts">
type DataInfo = {
fn1TriggerNum: number
fn2TriggerNum: number
theme: string
}
const dataInfo = reactive<DataInfo>({
fn1TriggerNum: 0,
fn2TriggerNum: 0,
theme: ''
})
const fn1 = (options : OnThemeChangeOptions) => {
dataInfo.fn1TriggerNum++
console.log('fn1 triggered options: ', options)
dataInfo.theme = options.theme
}
const fn2 = (options : OnThemeChangeOptions) => {
dataInfo.fn2TriggerNum++
console.log('fn2 triggered options: ', options)
dataInfo.theme = options.theme
}
const bindFn1 = () => {
uni.onOSThemeChange(fn1)
}
const removeFn1 = () => {
uni.offOSThemeChange(fn1)
}
const bindFn2 = () => {
uni.onOSThemeChange(fn2)
}
const removeFn2 = () => {
uni.offOSThemeChange(fn2)
}
onReady(() => {
bindFn1()
bindFn2()
})
</script>
<style>
.flex {
display: flex;
}
.flex-row {
flex-direction: row;
}
.justify-between {
justify-content: space-between;
}
</style>
......@@ -17,6 +17,7 @@ describe('unicloud-database', () => {
await page.callMethod('dbGetWithCommand')
await page.callMethod('dbUpdate')
await page.callMethod('dbRemove')
await page.callMethod('dbMultiSend')
const {
addId,
......@@ -26,6 +27,7 @@ describe('unicloud-database', () => {
getData,
getWithCommandData,
removeDeleted,
multiSendSuccessCount,
} = await page.data()
expect(addId !== '').toBe(true)
......@@ -35,6 +37,7 @@ describe('unicloud-database', () => {
expect(getWithCommandData.length).toBe(1)
expect(updateUpdated).toBe(3)
expect(removeDeleted).toBe(3)
expect(multiSendSuccessCount).toBe(2)
})
......
......@@ -14,6 +14,7 @@
<button type="primary" @click="dbRemove">删除数据</button>
<button type="primary" @click="dbLookupInit">初始化联表查询数据</button>
<button type="primary" @click="dbLookup">联表查询</button>
<button type="primary" @click="dbMultiSend">合并查询查询</button>
</view>
</view>
</view>
......@@ -35,6 +36,7 @@
getWithCommandData: [] as Array<UTSJSONObject>,
removeDeleted: 0,
lookupData: [] as Array<UTSJSONObject>,
multiSendSuccessCount: 0,
isUniTest: false
}
},
......@@ -278,6 +280,39 @@
const error = err as UniCloudError
this.notify(error.errMsg, '错误')
})
},
dbMultiSend() {
const db = uniCloud.databaseForJQL()
const temp1 = db.collection('type')
.where(
'tag == "default-tag"'
).getTemp()
const temp2 = db.collection('type')
.where(
'tag == "default-tag"'
).getTemp()
db.multiSend(temp1, temp2)
.then<void>(res => {
uni.hideLoading()
let successCount = 0
for (let i = 0; i < res.dataList.length; i++) {
const item = res.dataList[i]
if(item.errCode == 0) {
console.log(`第${i}个请求查询到${item.data!.length}条数据`)
successCount++
} else {
console.error(`第${i}个请求查询失败,错误信息:${item.data!.length}`)
}
}
this.multiSendSuccessCount = successCount
this.notify(`合并查询成功,成功查询的语句条数为:${successCount}`, '提示')
})
.catch<void>((err : any | null) => {
uni.hideLoading()
const error = err as UniCloudError
console.error(err)
this.notify(error.errMsg, '错误')
})
}
}
}
......
......@@ -34,7 +34,14 @@ describe('ExtApi-UploadFile', () => {
await page.waitFor(2000);
res = await page.data('jest_result');
expect(res).toBe(true)
});
});
it('Check Upload File In UTS Module', async () => {
res = await page.callMethod('jest_uts_module_invoked')
await page.waitFor(2000);
res = await page.data('jest_result');
expect(res).toBe(true)
})
let shouldTestCookie = false
if (process.env.uniTestPlatformInfo.startsWith('android') && !process.env.UNI_AUTOMATOR_APP_WEBVIEW) {
......
......@@ -15,7 +15,12 @@
</scroll-view>
<!-- #endif -->
</template>
<script>
<script>
import {
testInovkeUploadFile,
CommonOptions
} from '@/uni_modules/test-invoke-network-api'
export default {
data() {
return {
......@@ -171,6 +176,18 @@
this.jest_result = false;
},
})
},
jest_uts_module_invoked(){
testInovkeUploadFile({
success:(res: any)=>{
console.log("success :", res);
this.jest_result = true
},
fail:(err: any)=>{
console.log("fail :", err);
this.jest_result = false
}
} as CommonOptions)
}
}
}
......
......@@ -127,7 +127,7 @@
}
.fixed {
/* #ifdef H5*/
/* #ifdef WEB*/
top: calc(var(--window-top) + 25px);
/* #endif */
}
......
......@@ -10,7 +10,7 @@
<text class="reserve-text">转变前位置</text>
</view>
<view class="base reserve">
<text class="reserve-text">translate(-50%, 50%)</text>
<text class="reserve-text">translate(-50%,50%)</text>
<text class="reserve-text">转变前位置</text>
</view>
</view>
......
<template>
<view>
<page-head title="cover-view用于覆盖map、video等原生组件"></page-head>
<view class="cover-content">
<map :latitude="latitude" :longitude="longitude"></map>
<cover-view class="cover-view">简单的cover-view</cover-view>
<cover-image class="cover-image" src="/static/uni.png"></cover-image>
</view>
</view>
</template>
<script lang="uts">
export default {
data() {
return {
showMap: false,
latitude: 39.909,
longitude: 116.39742
};
},
onLoad() {
this.showMap = true
}
}
</script>
<style>
map {
width: 100%;
height: 600px;
}
.cover-content {
position: relative;
}
.cover-view {
position: absolute;
left: 5px;
top: 5px;
width: 375rpx;
text-align: center;
background-color: #DDDDDD;
}
.cover-image {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
width: 96px;
height: 96px;
}
</style>
@font-face {
font-family: 'iconfont';
src: url('data:font/truetype;charset=utf-8;base64,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AAsAJgFuAAoAQwByAGUAYQB0AGUAZAAgAGIAeQAgAGkAYwBvAG4AZgBvAG4AdAAKAAAKQ3JlYXRlZCBieSBpY29uZm9udAoAAGkAYwBvAG4AZgBvAG4AdAAAaWNvbmZvbnQAAFIAZQBnAHUAbABhAHIAAFJlZ3VsYXIAAGkAYwBvAG4AZgBvAG4AdAAAaWNvbmZvbnQAAGkAYwBvAG4AZgBvAG4AdAAAaWNvbmZvbnQAAFYAZQByAHMAaQBvAG4AIAAxAC4AMAAAVmVyc2lvbiAxLjAAAGkAYwBvAG4AZgBvAG4AdAAAaWNvbmZvbnQAAEcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAAcwB2AGcAMgB0AHQAZgAgAGYAcgBvAG0AIABGAG8AbgB0AGUAbABsAG8AIABwAHIAbwBqAGUAYwB0AC4AAEdlbmVyYXRlZCBieSBzdmcydHRmIGZyb20gRm9udGVsbG8gcHJvamVjdC4AAGgAdAB0AHAAOgAvAC8AZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AAGh0dHA6Ly9mb250ZWxsby5jb20AAAIAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOwAAAAEAAgECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BHwEgASEBIgEjASQBJQEmAScBKAEpASoBKwEsAS0BLgEvATABMQEyATMBNAE1ATYBNwE4ATkEcmVkbwlzZWxlY3RhbGwHcHJldmlldwR1bmRvBGRhdGUHY2xlYXJ1cBU3MjNiaWFuamlxaV9kdWFuaG91anUWNzIyYmlhbmppcWlfZHVhbnFpYW5qdQotY2hlY2tsaXN0DWRpcmVjdGlvbi1sdHINZGlyZWN0aW9uLXJ0bAtmb250Ymdjb2xvcg1jbGVhcmVkZm9ybWF0BGZvbnQHb3V0ZGVudAhmb250c2l6ZQp0ZXh0X2NvbG9yD2Zvcm1hdC1oZWFkZXItMg9mb3JtYXQtaGVhZGVyLTMLbGluZS1oZWlnaHQPZm9ybWF0LWhlYWRlci0xD2Zvcm1hdC1oZWFkZXItNA9mb3JtYXQtaGVhZGVyLTUPZm9ybWF0LWhlYWRlci02EUNoYXJhY3Rlci1TcGFjaW5nBmluZGVudAZiYW9jdW4IcXVhbnBpbmcFZnV6aGkHc2hhbmNodQxiaWFuamlzZWt1YWkJZmVuZ2V4aWFuB2RpYW56YW4MY2hhcnVsaWFuamllC2NoYXJ1dHVwaWFuCnd1eHVwYWlsaWUManV6aG9uZ2R1aXFpB3lpbnlvbmcLeW91eHVwYWlsaWUIeW91ZHVpcWkJeml0aWRhaW1hCHhpYW9saWFuCXppdGlqaWFjdQ96aXRpc2hhbmNodXhpYW4Neml0aXNoYW5nYmlhbwp6aXRpYmlhb3RpDnppdGl4aWFodWF4aWFuCXppdGl4aWV0aQl6aXRpeWFuc2UIenVvZHVpcWkJeml0aXl1bGFuC3ppdGl4aWFiaWFvC3p1b3lvdWR1aXFpB2R1aWdvdXgGZ3VhbmJpDnNoZW5neWluX3NoaXRpAAAAAAAB//8AAgABAAAADAAAABYAAAACAAEAAwA6AAEABAAAAAIAAAAAAAAAAQAAAADVpCcIAAAAANhk6GIAAAAA2GToYg==') format('truetype');
font-weight: normal;
font-style: normal;
font-display: swap;
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-redo:before {
content: "\e627";
}
.icon-undo:before {
content: "\e633";
}
.icon-indent:before {
content: "\eb28";
}
.icon-outdent:before {
content: "\e6e8";
}
.icon-fontsize:before {
content: "\e6fd";
}
.icon-format-header-1:before {
content: "\e860";
}
.icon-format-header-4:before {
content: "\e863";
}
.icon-format-header-5:before {
content: "\e864";
}
.icon-format-header-6:before {
content: "\e865";
}
.icon-clearup:before {
content: "\e64d";
}
.icon-preview:before {
content: "\e631";
}
.icon-date:before {
content: "\e63e";
}
.icon-fontbgcolor:before {
content: "\e678";
}
.icon-clearedformat:before {
content: "\e67e";
}
.icon-font:before {
content: "\e684";
}
.icon-723bianjiqi_duanhouju:before {
content: "\e65f";
}
.icon-722bianjiqi_duanqianju:before {
content: "\e660";
}
.icon-text_color:before {
content: "\e72c";
}
.icon-format-header-2:before {
content: "\e75c";
}
.icon-format-header-3:before {
content: "\e75d";
}
.icon--checklist:before {
content: "\e664";
}
.icon-baocun:before {
content: "\ec09";
}
.icon-line-height:before {
content: "\e7f8";
}
.icon-quanping:before {
content: "\ec13";
}
.icon-direction-rtl:before {
content: "\e66e";
}
.icon-direction-ltr:before {
content: "\e66d";
}
.icon-selectall:before {
content: "\e62b";
}
.icon-fuzhi:before {
content: "\ec7a";
}
.icon-shanchu:before {
content: "\ec7b";
}
.icon-bianjisekuai:before {
content: "\ec7c";
}
.icon-fengexian:before {
content: "\ec7f";
}
.icon-dianzan:before {
content: "\ec80";
}
.icon-charulianjie:before {
content: "\ec81";
}
.icon-charutupian:before {
content: "\ec82";
}
.icon-wuxupailie:before {
content: "\ec83";
}
.icon-juzhongduiqi:before {
content: "\ec84";
}
.icon-yinyong:before {
content: "\ec85";
}
.icon-youxupailie:before {
content: "\ec86";
}
.icon-youduiqi:before {
content: "\ec87";
}
.icon-zitidaima:before {
content: "\ec88";
}
.icon-xiaolian:before {
content: "\ec89";
}
.icon-zitijiacu:before {
content: "\ec8a";
}
.icon-zitishanchuxian:before {
content: "\ec8b";
}
.icon-zitishangbiao:before {
content: "\ec8c";
}
.icon-zitibiaoti:before {
content: "\ec8d";
}
.icon-zitixiahuaxian:before {
content: "\ec8e";
}
.icon-zitixieti:before {
content: "\ec8f";
}
.icon-zitiyanse:before {
content: "\ec90";
}
.icon-zuoduiqi:before {
content: "\ec91";
}
.icon-zitiyulan:before {
content: "\ec92";
}
.icon-zitixiabiao:before {
content: "\ec93";
}
.icon-zuoyouduiqi:before {
content: "\ec94";
}
.icon-duigoux:before {
content: "\ec9e";
}
.icon-guanbi:before {
content: "\eca0";
}
.icon-shengyin_shiti:before {
content: "\eca5";
}
.icon-Character-Spacing:before {
content: "\e964";
}
<template>
<view class="container">
<view class="page-body">
<view class='wrapper'>
<view class='toolbar' @tap="format">
<view :class="formats.bold ? 'ql-active' : ''" class="iconfont icon-zitijiacu"
data-name="bold"></view>
<view :class="formats.italic ? 'ql-active' : ''" class="iconfont icon-zitixieti"
data-name="italic"></view>
<view :class="formats.underline ? 'ql-active' : ''" class="iconfont icon-zitixiahuaxian"
data-name="underline"></view>
<view :class="formats.strike ? 'ql-active' : ''" class="iconfont icon-zitishanchuxian"
data-name="strike"></view>
<view :class="formats.align === 'left' ? 'ql-active' : ''" class="iconfont icon-zuoduiqi"
data-name="align" data-value="left"></view>
<view :class="formats.align === 'center' ? 'ql-active' : ''" class="iconfont icon-juzhongduiqi"
data-name="align" data-value="center"></view>
<view :class="formats.align === 'right' ? 'ql-active' : ''" class="iconfont icon-youduiqi"
data-name="align" data-value="right"></view>
<view :class="formats.align === 'justify' ? 'ql-active' : ''" class="iconfont icon-zuoyouduiqi"
data-name="align" data-value="justify"></view>
<view :class="formats.lineHeight ? 'ql-active' : ''" class="iconfont icon-line-height"
data-name="lineHeight" data-value="2"></view>
<view :class="formats.letterSpacing ? 'ql-active' : ''" class="iconfont icon-Character-Spacing"
data-name="letterSpacing" data-value="2em"></view>
<view :class="formats.marginTop ? 'ql-active' : ''" class="iconfont icon-722bianjiqi_duanqianju"
data-name="marginTop" data-value="20px"></view>
<view :class="formats.marginBottom ? 'ql-active' : ''" class="iconfont icon-723bianjiqi_duanhouju"
data-name="marginBottom" data-value="20px"></view>
<view class="iconfont icon-clearedformat" @tap="removeFormat"></view>
<view :class="formats.fontFamily ? 'ql-active' : ''" class="iconfont icon-font"
data-name="fontFamily" data-value="Pacifico"></view>
<view :class="formats.fontSize === '24px' ? 'ql-active' : ''" class="iconfont icon-fontsize"
data-name="fontSize" data-value="24px"></view>
<view :class="formats.color === '#0000ff' ? 'ql-active' : ''" class="iconfont icon-text_color"
data-name="color" data-value="#0000ff"></view>
<view :class="formats.backgroundColor === '#00ff00' ? 'ql-active' : ''"
class="iconfont icon-fontbgcolor" data-name="backgroundColor" data-value="#00ff00"></view>
<view class="iconfont icon-date" @tap="insertDate"></view>
<view class="iconfont icon--checklist" data-name="list" data-value="check"></view>
<view :class="formats.list === 'ordered' ? 'ql-active' : ''" class="iconfont icon-youxupailie"
data-name="list" data-value="ordered"></view>
<view :class="formats.list === 'bullet' ? 'ql-active' : ''" class="iconfont icon-wuxupailie"
data-name="list" data-value="bullet"></view>
<view class="iconfont icon-undo" @tap="undo"></view>
<view class="iconfont icon-redo" @tap="redo"></view>
<view class="iconfont icon-outdent" data-name="indent" data-value="-1"></view>
<view class="iconfont icon-indent" data-name="indent" data-value="+1"></view>
<view class="iconfont icon-fengexian" @tap="insertDivider"></view>
<view class="iconfont icon-charutupian" @tap="insertImage"></view>
<view :class="formats.header === 1 ? 'ql-active' : ''" class="iconfont icon-format-header-1"
data-name="header" :data-value="1"></view>
<view :class="formats.script === 'sub' ? 'ql-active' : ''" class="iconfont icon-zitixiabiao"
data-name="script" data-value="sub"></view>
<view :class="formats.script === 'super' ? 'ql-active' : ''" class="iconfont icon-zitishangbiao"
data-name="script" data-value="super"></view>
<view class="iconfont icon-shanchu" @tap="clear"></view>
<view :class="formats.direction === 'rtl' ? 'ql-active' : ''" class="iconfont icon-direction-rtl"
data-name="direction" data-value="rtl"></view>
</view>
<view class="editor-wrapper">
<editor id="editor" class="ql-container" placeholder="开始输入..." show-img-size show-img-toolbar
show-img-resize @statuschange="onStatusChange" :read-only="readOnly" @ready="onEditorReady">
</editor>
</view>
<view>
<button @tap="getCon">打印文本内容</button>
</view>
</view>
</view>
</view>
</template>
<script lang="uts">
type Context = {
id?: string;
pageId?: number;
}
export default {
data() {
return {
readOnly: false,
formats: {},
editorCtx:{} as Context
}
},
onLoad() {
uni.loadFontFace({
family: 'Pacifico',
source: 'url("/static/font/Pacifico-Regular.ttf")',
success() {
console.log('success load font')
},
fail() {
console.log('fail load font load')
}
})
},
methods: {
readOnlyChange() {
this.readOnly = !this.readOnly
},
onEditorReady() {
uni.createSelectorQuery().select('#editor').context((res) => {
this.editorCtx = res.context
}).exec()
},
getCon() {
this.editorCtx.getContents({
success: (res) => {
console.log('文本详情:', res)
},
fail: (err) => {
console.log(err)
}
})
},
undo() {
this.editorCtx.undo()
},
redo() {
this.editorCtx.redo()
},
format(e) {
let {
name,
value
} = e.target.dataset
if (!name) return
// console.log('format', name, value)
this.editorCtx.format(name, value)
},
onStatusChange(e) {
const formats = e.detail
this.formats = formats
},
insertDivider() {
this.editorCtx.insertDivider({
success: function() {
console.log('insert divider success')
}
})
},
clear() {
uni.showModal({
title: '清空编辑器',
content: '确定清空编辑器全部内容?',
success: res => {
if (res.confirm) {
this.editorCtx.clear({
success: function(res) {
console.log("clear success")
}
})
}
}
})
},
removeFormat() {
this.editorCtx.removeFormat()
},
insertDate() {
const date = new Date()
const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
this.editorCtx.insertText({
text: formatDate
})
},
insertImage() {
uni.chooseImage({
count: 1,
success: (res) => {
this.editorCtx.insertImage({
src: res.tempFilePaths[0],
alt: '图像',
success: function() {
console.log('insert image success')
}
})
}
})
}
}
}
</script>
<style>
@import "./editor-icon.css";
.page-body {
height: calc(100vh - var(--window-top) - var(--status-bar-height));
}
.wrapper {
height: 100%;
}
.editor-wrapper {
height: calc(100vh - var(--window-top) - var(--status-bar-height) - 80px - 46px);
background: #fff;
}
.iconfont {
display: inline-block;
padding: 8px 8px;
width: 30px;
height: 30px;
cursor: pointer;
font-size: 20px;
}
.toolbar {
box-sizing: border-box;
border-bottom: 0;
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
flex-direction: row;
flex-wrap: wrap;
height: 110px;
}
.ql-container {
box-sizing: border-box;
padding: 12px 15px;
width: 100%;
min-height: 30vh;
height: 100%;
font-size: 16px;
line-height: 1.5;
}
.ql-active {
color: #06c;
}
</style>
......@@ -5,12 +5,14 @@ const DEFAULT_GENDER = '0'
const DEFAULT_LOVES = ['0']
const DEFAULT_AGE = 18
const DEFAULT_SWITCH = true
const DEFAULT_COMMENT = ''
const CHANGE_NICK_NAME = 'hello'
const CHANGE_GENDER = '1'
const CHANGE_LOVES = ['0', '1']
const CHANGE_AGE = 50
const CHANGE_SWITCH = false
const CHANGE_COMMENT = '备注'
describe('form', () => {
let page
......@@ -35,6 +37,7 @@ describe('form', () => {
expect(formData['loves'][1]).toBe(CHANGE_LOVES[1])
expect(formData['age']).toBe(CHANGE_AGE)
expect(formData['switch']).toBe(CHANGE_SWITCH)
expect(formData['comment']).toBe(CHANGE_COMMENT)
})
it('reset', async () => {
await changeData(page)
......@@ -56,6 +59,7 @@ describe('form', () => {
expect(formData['loves'][0]).toBe(DEFAULT_LOVES[0])
expect(formData['age']).toBe(DEFAULT_AGE)
expect(formData['switch']).toBe(DEFAULT_SWITCH)
expect(formData['comment']).toBe(DEFAULT_COMMENT)
})
})
......@@ -65,7 +69,8 @@ async function changeData(page) {
gender: CHANGE_GENDER,
loves: CHANGE_LOVES,
age: CHANGE_AGE,
switch: CHANGE_SWITCH
switch: CHANGE_SWITCH,
comment:CHANGE_COMMENT
})
await page.waitFor(100)
}
......@@ -40,6 +40,11 @@
<switch name="switch" :checked="switch" />
</view>
</view>
<view class="uni-form-item">
<view class="title">备注</view>
<textarea name="comment" :value="comment" placeholder="请输入备注" style="background: #FFF;"/>
<!-- <textarea class="uni-input" name="comment" :value="comment" placeholder="这个class的写法,导致iOS和Android产生了高度差异"/> -->
</view>
<view class="uni-btn-v flex-row">
<button class="btn btn-submit" form-type="submit" type="primary">Submit</button>
<button class="btn btn-reset" type="default" form-type="reset">Reset</button>
......@@ -62,6 +67,7 @@
age: 18,
loves: ['0'],
switch: true,
comment:'',
formData: {} as UTSJSONObject
}
},
......
......@@ -172,6 +172,26 @@ describe('component-native-input', () => {
})
})
it("keyboard height changed after page back", async () => {
await program.navigateTo("/pages/API/navigator/new-page/new-page-3")
await page.waitFor(2000);
await program.navigateBack()
await page.waitFor(1000);
await page.setData({
focusedForKeyboardHeightChangeTest: true
})
await page.waitFor(1000);
const keyboardHeight = await page.data('keyboardHeight');
console.log("keyboardHeight :", keyboardHeight);
expect(keyboardHeight).toBeGreaterThan(25)
//reset
await page.setData({
focusedForKeyboardHeightChangeTest: false,
keyboardHeight:0
})
})
it("afterAllTestScreenshot", async () => {
const image = await program.screenshot({
fullPage: true
......
......@@ -213,7 +213,7 @@
v-if="keyboardHeightChangeEventDetail">{{keyboardHeightChangeEventDetail}}</text>
</view>
<view class="input-wrapper">
<input class="uni-input" @keyboardheightchange="onKeyborardHeightChange" />
<input class="uni-input" @keyboardheightchange="onKeyborardHeightChange" :focus="focusedForKeyboardHeightChangeTest"/>
</view>
</view>
......@@ -270,6 +270,8 @@
inputPasswordValue: "cipher",
inputFocusKeyBoardChangeValue: true,
holdKeyboard: false,
keyboardHeight: 0,
focusedForKeyboardHeightChangeTest: false,
}
},
methods: {
......@@ -327,7 +329,8 @@
},
onKeyborardHeightChange: function (event : UniInputKeyboardHeightChangeEvent) {
console.log("键盘高度发生变化", JSON.stringify(event.detail));
this.keyboardHeightChangeEventDetail = JSON.stringify(event.detail);
this.keyboardHeightChangeEventDetail = JSON.stringify(event.detail);
this.keyboardHeight = event.detail.height;
},
test_check_input_value() : number {
return this.onMaxLengthInputValue.length
......
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-common-mt">
<view class="uni-form-item uni-column">
<view class="title">表单组件在label内</view>
<checkbox-group class="uni-list" @change="checkboxChange">
<label class="uni-list-cell uni-list-cell-pd" v-for="item in checkboxItems" :key="item.name">
<view>
<checkbox :value="item.name" :checked="item.checked"></checkbox>
</view>
<view>{{item.value}}</view>
</label>
</checkbox-group>
</view>
<view class="uni-form-item uni-column">
<view class="title">label用for标识表单组件</view>
<radio-group class="uni-list" @change="radioChange">
<view class="uni-list-cell uni-list-cell-pd" v-for="(item,index) in radioItems" :key="index">
<view>
<radio :id="item.name" :value="item.name" :checked="item.checked"></radio>
</view>
<label class="label-2-text" :for="item.name">
<text>{{item.value}}</text>
</label>
</view>
</radio-group>
</view>
<view class="uni-form-item uni-column">
<view class="title">label内有多个时选中第一个</view>
<checkbox-group class="uni-list" @change="checkboxChange">
<label class="label-3">
<view class="uni-list-cell uni-list-cell-pd">
<checkbox>选项一</checkbox>
</view>
<view class="uni-list-cell uni-list-cell-pd">
<checkbox>选项二</checkbox>
</view>
<view class="uni-link uni-center" style="margin:20rpx 0;">点击该label下的文字默认选中第一个checkbox</view>
</label>
</checkbox-group>
</view>
</view>
</view>
</template>
<script lang="uts">
export default {
data() {
return {
title: 'label',
checkboxItems: [{
name: 'USA',
value: '美国'
},
{
name: 'CHN',
value: '中国',
checked: 'true'
}
],
radioItems: [{
name: 'USA',
value: '美国'
},
{
name: 'CHN',
value: '中国',
checked: 'true'
}
],
hidden: false
}
},
methods: {
checkboxChange: function (e) {
var checked = e.detail.value
console.log(checked)
},
radioChange: function (e) {
var checked = e.detail.value
console.log(checked)
}
}
}
</script>
<style>
.uni-list-cell {
justify-content: flex-start
}
.uni-list .label-3 {
padding: 0;
}
.label-2-text {
flex: 1;
}
.uni-form-item{
display:flex;
width:100%;
padding:10rpx 0;
}
.uni-form-item .title{
padding:10rpx 25rpx;
}
radio-group{
padding: 0 20rpx;
}
checkbox-group label{
margin: 0 20rpx;
}
</style>
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-common-mt">
<view>
<map :latitude="latitude" :longitude="longitude" :markers="covers">
</map>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'map',
latitude: 39.909,
longitude: 116.39742,
covers: [{
id: 1,
latitude: 39.9085,
longitude: 116.39747,
iconPath: '../../../static/location.png',
}, {
id: 2,
latitude: 39.90,
longitude: 116.39,
iconPath: '../../../static/location.png',
}]
}
}
}
</script>
<style>
map {
width: 100%;
height: 600rpx;
}
</style>
<template>
<view class="page-body">
<page-head title="movable-view,可拖动视图"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title uni-common-mt">
示例 1
<text>\nmovable-view 区域小于 movable-area</text>
</view>
<movable-area>
<movable-view :x="x" :y="y" direction="all" @change="onChange">text</movable-view>
</movable-area>
<view @tap="tap" class="uni-link uni-center uni-common-mt">
点击这里移动至 (30px, 30px)
</view>
<view class="uni-title uni-common-mt">
示例 2
<text>\nmovable-view区域大于movable-area</text>
</view>
<movable-area>
<movable-view class="max" direction="all">text</movable-view>
</movable-area>
<view class="uni-title uni-common-mt">
示例 3
<text>\n只可以横向移动</text>
</view>
<movable-area>
<movable-view direction="horizontal">text</movable-view>
</movable-area>
<view class="uni-title uni-common-mt">
示例 4
<text>\n只可以纵向移动</text>
</view>
<movable-area>
<movable-view direction="vertical">text</movable-view>
</movable-area>
<view class="uni-title uni-common-mt">
示例 5
<text>\n可超出边界</text>
</view>
<movable-area>
<movable-view direction="all" out-of-bounds>text</movable-view>
</movable-area>
<view class="uni-title uni-common-mt">
示例 6
<text>\n带有惯性</text>
</view>
<movable-area>
<movable-view direction="all" inertia>text</movable-view>
</movable-area>
<view class="uni-title uni-common-mt">
示例 7
<text>\n可放缩</text>
</view>
<movable-area scale-area>
<movable-view direction="all" @scale="onScale" scale scale-min="0.5" scale-max="4" :scale-value="scale">text</movable-view>
</movable-area>
<view @tap="tap2" class="uni-link uni-center uni-common-mt" style="padding-bottom:80rpx;">
点击这里放大3倍
</view>
</view>
</view>
</template>
<script lang="uts">
export default {
data() {
return {
x: 0,
y: 0,
scale: 2,
old: {
x: 0,
y: 0,
scale: 2
}
}
},
methods: {
tap: function(e) {
// 解决view层不同步的问题
this.x = this.old.x
this.y = this.old.y
this.$nextTick(function() {
this.x = 30
this.y = 30
})
},
tap2() {
// 解决view层不同步的问题
this.scale = this.old.scale
this.scale = this.old.scale
this.$nextTick(function() {
this.scale = 3
})
},
onChange: function(e) {
this.old.x = e.detail.x
this.old.y = e.detail.y
},
onScale: function(e) {
this.old.scale = e.detail.scale
}
}
}
</script>
<style>
movable-view {
display: flex;
align-items: center;
justify-content: center;
height: 150rpx;
width: 150rpx;
background-color: #007AFF;
color: #fff;
}
movable-area {
height: 300rpx;
width: 100%;
background-color: #D8D8D8;
overflow: hidden;
}
.max {
width:500rpx;
height: 500rpx;
}
</style>
......@@ -15,7 +15,7 @@ describe('navigator', () => {
page = await program.reLaunch(PAGE_PATH)
await page.waitFor(500)
const btnNavigate = await page.$('.navigate')
const btnNavigate = await page.$('#navigate')
await btnNavigate.tap()
await page.waitFor(300)
......@@ -26,7 +26,7 @@ describe('navigator', () => {
page = await program.reLaunch(PAGE_PATH)
await page.waitFor(500)
const btnRedirect = await page.$('.redirect')
const btnRedirect = await page.$('#redirect')
await btnRedirect.tap()
await page.waitFor(300)
......
<template>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<navigator class="navigator navigate" url="navigate?title=navigate">
<navigator id="navigate" class="navigator" url="navigate?title=navigate">
<button type="default">跳转到新页面</button>
</navigator>
<navigator class="navigator redirect" url="redirect?title=redirect" open-type="redirect">
<button type="default">在当前页打开</button>
<navigator id="redirect" class="navigator" url="redirect?title=redirect" open-type="redirect">
<button type="default">在当前页打开redirect</button>
</navigator>
<navigator id="switchTab" class="navigator" url="/pages/tabBar/template" open-type="switchTab">
<button type="default">切换到模板选项卡switchTab</button>
</navigator>
<navigator id="reLaunch" class="navigator" url="/pages/tabBar/component" open-type="reLaunch">
<button type="default">关闭所有页面回首页reLaunch</button>
</navigator>
<navigator id="reLaunch" class="navigator" open-type="navigateBack">
<button type="default">返回上一页navigateBack</button>
</navigator>
<!-- <navigator id="reLaunch" class="navigator" open-type="exit">
<button type="default">退出应用(仅Android和小程序生效)</button>
</navigator> -->
<navigator id="navigateToErrorPage" class="navigator" url="/pages/error-page/error-page" >
<button type="default"> 打开不存在的页面 </button>
</navigator>
<navigator id="navigateToErrorPage" class="navigator">
<button type="default"> 未指定URL的跳转 </button>
</navigator>
<navigator style="flex-direction: row;justify-content: space-between;">
<text>两端对齐样式测试</text>
......
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-title uni-common-pl">普通选择器</view>
<view class="uni-list">
<view class="uni-list-cell">
<view class="uni-list-cell-left">
当前选择
</view>
<view class="uni-list-cell-db">
<picker @change="bindPickerChange" :value="index" :range="array" range-key="name">
<view class="uni-input">{{array[index].name}}</view>
</picker>
</view>
</view>
</view>
<view class="uni-title uni-common-pl">多列选择器</view>
<view class="uni-list">
<view class="uni-list-cell">
<view class="uni-list-cell-left">
当前选择
</view>
<view class="uni-list-cell-db">
<picker mode="multiSelector" @columnchange="bindMultiPickerColumnChange" :value="multiIndex" :range="multiArray">
<view class="uni-input">{{multiArray[0][multiIndex[0]]}},{{multiArray[1][multiIndex[1]]}},{{multiArray[2][multiIndex[2]]}}</view>
</picker>
</view>
</view>
</view>
<view class="uni-title uni-common-pl">时间选择器</view>
<view class="uni-list">
<view class="uni-list-cell">
<view class="uni-list-cell-left">
当前选择
</view>
<view class="uni-list-cell-db">
<picker mode="time" :value="time" start="09:01" end="21:01" @change="bindTimeChange">
<view class="uni-input">{{time}}</view>
</picker>
</view>
</view>
</view>
<view class="uni-picker-tips">
注:选择 09:01 ~ 21:01 之间的时间, 不在区间内不能选中
</view>
<view class="uni-title uni-common-pl">日期选择器</view>
<view class="uni-list">
<view class="uni-list-cell">
<view class="uni-list-cell-left">
当前选择
</view>
<view class="uni-list-cell-db">
<picker mode="date" :value="date" :start="startDate" :end="endDate" @change="bindDateChange">
<view class="uni-input">{{date}}</view>
</picker>
</view>
</view>
</view>
<view class="uni-picker-tips">
注:选择当前时间 ±10 年之间的时间, 不在区间内不能选中
</view>
</view>
</template>
<script lang="uts">
function getDate(type?:string):string {
const date = new Date();
let year:string | number = date.getFullYear();
let month:string | number = date.getMonth() + 1;
let day:string | number = date.getDate();
if (type === 'start') {
year = year - 10;
} else if (type === 'end') {
year = year + 10;
}
month = month > 9 ? month : '0' + month;;
day = day > 9 ? day : '0' + day;
return `${year}-${month}-${day}`;
}
export default {
data() {
return {
title: 'picker',
array: [{name:'中国'},{name: '美国'}, {name:'巴西'}, {name:'日本'}],
index: 0,
multiArray: [
['亚洲', '欧洲'],
['中国', '日本'],
['北京', '上海', '广州']
],
multiIndex: [0, 0, 0],
date:getDate(),
startDate:getDate('start'),
endDate:getDate('end'),
time: '12:01'
}
},
methods: {
bindPickerChange: function(e) {
console.log('picker发送选择改变,携带值为:' + e.detail.value)
this.index = e.detail.value
},
bindMultiPickerColumnChange: function(e) {
console.log('修改的列为:' + e.detail.column + ',值为:' + e.detail.value)
this.multiIndex[e.detail.column] = e.detail.value
switch (e.detail.column) {
case 0: //拖动第1列
switch (this.multiIndex[0]) {
case 0:
this.multiArray[1] = ['中国', '日本']
this.multiArray[2] = ['北京', '上海', '广州']
break
case 1:
this.multiArray[1] = ['英国', '法国']
this.multiArray[2] = ['伦敦', '曼彻斯特']
break
}
this.multiIndex.splice(1, 1, 0)
this.multiIndex.splice(2, 1, 0)
break
case 1: //拖动第2列
switch (this.multiIndex[0]) { //判断第一列是什么
case 0:
switch (this.multiIndex[1]) {
case 0:
this.multiArray[2] = ['北京', '上海', '广州']
break
case 1:
this.multiArray[2] = ['东京','北海道']
break
}
break
case 1:
switch (this.multiIndex[1]) {
case 0:
this.multiArray[2] = ['伦敦', '曼彻斯特']
break
case 1:
this.multiArray[2] = ['巴黎', '马赛']
break
}
break
}
this.multiIndex.splice(2, 1, 0)
break
}
this.$forceUpdate()
},
bindDateChange: function(e) {
this.date = e.detail.value
},
bindTimeChange: function(e) {
this.time = e.detail.value
}
}
}
</script>
<style>
.uni-picker-tips {
font-size: 12px;
color: #666;
margin-bottom: 15px;
padding: 0 15px;
}
</style>
// uni-app自动化测试教程: uni-app自动化测试教程: https://uniapp.dcloud.net.cn/worktile/auto/hbuilderx-extension/
describe('component-native-scroll-view-refresher', () => {
if (process.env.uniTestPlatformInfo.startsWith('android') && !process.env.UNI_AUTOMATOR_APP_WEBVIEW) {
let page;
beforeAll(async () => {
page = await program.reLaunch('/pages/component/scroll-view/scroll-view-refresher');
await page.waitFor(300);
});
describe('component-native-scroll-view-refresher', () => {
if (!process.env.uniTestPlatformInfo.startsWith('android') && !process.env.uniTestPlatformInfo.startsWith('web') || process.env.UNI_AUTOMATOR_APP_WEBVIEW) {
it('other platform', () => {
expect(1).toBe(1)
})
return
}
let page;
beforeAll(async () => {
page = await program.reLaunch('/pages/component/scroll-view/scroll-view-refresher');
await page.waitFor(300);
});
it('scroll-view-refresher-screenshot', async () => {
//禁止滚动条
await page.setData({
showScrollbar: false
})
await page.waitFor(300);
const image = await program.screenshot({fullPage: true});
expect(image).toSaveImageSnapshot();
it('scroll-view-refresher-screenshot', async () => {
//禁止滚动条
await page.setData({
showScrollbar: false
})
await page.waitFor(300);
const image = await program.screenshot({fullPage: true});
expect(image).toSaveImageSnapshot();
})
it('check_refresher', async () => {
await page.setData({
refresherTriggered: true
})
await page.waitFor(2000);
expect(await page.data('refresherrefresh')).toBe(true)
});
} else {
it('other platform', () => {
expect(1).toBe(1)
it('check_refresher', async () => {
await page.setData({
refresherTriggered: true
})
}
await page.waitFor(2000);
expect(await page.data('refresherrefreshTimes')).toBe(1)
});
it('check_refresher_snapshot', async () => {
await page.setData({
refresherTriggered: true
})
await page.waitFor(300);
const image = await program.screenshot({fullPage: true});
expect(image).toSaveImageSnapshot();
});
});
......@@ -19,6 +19,7 @@
scrollData: [] as Array<string>,
refresherTriggered: false,
refresherrefresh: false,
refresherrefreshTimes: 0,
showScrollbar: false
};
},
......@@ -35,6 +36,7 @@
this.refresherrefresh = true
console.log("onRefresherrefresh--------------下拉刷新触发")
this.refresherTriggered = true
this.refresherrefreshTimes++
setTimeout(() => {
this.refresherTriggered = false
}, 1500)
......
......@@ -40,7 +40,6 @@
</navigator>
<view class="uni-common-pb"></view>
<!-- #ifdef APP -->
<navigator url="/pages/component/scroll-view/scroll-view-refresher-props" hover-class="none">
<button type="primary" class="button">
下拉刷新的属性示例
......@@ -57,7 +56,6 @@
</button>
</navigator>
<view class="uni-common-pb"></view>
<!-- #endif -->
</view>
</view>
<!-- #ifdef APP -->
......
......@@ -8,7 +8,7 @@ describe('slider', () => {
})
// it('change', async () => {})
it('value', async () => {
const slider = await page.$('.slider-custom-color-and-size')
const slider = await page.$('#slider-custom-color-and-size')
const sliderValue = 80
await page.setData({
......@@ -20,7 +20,7 @@ describe('slider', () => {
expect(newValue.toString()).toBe(sliderValue + '')
})
it('color', async () => {
const slider = await page.$('.slider-custom-color-and-size')
const slider = await page.$('#slider-custom-color-and-size')
expect(await slider.attribute('backgroundColor')).toBe('#000000')
expect(await slider.attribute('activeColor')).toBe('#FFCC33')
expect(await slider.attribute('blockColor')).toBe('#8A6DE9')
......@@ -40,7 +40,7 @@ describe('slider', () => {
expect(await slider.attribute('blockColor')).toBe(blockColor)
})
it('block-size', async () => {
const slider = await page.$('.slider-custom-color-and-size')
const slider = await page.$('#slider-custom-color-and-size')
expect(await slider.attribute('blockSize')).toBe(20 + '')
const blockSize = 18
......
......@@ -145,7 +145,7 @@
<view class="uni-title">不同颜色和大小的滑块</view>
<view>
<slider class="slider-custom-color-and-size" @change="sliderChange" :value="sliderValue"
<slider id="slider-custom-color-and-size" @change="sliderChange" :value="sliderValue"
:backgroundColor="sliderBackgroundColor" :activeColor="sliderActiveColor" :blockColor="sliderBlockColor"
:block-size="sliderBlockSize" />
</view>
......
......@@ -3,7 +3,7 @@
:refresher-enabled="refresher_enabled_boolean" :refresher-triggered="refresher_triggered_boolean"
@refresherrefresh="list_view_refresherrefresh">
<list-item type=1>
<swiper indicator-dots="true" circular="true">
<swiper indicator-dots="true" circular="true" style="height: 240px;">
<swiper-item v-for="i in 3" :item-id="i + ''">
<image src="/static/shuijiao.jpg" style="height: 240px; width: 100%;"></image>
<text style="position: absolute;">{{i}}</text>
......
......@@ -6,7 +6,8 @@ describe('component-native-sticky-section', () => {
})
//检测吸顶上推效果
it('check_sticky_section', async () => {
it('check_sticky_section', async () => {
page.waitFor(300)
await page.callMethod('listViewScrollByY', 1000)
const image = await program.screenshot({fullPage: true});
expect(image).toSaveImageSnapshot();
......
<template>
<page-head title="sticky-section"></page-head>
<list-view id="list-view" ref="list-view" show-scrollbar=false class="page" :scroll-into-view="scrollIntoView"
@scroll="onScroll" @scrollend="onScrollEnd" rebound="false">
<!-- #ifdef APP -->
@scroll="onScroll" @scrollend="onScrollEnd" rebound="false">
<list-item style="padding: 10px; margin: 5px 0;align-items: center;" :type = 20>
<button @click="gotoStickyHeader('C')" size="mini">跳转到id为C的sticky-header位置上</button>
</list-item>
<!-- #endif -->
</list-item>
<sticky-section v-for="(sectionText) in data" :padding="sectionPadding" :push-pinned-header="true">
<sticky-header :header-id="sectionText" :id="sectionText">
<text class="sticky-header-text">{{sectionText}}</text>
......@@ -43,8 +41,13 @@
// listview.scrollBy(0, y)
listview.scrollTop = y
},
gotoStickyHeader(id : string) {
this.scrollIntoView = id
gotoStickyHeader(id : string) {
// #ifdef APP
this.scrollIntoView = id
// #endif
// #ifdef WEB
console.log("web端不支持该功能")
// #endif
},
onScroll() {
this.scrolling = true
......
......@@ -87,13 +87,13 @@
</view>
<view class="uni-title">
<text class="uni-subtitle-text">padding</text>
<text class="uni-subtitle-text">padding和border</text>
</view>
<view class="text-box">
<text class="text-padding">hello uni-app x</text>
<text class="text-padding" style="width: 200px;">hello uni-app x</text>
<text class="text-padding" style="height: 100px;">hello uni-app x</text>
<text class="text-padding" style="width: 200px;height: 100px;">hello uni-app x</text>
<text class="text-padding-border">hello uni-app x</text>
<text class="text-padding-border" style="width: 200px;">hello uni-app x</text>
<text class="text-padding-border" style="height: 100px;">hello uni-app x</text>
<text class="text-padding-border" style="width: 200px;height: 100px;">hello uni-app x</text>
</view>
<view v-if="autoTest">
......@@ -162,10 +162,10 @@ export default {
text-align: center;
}
.text-padding {
.text-padding-border {
margin-top: 5px;
padding: 20px;
border: 1px solid red;
border: 5px solid red;
text-align: center;
}
</style>
......@@ -4,7 +4,7 @@
<!-- #endif -->
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="text-box" scroll-y="true">
<view class="text-box">
<text class="text">{{ text }}</text>
</view>
<view class="uni-btn-v">
......
......@@ -29,7 +29,7 @@ describe('component-native-textarea', () => {
width,
height
} = await textarea.size()
expect(height).toBeLessThanOrEqual(150)
expect(height).toBeLessThanOrEqual(200)
await page.setData({
default_value: "1\n2\n3\n4\n5\n6",
auto_height_boolean: false
......@@ -39,7 +39,7 @@ describe('component-native-textarea', () => {
width,
height
} = await textarea.size()
expect(height).toEqual(150)
expect(height).toEqual(200)
})
it("cursor-color", async () => {
await page.setData({
......@@ -49,6 +49,15 @@ describe('component-native-textarea', () => {
expect(await textarea.attribute("cursor-color")).toBe("transparent")
})
it("flex 1 height exception", async () => {
const bottomTextarea = await page.$('#textarea-height-exception');
var {
height
} = await bottomTextarea.size()
expect(height).toEqual(150)
})
it("inputmode", async () => {
const inputmodeEnum = await page.data("inputmode_enum")
for (var i = 0; i < inputmodeEnum.length; i++) {
......
......@@ -18,7 +18,7 @@ export default {
cursor: 0,
inputmode_enum_current: 0,
confirm_type_current: 0,
placeholder_value: "请输入"
placeholder_value: "请输入"
}
},
......@@ -66,6 +66,8 @@ export default {
:show-confirm-bar="show_confirm_bar_boolean"
:adjust-position="adjust_position_boolean"
:cursor-color="cursor_color"
:cursor="cursor"
:placeholder="placeholder_value"
:inputmode="inputmode_enum[inputmode_enum_current].name"
:confirm-type="confirm_type_list[confirm_type_current].name"
:maxlength="maxlength"
......@@ -82,60 +84,63 @@ export default {
@blur="textarea_blur"
@keyboardheightchange="textarea_keyboardheightchange"
@focus="textarea_focus"
style="padding: 10px; border: 1px solid #666"
style="padding: 10px; border: 1px solid #666;height: 200px"
/>
</view>
<view class="content">
<boolean-data
:defaultValue="false"
title="键盘弹起时,是否自动上推页面(限非 Web 平台)"
title="键盘弹起时,是否自动上推页面(限非 Web 平台)"
@change="change_adjust_position_boolean"
></boolean-data>
<boolean-data
:defaultValue="false"
title="是否显示键盘上方带有“完成”按钮那一栏(仅限小程序平台)"
@change="change_show_confirm_bar_boolean"
></boolean-data>
<boolean-data
:defaultValue="false"
title="如果 textarea 是在一个 position:fixed 的区域,需要显示指定属性 fixed 为 true(仅限小程序平台)"
@change="change_fixed_boolean"
></boolean-data>
<boolean-data
:defaultValue="false"
title="是否自动增高,设置auto-height时,style.height不生效"
@change="change_auto_height_boolean"
></boolean-data>
<boolean-data
:defaultValue="false"
title="点击键盘右下角按钮时是否保持键盘不收起"
@change="change_confirm_hold_boolean"
></boolean-data>
<boolean-data
:defaultValue="focus_boolean"
title="获取焦点"
@change="change_focus_boolean"
></boolean-data>
<boolean-data
:defaultValue="true"
title="首次自动获取焦点"
@change="change_auto_focus_boolean"
></boolean-data>
<boolean-data
:defaultValue="focus_boolean"
title="获取焦点"
@change="change_focus_boolean"
></boolean-data>
<boolean-data
:defaultValue="true"
title="首次自动获取焦点"
@change="change_auto_focus_boolean"
></boolean-data>
<boolean-data
:defaultValue="false"
title="改变光标颜色为透明"
@change="change_cursor_color_boolean"
></boolean-data>
<enum-data
:items="inputmode_enum"
title="是一个枚举属性,它提供了用户在编辑元素或其内容时可能输入的数据类型的提示。(仅限 Web 平台符合条件的高版本浏览器或webview)。"
@change="radio_change_inputmode_enum"
></enum-data>
<enum-data
:items="confirm_type_list"
title="枚举属性,可以设置键盘右下角按钮。(仅限 Web、iOS 平台)。"
title="confirm-type,设置键盘右下角按钮。(Android仅支持return)"
@change="radio_change_confirm_type"
></enum-data>
<boolean-data
:defaultValue="false"
title="点击软键盘右下角按钮时是否保持键盘不收起(confirm-type为return时必然不收起)"
@change="change_confirm_hold_boolean"
></boolean-data>
<enum-data
:items="inputmode_enum"
title="input-mode,控制软键盘类型。(仅限 Web 平台符合条件的高版本浏览器或webview)。"
@change="radio_change_inputmode_enum"
></enum-data>
<boolean-data
:defaultValue="false"
title="是否显示键盘上方带有“完成”按钮那一栏(仅限小程序平台)"
@change="change_show_confirm_bar_boolean"
></boolean-data>
<boolean-data
:defaultValue="false"
title="如果 textarea 是在一个 position:fixed 的区域,需要显示指定属性 fixed 为 true(仅限小程序平台)"
@change="change_fixed_boolean"
></boolean-data>
<view style="flex-direction:row;justify-content:center;">
<textarea id="textarea-height-exception" style="flex:1;border: 1 solid #666;margin: 10px" placeholder="底部textarea测试键盘遮挡"/>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
......
......@@ -5,7 +5,7 @@
:hover-start-time="start_time" :hover-stay-time="stay_time">
</view>
</view>
<scroll-view style="flex: 1" scroll-y="true">
<scroll-view style="flex: 1">
<view class="content">
<boolean-data :defaultValue="false" title="是否指定按下去的样式类" @change="change_hover_class_boolean"></boolean-data>
<boolean-data :defaultValue="false" title="是否阻止本节点的祖先节点出现点击态"
......
<template>
<view class="uni-flex-item">
<scroll-view class="uni-flex-item">
<web-view id="web-view" class="uni-flex-item" :src="src" :webview-styles="webview_styles"
:horizontalScrollBarAccess="horizontalScrollBarAccess" :verticalScrollBarAccess="verticalScrollBarAccess"
@message="message" @error="error" @loading="loading" @load="load" @download="download">
......@@ -34,7 +34,7 @@
<!-- #endif -->
</view>
<!-- #endif -->
</view>
</scroll-view>
</template>
<script>
......
此差异已折叠。
......@@ -66,17 +66,15 @@
},
{
name: 'swiper',
},
/*
{
name: 'movable-view',
enable: false
},
{
name: 'cover-view',
enable: false
},
*/
},
// #ifdef WEB
{
name: 'movable-view'
},
{
name: 'cover-view'
},
// #endif
{
name: 'list-view',
},
......@@ -127,14 +125,18 @@
},
{
name: 'input',
},
/*
{
name: 'label',
}, {
name: 'picker',
},
*/
},
// #ifdef WEB
{
name: 'editor',
},
{
name: 'label',
},
{
name: 'picker',
},
// #endif
{
name: 'picker-view',
},
......@@ -153,12 +155,6 @@
{
name: 'textarea',
},
/*
{
name: 'editor',
enable: false
},
*/
] as Page[],
},
{
......@@ -186,18 +182,18 @@
enable: false,
}, */
] as Page[],
},
// #ifdef WEB
{
id: 'map',
name: '地图',
pages: [
{
name: 'map',
}
] as Page[]
},
// {
// id: 'map',
// name: '地图',
// pages: [
// {
// name: 'map',
// enable: false
// }
// ] as Page[]
// },
// {
// id: 'canvas',
// name: '画布',
// pages: [
......@@ -205,7 +201,8 @@
// name: 'canvas'
// }
// ] as Page[]
// },
// },
// #endif
{
id: 'web-view',
name: '网页',
......@@ -312,11 +309,16 @@
// #ifdef UNI-APP-X && APP
checkUpdate(this.$refs['upgradePopup'] as UniUpgradeCenterAppComponentPublicInstance)
// #endif
},
onLoad() {
// console.log("component page onLoad")
},
onShow() {
// console.log("component page onShow")
this.pageHiden = false
},
onHide() {
// console.log("component page onHide")
this.pageHiden = true
},
beforeUnmount() {
......
......@@ -87,13 +87,6 @@
open: false,
pages: [] as Page[],
},
{
id: 'scroll-fold-nav',
url: 'scroll-fold-nav',
name: '随滚动折叠的导航栏',
open: false,
pages: [] as Page[],
},
{
id: 'swiper-list',
url: 'swiper-list',
......@@ -113,9 +106,16 @@
{
id: 'custom-long-list',
url: 'custom-long-list',
name: '自定义虚拟长列表',
name: '自定义虚拟长列表uni-recycle-view',
open: false,
pages: [] as Page[],
},
{
id: 'scroll-fold-nav',
url: 'scroll-fold-nav',
name: '随滚动折叠的导航栏',
open: false,
pages: [] as Page[],
},
// #ifdef APP
{
......@@ -131,6 +131,13 @@
name: '下拉缩放顶部封面图',
open: false,
pages: [] as Page[],
},
{
id: 'scroll-sticky',
url: 'scroll-sticky',
name: 'scroll-view自定义滚动吸顶',
open: false,
pages: [] as Page[],
},
// #endif
{
......@@ -140,15 +147,6 @@
open: false,
pages: [] as Page[],
},
// #ifdef APP
{
id: 'scroll-sticky',
url: 'scroll-sticky',
name: 'scroll-view自定义滚动吸顶',
open: false,
pages: [] as Page[],
},
// #endif
{
id: 'half-screen',
url: 'half-screen',
......
......@@ -2,7 +2,7 @@
<view style="flex: 1;background-color: aliceblue;">
<page-head :title="title"></page-head>
<view class="tips">list-view组件虽然在UI层有recycle机制,但长列表的vnode太多也会造成初始化卡顿。本组件仅创建部分vnode,而未使用list-view,也就是UI层其实是短列表。
此示例中仅渲染滚动容器上下5屏的内容。适用于仅使用一个for循环创建所有列表项的场景。</view>
此示例中仅渲染滚动容器上下5屏的内容。适用于仅使用一个for循环创建所有列表项的场景。文档详见插件市场:https://ext.dcloud.net.cn/plugin?id=17385</view>
<uni-recycle-view style="flex: 1;" :list="list" @scrolltoupper="scrolltoupper" @scroll="scroll">
<template v-slot:default="{items}">
<uni-recycle-item class="item" v-for="item in (items as Item[])" :item="item" :key="item.id">
......@@ -25,7 +25,7 @@
export default {
data() {
return {
title: '自行实现长列表组件',
title: '自定义虚拟列表组件uni-recycle-view',
list: [] as Item[]
}
},
......
<template>
<view class="content">
<uni-navbar-lite :title="title" :is-left="isLeft" :text-color="navigationBarTextColor"></uni-navbar-lite>
<scroll-view class="scroll-view" scroll-y="true">
<view class="content-item" @click="onClick">
<text>点击此处,将标题切换为{{isLeft?'居中':'左侧'}}显示</text>
</view>
<uni-navbar-lite :status-bar="true" :title="title" :is-left="isLeft" :text-color="navigationBarTextColor"></uni-navbar-lite>
<view class="content-item" @tap="setNavigationBarColor1">
<text>设置自定义导航栏前景色白色</text>
</view>
<view class="content-item" @tap="setNavigationBarColor2">
<text>设置自定义导航栏前景色黑色</text>
</view>
<view class="content-item" v-for="item in 20">
<view class="cell-item">
<text class="text">内容:{{item}}</text>
<input class="text" style="margin-top: 8px;" placeholder="备注:"/>
<view class="content-item" @click="onClick">
<text>点击此处,将标题切换为{{isLeft?'居中':'左侧'}}显示</text>
</view>
<view class="content-item" @tap="setNavigationBarColor1">
<text>设置自定义导航栏前景色白色</text>
</view>
<view class="content-item" @tap="setNavigationBarColor2">
<text>设置自定义导航栏前景色黑色</text>
</view>
<view style="align-items: center;height: 60px;">
<text>测试输入框上推页面</text>
<radio-group @change="ChangeView" style="flex-direction: row;">
<radio value="0" :checked="true"><text>scroll-view</text></radio>
<radio value="1"><text>list-view</text></radio>
<radio value="2"><text>web-view</text></radio>
</radio-group>
</view>
<scroll-view v-if="indexView==0" class="scroll-view">
<view class="content-item" v-for="item in 10">
<view class="cell-item">
<text class="text">内容:{{item}}</text>
<input class="text" style="margin-top: 8px;" placeholder="备注输入框:" />
</view>
</view>
<!-- <input/> -->
</view>
</scroll-view>
<list-view v-if="indexView==1" class="scroll-view">
<list-item class="content-item" v-for="item in 10">
<view class="cell-item">
<text class="text">列表项内容:{{item}}</text>
<input class="text" style="margin-top: 8px;" placeholder="备注输入框:" />
</view>
</list-item>
</list-view>
<web-view v-if="indexView==2" src="/hybrid/html/local.html" id="webv" style="height:380px"></web-view>
<view style="position: relative;bottom: 0;">
<input placeholder="滚动视图外的居底输入框" adjust-position="true" />
</view>
</view>
</template>
<script>
<script>
import { state, setLifeCycleNum } from '@/store/index.uts'
export default {
data() {
return {
title: 'Hello uni-app',
isLeft: false,
navigationBarTextColor: '#000'
isLeft: false,
navigationBarTextColor: '#000',
indexView: 0
}
},
methods: {
onClick(){
this.isLeft = !this.isLeft
},
setNavigationBarColor1() {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#0000',
success: () => {
this.navigationBarTextColor = '#fff'
console.log('setNavigationBarColor success')
this.setLifeCycleNum(state.lifeCycleNum + 1)
},
fail: () => {
console.log('setNavigationBarColor fail')
this.setLifeCycleNum(state.lifeCycleNum - 1)
},
complete: () => {
console.log('setNavigationBarColor complete')
this.setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
setNavigationBarColor2() {
uni.setNavigationBarColor({
frontColor: '#000000',
backgroundColor: '#0000',
success: () => {
this.navigationBarTextColor = '#000'
console.log('setNavigationBarColor success')
this.setLifeCycleNum(state.lifeCycleNum + 1)
},
fail: () => {
console.log('setNavigationBarColor fail')
this.setLifeCycleNum(state.lifeCycleNum - 1)
},
complete: () => {
console.log('setNavigationBarColor complete')
this.setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
// 自动化测试
getLifeCycleNum(): number {
return state.lifeCycleNum
},
// 自动化测试
setLifeCycleNum(num: number) {
setLifeCycleNum(num)
methods: {
onClick() {
this.isLeft = !this.isLeft
},
setNavigationBarColor1() {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#0000',
success: () => {
this.navigationBarTextColor = '#fff'
console.log('setNavigationBarColor success')
this.setLifeCycleNum(state.lifeCycleNum + 1)
},
fail: () => {
console.log('setNavigationBarColor fail')
this.setLifeCycleNum(state.lifeCycleNum - 1)
},
complete: () => {
console.log('setNavigationBarColor complete')
this.setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
setNavigationBarColor2() {
uni.setNavigationBarColor({
frontColor: '#000000',
backgroundColor: '#0000',
success: () => {
this.navigationBarTextColor = '#000'
console.log('setNavigationBarColor success')
this.setLifeCycleNum(state.lifeCycleNum + 1)
},
fail: () => {
console.log('setNavigationBarColor fail')
this.setLifeCycleNum(state.lifeCycleNum - 1)
},
complete: () => {
console.log('setNavigationBarColor complete')
this.setLifeCycleNum(state.lifeCycleNum + 1)
}
})
},
ChangeView(e:UniRadioGroupChangeEvent){
this.indexView = parseInt(e.detail.value)
},
// 自动化测试
getLifeCycleNum() : number {
return state.lifeCycleNum
},
// 自动化测试
setLifeCycleNum(num : number) {
setLifeCycleNum(num)
},
}
}
</script>
......@@ -108,11 +129,11 @@
margin: 5px 10px;
background-color: #fff;
border-radius: 5px;
}
.cell-item {
display: flex;
flex-direction: column;
}
.cell-item {
display: flex;
flex-direction: column;
}
.text {
......
<template>
<view>
<!-- #ifdef UNI-APP-X -->
<button class="button" @click="openSchema('https://uniapp.dcloud.io/uni-app-x')">使用外部浏览器打开指定URL</button>
<!-- #ifdef APP-ANDROID -->
<button class="button" @click="openSchema('market://details?id=com.tencent.mm')">使用应用商店打开指定App</button>
......@@ -13,7 +12,6 @@
<button class="button" @click="openSchema('http://maps.apple.com/?q=数字天堂公司&sll=39.9631018208,116.3406135236&z=10&t=s')">打开 iOS 地图坐标</button>
<!-- apple协议:https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html -->
<!-- #endif -->
<!-- #endif -->
</view>
</template>
......
......@@ -6,7 +6,7 @@
<swiper class="swiper" :current="current" :circular="index != 0" :vertical="true" @change="onSwiperChange"
@transition="onTransition">
<swiper-item class="swiper-item" v-for="(item,i) in visibleList" :key="i">
<video @click="changeState(i)" ref="video" class="video-box" objectFit="cover" :id="'video-'+i"
<video @click="changeState(i)" ref="video" class="video-box" :id="'video-'+i"
@loadstart="onLoadstart(i)" :src="item.src" :poster="item.poster_src" :autoplay="false"
:show-center-play-btn="false" :loop="true" @play="onPlay(i)" @pause="onPause(i)" http-cache="true"></video>
<view class="video-cover" @click="changeState(i)">
......@@ -154,15 +154,15 @@
},
getData() : ListItem[] {
let videoUrlList = [
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/video/swiper-vertical-video/uts.mp4',
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/video/swiper-vertical-video/uni-ai.mp4',
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/video/swiper-vertical-video/uni-verify.mp4'
'https://web-ext-storage.dcloud.net.cn/uni-app-x/video/uts-5-16.mp4',
'https://web-ext-storage.dcloud.net.cn/uni-app-x/video/uni-ai-5-16.mp4',
'https://web-ext-storage.dcloud.net.cn/uni-app-x/video/uni-verify-5-16.mp4'
] as string[]
let posterSrcList = [
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/images/swiper-vertical-video-poster/uni-uts.jpg',
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/images/swiper-vertical-video-poster/uni-ai.jpg',
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/images/swiper-vertical-video-poster/uni-verify.jpg'
'https://web-ext-storage.dcloud.net.cn/uni-app-x/dark-uni-uts-01.png',
'https://web-ext-storage.dcloud.net.cn/uni-app-x/dark-uni-ai-01.png',
'https://web-ext-storage.dcloud.net.cn/uni-app-x/dark-uni-verify-01.jpg'
] as string[]
let list = [] as ListItem[];
......
{
"id": "uni-scss",
"displayName": "uni-scss 辅助样式",
"version": "1.0.3",
"description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
"id": "test-invoke-network-api",
"displayName": "test-invoke-network-api",
"version": "1.0.0",
"description": "测试UTS插件中访问网络相关接口",
"keywords": [
"uni-scss",
"uni-ui",
"辅助样式"
"test-invoke-network-api"
],
"repository": "https://github.com/dcloudio/uni-ui",
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
"HBuilderX": "^3.6.8"
},
"dcloudext": {
"category": [
"JS SDK",
"通用 SDK"
],
"type": "uts",
"sale": {
"regular": {
"price": "0.00"
......@@ -29,52 +24,57 @@
"qq": ""
},
"declaration": {
"ads": "",
"data": "",
"permissions": ""
"ads": "",
"data": "",
"permissions": ""
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
"tcb": "u",
"aliyun": "u",
"alipay": "u"
},
"client": {
"Vue": {
"vue2": "u",
"vue3": "u"
},
"App": {
"app-vue": "y",
"app-nvue": "u"
"app-android": "u",
"app-ios": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
"Safari": "u",
"Android Browser": "u",
"微信浏览器(Android)": "u",
"QQ浏览器(Android)": "u"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
"Chrome": "u",
"IE": "u",
"Edge": "u",
"Firefox": "u",
"Safari": "u"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
"微信": "u",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "n",
"联盟": "n"
},
"Vue": {
"vue2": "y",
"vue3": "y"
"华为": "u",
"联盟": "u"
}
}
}
......
# test-invoke-network-api
### 开发文档
[UTS 语法](https://uniapp.dcloud.net.cn/tutorial/syntax-uts.html)
[UTS API插件](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html)
[UTS 组件插件](https://uniapp.dcloud.net.cn/plugin/uts-component.html)
[Hello UTS](https://gitcode.net/dcloud/hello-uts)
\ No newline at end of file
{
"minSdkVersion": "21"
}
\ No newline at end of file
import { CommonOptions } from '../interface.uts'
export function testInovkeRequest(options : CommonOptions) : void {
uni.request<any>({
url: "https://request.dcloud.net.cn/api/http/method/post",
method: "POST",
header: {
"Cookie": "token11222"
} as UTSJSONObject,
timeout: 6000,
sslVerify: false,
withCredentials: false,
data: {
"platform": {
"abc": "xyq"
},
},
firstIpv4: false,
success: (res : RequestSuccess<any>) => {
options.success?.(res)
},
fail(e : RequestFail) {
options.fail?.(e)
},
} as RequestOptions<any>)
}
export function testInovkeUploadFile(options : CommonOptions) : void {
const imageSrc = "/static/uni.png";
uni.uploadFile({
url: 'https://unidemo.dcloud.net.cn/upload',
files: [
{
name: "file1",
uri: imageSrc
} as UploadFileOptionFiles,
{
name: "file2",
uri: imageSrc
} as UploadFileOptionFiles
],
success: (res : UploadFileSuccess) => {
options.success?.(res)
},
fail: (err : UploadFileFail) => {
options.fail?.(err)
},
} as UploadFileOptions)
}
export function testInovkeDownloadFile(options : CommonOptions) : void {
uni.downloadFile({
url: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app.png",
filePath: `${uni.env.CACHE_PATH}/halo/world/`,
success(res : DownloadFileSuccess) {
options.success?.(res)
},
fail(e : DownloadFileFail) {
options.fail?.(e)
}
} as DownloadFileOptions);
}
{
"deploymentTarget": "9"
}
\ No newline at end of file
import { CommonOptions } from '../interface.uts'
export function testInovkeRequest(options : CommonOptions) : void {
uni.request<any>({
url: "https://request.dcloud.net.cn/api/http/method/post",
method: "POST",
header: {
"Cookie": "token11222"
} as UTSJSONObject,
timeout: 6000,
sslVerify: false,
withCredentials: false,
data: {
"platform": {
"abc": "xyq"
},
},
firstIpv4: false,
success: (res : RequestSuccess<any>) => {
options.success?.(res)
},
fail(e : RequestFail) {
options.fail?.(e)
},
} as RequestOptions<any>)
}
export function testInovkeUploadFile(options : CommonOptions) : void {
const imageSrc = "/static/uni.png";
uni.uploadFile({
url: 'https://unidemo.dcloud.net.cn/upload',
files: [
{
name: "file1",
uri: imageSrc
} as UploadFileOptionFiles,
{
name: "file2",
uri: imageSrc
} as UploadFileOptionFiles
],
success: (res : UploadFileSuccess) => {
options.success?.(res)
},
fail: (err : UploadFileFail) => {
options.fail?.(err)
},
} as UploadFileOptions)
}
export function testInovkeDownloadFile(options : CommonOptions) : void {
uni.downloadFile({
url: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app.png",
filePath: `${uni.env.CACHE_PATH}/halo/world/`,
success(res : DownloadFileSuccess) {
options.success?.(res)
},
fail(e : DownloadFileFail) {
options.fail?.(e)
}
} as DownloadFileOptions);
}
export type CommonOptions = {
success ?: (res: any) => void
fail ?: (res : any) => void
}
export type testInovkeRequest = (options : CommonOptions) => void
export type testInovkeUploadFile = (options : CommonOptions) => void
export type testInovkeDownloadFile = (options : CommonOptions) => void
......@@ -5,7 +5,7 @@ import { Int } from 'Swift';
import { GetBatteryInfo, GetBatteryInfoSuccess, GetBatteryInfoResult, GetBatteryInfoSync } from '../interface.uts';
/**
* 导出 获取电量方法
* 导出 获取电量方法
*/
export const getBatteryInfo : GetBatteryInfo = function (options) {
......@@ -15,7 +15,7 @@ export const getBatteryInfo : GetBatteryInfo = function (options) {
// 返回数据
const res : GetBatteryInfoSuccess = {
errMsg: "getBatteryInfo:ok",
level: new Int(UIDevice.current.batteryLevel * 100),
level: Math.abs(Number(UIDevice.current.batteryLevel * 100)),
isCharging: UIDevice.current.batteryState == UIDevice.BatteryState.charging,
};
options.success?.(res);
......@@ -29,8 +29,8 @@ export const getBatteryInfoSync : GetBatteryInfoSync = function (): GetBatteryIn
// 返回数据
const res : GetBatteryInfoResult = {
level: Number(UIDevice.current.batteryLevel * 100),
level: Math.abs(Number(UIDevice.current.batteryLevel * 100)),
isCharging: UIDevice.current.batteryState == UIDevice.BatteryState.charging,
};
return res;
}
\ No newline at end of file
}
......@@ -11,7 +11,7 @@
* @property {any[]} item 当前组件渲染的列表项
*/
export default {
name: "custom-list-item",
name: "uni-recycle-item",
props: {
item: {
type: Object as PropType<any>,
......
......@@ -22,7 +22,7 @@
* @property {any[]} list 列表所有数据
*/
export default {
name: "custom-list-view",
name: "uni-recycle-view",
props: {
list: {
type: Array as PropType<any[]>,
......
## uni-recycle-view
> 此组件支持uni-app-x(web端及app端),不支持非uni-app-x项目
> 此组件支持uni-app-x(web端及app端),不支持非uni-app-x项目。最低HBuilderX版本4.11
uni-recycle-view 组件是一个开源的、适用于展示超长列表的组件,它有2个优势:
- 更快的初始化速度
......
此差异已折叠。
`uni-sass``uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册