Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
hello-uvue
提交
5a0eea13
H
hello-uvue
项目概览
DCloud
/
hello-uvue
通知
367
Star
3
Fork
8
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hello-uvue
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
5a0eea13
编写于
11月 27, 2024
作者:
dcloud_wdl
浏览文件
操作
浏览文件
下载
差异文件
[转正] git merge origin/alpha
上级
22acdae9
0395fa44
变更
57
隐藏空白更改
内联
并排
Showing
57 changed file
with
1808 addition
and
613 deletion
+1808
-613
App.uvue
App.uvue
+102
-99
changelog.md
changelog.md
+16
-4
components/CompForHFunction.uvue
components/CompForHFunction.uvue
+16
-6
components/CompForHFunctionWithSlot.uvue
components/CompForHFunctionWithSlot.uvue
+6
-0
jest.config.js
jest.config.js
+4
-1
package.json
package.json
+4
-4
pages/App.test.js
pages/App.test.js
+3
-0
pages/component-instance/data/data-options.uvue
pages/component-instance/data/data-options.uvue
+1
-1
pages/component-instance/inject/inject-options-1.uvue
pages/component-instance/inject/inject-options-1.uvue
+2
-2
pages/component-instance/inject/inject-options-2.uvue
pages/component-instance/inject/inject-options-2.uvue
+1
-1
pages/component-instance/methods/call-method-easycom-uni-modules-composition.test.js
...thods/call-method-easycom-uni-modules-composition.test.js
+45
-0
pages/component-instance/methods/call-method-easycom-uni-modules-composition.uvue
.../methods/call-method-easycom-uni-modules-composition.uvue
+132
-59
pages/component-instance/methods/call-method-easycom-uni-modules-options.test.js
...e/methods/call-method-easycom-uni-modules-options.test.js
+46
-0
pages/component-instance/methods/call-method-easycom-uni-modules-options.uvue
...ance/methods/call-method-easycom-uni-modules-options.uvue
+121
-59
pages/component-instance/options/options-composition.uvue
pages/component-instance/options/options-composition.uvue
+17
-20
pages/component-instance/options/options-options.uvue
pages/component-instance/options/options-options.uvue
+12
-15
pages/component-instance/props/object-type-composition.uvue
pages/component-instance/props/object-type-composition.uvue
+1
-1
pages/component-instance/props/object-type-options.uvue
pages/component-instance/props/object-type-options.uvue
+1
-1
pages/component-instance/setup-function/RenderFunction.uvue
pages/component-instance/setup-function/RenderFunction.uvue
+1
-1
pages/directive/v-bind/v-bind-composition.uvue
pages/directive/v-bind/v-bind-composition.uvue
+27
-6
pages/directive/v-bind/v-bind-options.uvue
pages/directive/v-bind/v-bind-options.uvue
+28
-6
pages/directive/v-bind/v-bind.test.js
pages/directive/v-bind/v-bind.test.js
+13
-2
pages/directive/v-model/Foo-composition.uvue
pages/directive/v-model/Foo-composition.uvue
+13
-1
pages/directive/v-model/v-model-composition.test.js
pages/directive/v-model/v-model-composition.test.js
+16
-6
pages/directive/v-model/v-model-composition.uvue
pages/directive/v-model/v-model-composition.uvue
+6
-1
pages/directive/v-show/Foo.uvue
pages/directive/v-show/Foo.uvue
+5
-0
pages/directive/v-show/v-show-composition.uvue
pages/directive/v-show/v-show-composition.uvue
+51
-26
pages/directive/v-show/v-show-options.uvue
pages/directive/v-show/v-show-options.uvue
+55
-29
pages/directive/v-show/v-show.test.js
pages/directive/v-show/v-show.test.js
+18
-8
pages/error/throw-error/throw-error-composition.uvue
pages/error/throw-error/throw-error-composition.uvue
+8
-2
pages/error/throw-error/throw-error-options.uvue
pages/error/throw-error/throw-error-options.uvue
+30
-24
pages/error/throw-error/throw-error.test.js
pages/error/throw-error/throw-error.test.js
+59
-47
pages/index/index.uvue
pages/index/index.uvue
+5
-5
pages/lifecycle/component/ChildComponentComposition.uvue
pages/lifecycle/component/ChildComponentComposition.uvue
+11
-5
pages/lifecycle/component/ChildComponentOptions.uvue
pages/lifecycle/component/ChildComponentOptions.uvue
+10
-0
pages/lifecycle/component/component-composition.test.js
pages/lifecycle/component/component-composition.test.js
+24
-6
pages/lifecycle/component/component-composition.uvue
pages/lifecycle/component/component-composition.uvue
+19
-3
pages/lifecycle/component/component-options.test.js
pages/lifecycle/component/component-options.test.js
+42
-33
pages/lifecycle/component/component-options.uvue
pages/lifecycle/component/component-options.uvue
+18
-1
pages/lifecycle/page/page.test.js
pages/lifecycle/page/page.test.js
+8
-8
pages/reactivity/core/reactive/reactive.test.js
pages/reactivity/core/reactive/reactive.test.js
+53
-35
pages/reactivity/core/reactive/reactive.uvue
pages/reactivity/core/reactive/reactive.uvue
+85
-45
pages/reactivity/core/watch/watch-options.uvue
pages/reactivity/core/watch/watch-options.uvue
+1
-1
pages/render-function/render/Foo.uvue
pages/render-function/render/Foo.uvue
+6
-0
pages/render-function/render/render-composition.uvue
pages/render-function/render/render-composition.uvue
+12
-5
pages/render-function/render/render-options.uvue
pages/render-function/render/render-options.uvue
+41
-32
pages/render-function/render/render.test.js
pages/render-function/render/render.test.js
+8
-1
testSequencer.js
testSequencer.js
+17
-0
uni_modules/call-easy-method/components/call-easy-method-uni-modules/call-easy-method-uni-modules.vue
...-easy-method-uni-modules/call-easy-method-uni-modules.vue
+8
-1
uni_modules/test-props/changelog.md
uni_modules/test-props/changelog.md
+0
-0
uni_modules/test-props/package.json
uni_modules/test-props/package.json
+82
-0
uni_modules/test-props/readme.md
uni_modules/test-props/readme.md
+6
-0
uni_modules/test-props/utssdk/app-android/event.uts
uni_modules/test-props/utssdk/app-android/event.uts
+7
-0
uni_modules/test-props/utssdk/app-android/index.uts
uni_modules/test-props/utssdk/app-android/index.uts
+4
-0
uni_modules/test-props/utssdk/app-android/index.vue
uni_modules/test-props/utssdk/app-android/index.vue
+228
-0
uni_modules/test-props/utssdk/app-ios/index.vue
uni_modules/test-props/utssdk/app-ios/index.vue
+241
-0
uni_modules/test-props/utssdk/interface.uts
uni_modules/test-props/utssdk/interface.uts
+12
-0
未找到文件。
App.uvue
浏览文件 @
5a0eea13
<script lang="uts">
import { state, setLifeCycleNum, setAppLaunchPath, setAppShowPath } from './store/index.uts'
import { state, setLifeCycleNum, setAppLaunchPath, setAppShowPath } from './store/index.uts'
let firstBackTime = 0
export default {
// #ifndef APP-ANDROID
mixins: [
{
data() {
return {
appMixinDataMsg: 'App.uvue mixin data msg'
let firstBackTime = 0
export default {
// #ifndef APP-ANDROID
mixins: [
{
data() {
return {
appMixinDataMsg: 'App.uvue mixin data msg'
}
}
}
}],
// #endif
onLaunch: function (options) {
console.log(options)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1000)
setAppLaunchPath(options.path)
console.log('App Launch')
// #ifdef UNI-APP-X && APP-ANDROID
const performance = uni.getPerformance()
const observer : PerformanceObserver = performance.createObserver((entryList : PerformanceObserverEntryList) => {
console.log('observer:entryList.getEntries()')
console.log(entryList.getEntries())
})
observer.observe({
entryTypes: ['render', 'navigation'],
} as PerformanceObserverOptions)
}],
// #endif
},
onShow: function (options) {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 100)
setAppShowPath(options.path)
console.log('App Show')
},
onHide: function () {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 100)
console.log('App Hide')
},
// #ifdef APP-ANDROID
onLastPageBackPress: function () {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 1000)
console.log('App LastPageBackPress')
if (firstBackTime == 0) {
uni.showToast({
title: '再按一次退出应用',
position: 'bottom',
onLaunch: function (options) {
console.log(options)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1000)
setAppLaunchPath(options.path)
console.log('App Launch')
// #ifdef UNI-APP-X && APP-ANDROID
const performance = uni.getPerformance()
const observer : PerformanceObserver = performance.createObserver((entryList : PerformanceObserverEntryList) => {
console.log('observer:entryList.getEntries()')
console.log(entryList.getEntries())
})
firstBackTime = Date.now()
setTimeout(() => {
firstBackTime = 0
}, 2000)
} else if (Date.now() - firstBackTime < 2000) {
firstBackTime = Date.now()
uni.exit()
}
},
onExit() {
console.log('App Exit')
},
// #endif
onError: function(error: any) {
console.log('App Error', error)
setLifeCycleNum(state.lifeCycleNum + 100)
},
methods: {
checkLaunchPath() : boolean {
const HOME_PATH = 'pages/index/index'
if (state.appLaunchPath != HOME_PATH) {
return false
}
if (state.appShowPath != HOME_PATH) {
return false
observer.observe({
entryTypes: ['render', 'navigation'],
} as PerformanceObserverOptions)
// #endif
},
onShow: function (options) {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 100)
setAppShowPath(options.path)
if(this.globalPropertiesStr === 'default string'){
setLifeCycleNum(state.lifeCycleNum + 10)
}
return true
console.log('App Show')
},
// #ifndef APP-ANDROID
checkAppMixin() : boolean {
if(this.globalMixinDataMsg1 != '通过 defineMixin 定义全局 mixin data') {
return false
onHide: function () {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 100)
console.log('App Hide')
},
// #ifdef APP-ANDROID
onLastPageBackPress: function () {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 1000)
console.log('App LastPageBackPress')
if (firstBackTime == 0) {
uni.showToast({
title: '再按一次退出应用',
position: 'bottom',
})
firstBackTime = Date.now()
setTimeout(() => {
firstBackTime = 0
}, 2000)
} else if (Date.now() - firstBackTime < 2000) {
firstBackTime = Date.now()
uni.exit()
}
if(this.appMixinDataMsg != 'App.uvue mixin data msg') {
return false
},
onExit() {
console.log('App Exit')
},
// #endif
onError: function(error: any) {
console.log('App Error', error)
setLifeCycleNum(state.lifeCycleNum + 100)
},
methods: {
checkLaunchPath() : boolean {
const HOME_PATH = 'pages/index/index'
if (state.appLaunchPath != HOME_PATH) {
return false
}
if (state.appShowPath != HOME_PATH) {
return false
}
return true
},
// #ifndef APP-ANDROID
checkAppMixin() : boolean {
if(this.globalMixinDataMsg1 != '通过 defineMixin 定义全局 mixin data') {
return false
}
if(this.appMixinDataMsg != 'App.uvue mixin data msg') {
return false
}
return true
}
return true
// #endif
}
// #endif
}
}
</script>
<style>
@import './styles/common.css';
@import './styles/common.css';
.list-item-text {
line-height: 36px;
}
.list-item-text {
line-height: 36px;
}
.split-title {
margin: 20px 0 5px;
padding: 5px 0;
border-bottom: 1px solid #dfdfdf;
}
.split-title {
margin: 20px 0 5px;
padding: 5px 0;
border-bottom: 1px solid #dfdfdf;
}
.btn-view {
margin: 10px 0;
padding: 10px;
border: 1px solid #dfdfdf;
border-radius: 3px;
}
.btn-view {
margin: 10px 0;
padding: 10px;
border: 1px solid #dfdfdf;
border-radius: 3px;
}
</style>
<style>
.text-red{
color: red;
}
</style>
\ No newline at end of file
</style>
changelog.md
浏览文件 @
5a0eea13
## 1.0.
9
*
update 4.
29.2024093009
## 1.0.
28
*
update 4.
36.2024112612-alpha
## 1.0.8
*
update 4.28.2024092502
## 1.0.27
*
update 4.35.2024112402-alpha
## 1.0.26
*
update 4.34.2024112020-alpha
## 1.0.25
*
update 4.33.2024111702-alpha
## 1.0.24
*
update 4.32.2024110103-alpha
## 1.0.23
*
update 4.31.2024102414-alpha
## 1.0.22
*
update 4.28.2024092105-alpha
...
...
components/CompForHFunction.uvue
浏览文件 @
5a0eea13
<template>
<view>
<text class="uni-common-mt bold component-for-h-function">component for h()</text>
<slot />
</view>
</template>
<template>
<view>
<text class="uni-common-mt bold component-for-h-function">component for h()</text>
<text id="comp-for-h-function-msg">{{msg}}</text>
</view>
</template>
<script>
export default {
props: {
msg: {
type: String
}
}
}
</script>
components/CompForHFunctionWithSlot.uvue
0 → 100644
浏览文件 @
5a0eea13
<template>
<view>
<text class="uni-common-mt bold component-for-h-function">component for h() with slot</text>
<slot />
</view>
</template>
jest.config.js
浏览文件 @
5a0eea13
const
path
=
require
(
'
path
'
)
module
.
exports
=
{
testTimeout
:
10000
,
reporters
:
[
'
default
'
],
watchPathIgnorePatterns
:
[
'
/node_modules/
'
,
'
/dist/
'
,
'
/.git/
'
],
moduleFileExtensions
:
[
'
js
'
,
'
json
'
],
rootDir
:
__dirname
,
testMatch
:
[
'
<rootDir>/pages/**/**/*.test.js
'
],
testMatch
:
[
"
<rootDir>/pages/App.test.js
"
],
testPathIgnorePatterns
:
[
'
/node_modules/
'
],
setupFilesAfterEnv
:
[
'
<rootDir>/jest-setup.js
'
],
testSequencer
:
path
.
join
(
__dirname
,
"
testSequencer.js
"
)
}
package.json
浏览文件 @
5a0eea13
{
"id"
:
"hello-uvue"
,
"name"
:
"hello-uvue"
,
"displayName"
:
"hello-uvue"
,
"version"
:
"1.0.
9
"
,
"id"
:
"hello-uvue
-alpha
"
,
"name"
:
"hello-uvue
-alpha
"
,
"displayName"
:
"hello-uvue
-alpha
"
,
"version"
:
"1.0.
28
"
,
"description"
:
"uvue的vue语法示例工程"
,
"main"
:
"env.js"
,
"scripts"
:
{
...
...
pages/App.test.js
浏览文件 @
5a0eea13
...
...
@@ -8,5 +8,8 @@ describe("app launch & show options", () => {
if
(
!
process
.
env
.
uniTestPlatformInfo
.
startsWith
(
'
android
'
))
{
expect
(
await
page
.
callMethod
(
"
checkAppMixin
"
)).
toBe
(
true
)
}
const
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
1110
)
})
})
pages/component-instance/data/data-options.uvue
浏览文件 @
5a0eea13
...
...
@@ -51,7 +51,7 @@
num: 10,
arr: [4, 5, 6]
} as Obj,
refElement: null,
refElement: null
as UniElement | null
,
refElementIsSame: false
}
},
...
...
pages/component-instance/inject/inject-options-1.uvue
浏览文件 @
5a0eea13
...
...
@@ -63,7 +63,7 @@ export default {
default: false
},
providePageObject: {
type:
Object as PropType<UTSJSONObject>
,
type:
UTSJSONObject
,
default: (): UTSJSONObject => {
return {
title: 'default provide page object title',
...
...
@@ -94,7 +94,7 @@ export default {
default: 'test inject string default value'
},
testInjectObjectDefaultValue: {
type:
Object as PropType<UTSJSONObject>
,
type:
UTSJSONObject
,
default(): UTSJSONObject {
return {
title: 'test inject object default value title',
...
...
pages/component-instance/inject/inject-options-2.uvue
浏览文件 @
5a0eea13
...
...
@@ -39,7 +39,7 @@ export default {
default: false
},
providePageObject: {
type:
Object as PropType<UTSJSONObject>
,
type:
UTSJSONObject
,
default: (): UTSJSONObject => {
return {
title: 'default provide page object title',
...
...
pages/component-instance/methods/call-method-easycom-uni-modules-composition.test.js
0 → 100644
浏览文件 @
5a0eea13
const
PAGE_PATH
=
"
/pages/component-instance/methods/call-method-easycom-uni-modules-composition
"
let
page
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
PAGE_PATH
)
await
page
.
waitFor
(
'
view
'
)
})
it
(
'
callMethodTest
'
,
async
()
=>
{
// a[[]] only issue 8582
if
(
process
.
env
.
uniTestPlatformInfo
.
toLowerCase
().
startsWith
(
'
web
'
))
{
expect
(
1
).
toBe
(
1
)
return
}
const
platformInfo
=
process
.
env
.
uniTestPlatformInfo
.
toLocaleLowerCase
()
const
isIOS
=
process
.
env
.
uniTestPlatformInfo
.
toLowerCase
().
startsWith
(
'
ios
'
)
// ios_simulator ios 17.0
// xcodoe 15 以下的版本环境不满足
if
(
isIOS
&&
(
platformInfo
.
indexOf
(
'
14.
'
)
!=
-
1
||
platformInfo
.
indexOf
(
'
13.
'
)
!=
-
1
||
platformInfo
.
indexOf
(
'
12.
'
)
!=
-
1
)
)
{
expect
(
1
).
toBe
(
1
)
return
}
const
delay
=
()
=>
new
Promise
((
resolve
,
_
)
=>
{
setTimeout
(()
=>
{
resolve
(
''
)
},
1500
)
})
await
page
.
callMethod
(
'
onButtonClick
'
)
await
delay
()
const
resStr1
=
await
page
.
$
(
"
#isNumListValid
"
)
const
resStr2
=
await
page
.
$
(
"
#isObjListValid
"
)
expect
(
await
resStr1
.
text
()).
toBe
(
`true`
)
expect
(
await
resStr2
.
text
()).
toBe
(
`true`
)
})
pages/component-instance/methods/call-method-easycom-uni-modules-composition.uvue
浏览文件 @
5a0eea13
<template>
<view>
<call-easy-method-uni-modules ref="callEasyMethod1"></call-easy-method-uni-modules>
<!-- #ifdef APP -->
<view>---</view>
<test-props id="btn1" :numList="numList" :objList='objList' @buttonclick='onButtonClick'
@numListChange='numListChange' @objListChange='objListChange'
style="width: 80px;height: 30px;background-color: lightblue"></test-props>
<view style="flex-direction: row ;">
<text>isNumListValid: </text>
<text id='isNumListValid'>{{isNumListValid}}</text>
</view>
<view style="flex-direction: row ;">
<text>isObjListValid: </text>
<text id='isObjListValid'>{{isObjListValid}}</text>
</view>
<!-- #endif -->
</view>
</template>
<script setup lang="uts">
import { testInOtherFile } from './call-method-easycom-uni-modules'
import { testInOtherFile } from './call-method-easycom-uni-modules'
import { ref, isProxy, isRef } from 'vue'
const delay = (): Promise<string> =>
new Promise((resolve, _) => {
setTimeout(() => {
resolve('')
}, 1000)
// #ifdef APP
import { PropsChangeEvent } from '@/uni_modules/test-props'
// #endif
const delay = () : Promise<string> =>
new Promise((resolve, _) => {
setTimeout(() => {
resolve('')
}, 1000)
})
const callEasyMethod1 = ref<CallEasyMethodUniModulesComponentPublicInstance | null>(null)
const numList = ref<number[]>([1]) // 传递 props
const objList = ref<any[]>([])
const isNumListValid = ref(false)
const isObjListValid = ref(false)
const callMethod1 = () => {
// 调用组件的 foo1 方法
callEasyMethod1.value?.foo1?.()
}
const callMethod2 = () => {
// 调用组件的 foo2 方法并传递 1个参数
callEasyMethod1.value?.foo2?.(Date.now())
}
const callMethod3 = () => {
// 调用组件的 foo3 方法并传递 2个参数
callEasyMethod1.value?.foo3?.(Date.now(), Date.now())
}
const callMethod4 = () => {
// 调用组件的 foo4 方法并传递 callback
callEasyMethod1.value?.foo4?.(() => {
console.log('callback')
})
}
const callMethod5 = () => {
// 注意: 返回值可能为 null,当前例子一定不为空,所以加了 !
const result = callEasyMethod1.value?.foo5?.('string5') as string
console.log(result) // string1
}
const callMethodTest = (text : string) : string | null => {
const result = callEasyMethod1.value?.foo5?.(text) as string
return result
}
const callMethodInOtherFile = (text : string) : string => {
return testInOtherFile(callEasyMethod1.value!, text)
}
// #ifdef APP-ANDROID
const numListChange = (res : Map<string, Map<string, any>>) => {
const value = res['detail']!['value'] as number[]
const isArray = Array.isArray(value)
const isLengthGt0 = value.length > 0
isNumListValid.value = isArray && isLengthGt0
}
// #endif
// #ifdef APP-IOS
const numListChange = (res : any) => {
const value = res['detail']!['value'] as number[]
const isArray = Array.isArray(value)
const isLengthGt0 = value.length > 0
console.log('is array',isArray,'is length>0',isLengthGt0,'res',isArray && isLengthGt0);
isNumListValid.value = isArray && isLengthGt0
}
// #endif
// #ifdef APP-ANDROID
const objListChange = (res : Map<string, Map<string, any>>) => {
const value = res['detail']!['value'] as any[]
const isArray = Array.isArray(value)
const isLengthGt0 = value.length > 0
isObjListValid.value = isArray && isLengthGt0
}
// #endif
// #ifdef APP-IOS
const objListChange = (res : any) => {
const value = res['detail']!['value'] as any[]
const isArray = Array.isArray(value)
const isLengthGt0 = value.length > 0
console.log('is array',isArray,'is length>0',isLengthGt0,'res',isArray && isLengthGt0);
isObjListValid.value = isArray && isLengthGt0
}
// #endif
const onButtonClick = () => {
// 改变 props: 观察 props 返回值为非响应式值
numList.value = [3, 2, 1]
objList.value = [{ id: '3' }, { id: '4' }]
}
const call = async () : Promise<void> => {
callMethod1()
await delay()
callMethod2()
await delay()
callMethod3()
await delay()
callMethod4()
await delay()
callMethod5()
}
onReady(() => {
call()
})
const callEasyMethod1 = ref<CallEasyMethodUniModulesComponentPublicInstance | null>(null)
const callMethod1 = () => {
// 调用组件的 foo1 方法
callEasyMethod1.value?.foo1?.()
}
const callMethod2 = () => {
// 调用组件的 foo2 方法并传递 1个参数
callEasyMethod1.value?.foo2?.(Date.now())
}
const callMethod3 = () => {
// 调用组件的 foo3 方法并传递 2个参数
callEasyMethod1.value?.foo3?.(Date.now(), Date.now())
}
const callMethod4 = () => {
// 调用组件的 foo4 方法并传递 callback
callEasyMethod1.value?.foo4?.(() => {
console.log('callback')
defineExpose({
callMethodTest,
callMethodInOtherFile,
onButtonClick
})
}
const callMethod5 = () => {
// 注意: 返回值可能为 null,当前例子一定不为空,所以加了 !
const result = callEasyMethod1.value?.foo5?.('string5') as string
console.log(result) // string1
}
const callMethodTest = (text: string): string | null => {
const result = callEasyMethod1.value?.foo5?.(text) as string
return result
}
const callMethodInOtherFile = (text: string): string => {
return testInOtherFile(callEasyMethod1.value!, text)
}
const call = async (): Promise<void> => {
callMethod1()
await delay()
callMethod2()
await delay()
callMethod3()
await delay()
callMethod4()
await delay()
callMethod5()
}
onReady(() => {
call()
})
defineExpose({
callMethodTest,
callMethodInOtherFile
})
</script>
\ No newline at end of file
</script>
pages/component-instance/methods/call-method-easycom-uni-modules-options.test.js
0 → 100644
浏览文件 @
5a0eea13
const
PAGE_PATH
=
"
/pages/component-instance/methods/call-method-easycom-uni-modules-options
"
let
page
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
PAGE_PATH
)
await
page
.
waitFor
(
'
view
'
)
})
it
(
'
callMethodTest
'
,
async
()
=>
{
// app only issue 8582
if
(
process
.
env
.
uniTestPlatformInfo
.
toLowerCase
().
startsWith
(
'
web
'
))
{
expect
(
1
).
toBe
(
1
)
return
}
// ios_simulator ios 17.0
// xcodoe 15 以下的版本环境不满足
const
platformInfo
=
process
.
env
.
uniTestPlatformInfo
.
toLocaleLowerCase
()
const
isIOS
=
process
.
env
.
uniTestPlatformInfo
.
toLowerCase
().
startsWith
(
'
ios
'
)
if
(
isIOS
&&
(
platformInfo
.
indexOf
(
'
14.
'
)
!=
-
1
||
platformInfo
.
indexOf
(
'
13.
'
)
!=
-
1
||
platformInfo
.
indexOf
(
'
12.
'
)
!=
-
1
)
)
{
expect
(
1
).
toBe
(
1
)
return
}
const
delay
=
()
=>
new
Promise
((
resolve
,
_
)
=>
{
setTimeout
(()
=>
{
resolve
(
''
)
},
1500
)
})
await
page
.
callMethod
(
'
onButtonClick
'
)
await
delay
()
const
resStr1
=
await
page
.
$
(
"
#isNumListValid
"
)
const
resStr2
=
await
page
.
$
(
"
#isObjListValid
"
)
expect
(
await
resStr1
.
text
()).
toBe
(
`true`
)
expect
(
await
resStr2
.
text
()).
toBe
(
`true`
)
})
pages/component-instance/methods/call-method-easycom-uni-modules-options.uvue
浏览文件 @
5a0eea13
<template>
<view>
<call-easy-method-uni-modules ref="callEasyMethod1"></call-easy-method-uni-modules>
<!-- #ifdef APP -->
<view>---</view>
<test-props id="btn1" :numList="numList" :objList='objList' @buttonclick='onButtonClick'
@numListChange='numListChange' @objListChange='objListChange'
style="width: 80px;height: 30px;background-color: lightblue"></test-props>
<view style="flex-direction: row ;">
<text>isNumListValid: </text>
<text id='isNumListValid'>{{isNumListValid}}</text>
</view>
<view style="flex-direction: row ;">
<text>isObjListValid: </text>
<text id='isObjListValid'>{{isObjListValid}}</text>
</view>
<!-- #endif -->
</view>
</template>
<script lang="uts">
import { testInOtherFile } from './call-method-easycom-uni-modules'
import { testInOtherFile } from './call-method-easycom-uni-modules'
const delay = ()
: Promise<string> =>
new Promise((resolve, _) => {
setTimeout(() => {
resolve('')
}, 1000)
})
const delay = ()
: Promise<string> =>
new Promise((resolve, _) => {
setTimeout(() => {
resolve('')
}, 1000)
})
export default {
data() {
return {
callEasyMethod1: null as CallEasyMethodUniModulesComponentPublicInstance | null
}
export default {
data() {
return {
callEasyMethod1: null as CallEasyMethodUniModulesComponentPublicInstance | null,
isWatched: false,
changeTimes: 0,
numList: [1] as number[], // 传递 props
objList: [] as any[],
isNumListValid: false,
isObjListValid: false
}
},
onReady() {
// 通过组件 ref 属性获取组件实例, 组件标签名首字母大写,驼峰+ComponentPublicInstance
this.callEasyMethod1 = this.$refs['callEasyMethod1'] as CallEasyMethodUniModulesComponentPublicInstance
this.call()
},
methods: {
async call() : Promise<void> {
this.callMethod1()
await delay()
this.callMethod2()
await delay()
this.callMethod3()
await delay()
this.callMethod4()
await delay()
this.callMethod5()
},
callMethod1() {
// 调用组件的 foo1 方法
this.callEasyMethod1?.foo1?.()
},
callMethod2() {
// 调用组件的 foo2 方法并传递 1个参数
this.callEasyMethod1?.foo2?.(Date.now())
},
callMethod3() {
// 调用组件的 foo3 方法并传递 2个参数
this.callEasyMethod1?.foo3?.(Date.now(), Date.now())
},
callMethod4() {
// 调用组件的 foo4 方法并传递 callback
this.callEasyMethod1?.foo4?.(() => {
console.log('callback')
})
},
callMethod5() {
// 注意: 返回值可能为 null,当前例子一定不为空,所以加了 !
const result = this.callEasyMethod1?.foo5?.('string5') as string
console.log(result) // string1
},
callMethodTest(text : string) : string | null {
const result = this.callEasyMethod1?.foo5?.(text) as string
return result
},
callMethodInOtherFile(text : string) : string {
return testInOtherFile(this.callEasyMethod1!, text)
},
// #ifdef APP-ANDROID
numListChange(res : Map<string, Map<string, any>>) {
const value = res['detail']!['value'] as number[]
const isArray = Array.isArray(value)
const isLengthGt0 = value.length > 0
this.isNumListValid = isArray && isLengthGt0
},
onReady() {
// 通过组件 ref 属性获取组件实例, 组件标签名首字母大写,驼峰+ComponentPublicInstance
this.callEasyMethod1 = this.$refs['callEasyMethod1'] as CallEasyMethodUniModulesComponentPublicInstance
// #endif
// #ifdef APP-IOS
numListChange(res : any) {
const value = res['detail']!['value'] as number[]
const isArray = Array.isArray(value)
const isLengthGt0 = value.length > 0
this.isNumListValid = isArray && isLengthGt0
},
// #endif
this.call()
// #ifdef APP-ANDROID
objListChange(res : Map<string, Map<string, any>>) {
const value = res['detail']!['value'] as number[]
const isArray = Array.isArray(value)
const isLengthGt0 = value.length > 0
this.isObjListValid = isArray && isLengthGt0
},
methods: {
async call(): Promise<void> {
this.callMethod1()
await delay()
this.callMethod2()
await delay()
this.callMethod3()
await delay()
this.callMethod4()
await delay()
this.callMethod5()
},
callMethod1() {
// 调用组件的 foo1 方法
this.callEasyMethod1?.foo1?.()
},
callMethod2() {
// 调用组件的 foo2 方法并传递 1个参数
this.callEasyMethod1?.foo2?.(Date.now())
},
callMethod3() {
// 调用组件的 foo3 方法并传递 2个参数
this.callEasyMethod1?.foo3?.(Date.now(), Date.now())
},
callMethod4() {
// 调用组件的 foo4 方法并传递 callback
this.callEasyMethod1?.foo4?.(() => {
console.log('callback')
})
},
callMethod5() {
// 注意: 返回值可能为 null,当前例子一定不为空,所以加了 !
const result = this.callEasyMethod1?.foo5?.('string5') as string
console.log(result) // string1
},
callMethodTest(text: string): string | null {
const result = this.callEasyMethod1?.foo5?.(text) as string
return result
},
callMethodInOtherFile(text: string): string {
return testInOtherFile(this.callEasyMethod1!, text)
// #endif
// #ifdef APP-IOS
objListChange(res : any) {
const value = res['detail']!['value'] as number[]
const isArray = Array.isArray(value)
const isLengthGt0 = value.length > 0
this.isObjListValid = isArray && isLengthGt0
},
// #endif
onButtonClick() {
// 改变 props: 观察 props 返回值为非响应式值
console.log('button click');
this.numList = [3, 2, 1]
this.objList = [{ id: '3' }, { id: '4' }]
}
}
}
}
</script>
\ No newline at end of file
</script>
pages/component-instance/options/options-composition.uvue
浏览文件 @
5a0eea13
...
...
@@ -24,33 +24,30 @@ defineOptions({
mixins: [mixins],
name: "$options",
_customKey: "custom key"
})
type DataInfo = {
name: string
customKey: string
mixinDataStr: string
})
type DataInfo = {
name: string
customKey: string
mixinDataStr: string
}
const dataInfo = reactive({
name: "",
customKey: "",
mixinDataStr: ""
} as DataInfo)
const dataInfo = reactive({
name: "",
customKey: "",
mixinDataStr: ""
} as DataInfo)
onMounted(() => {
const instance = getCurrentInstance()!.proxy!
// #ifdef APP-ANDROID
dataInfo.name = instance.$options.name
// #endif
// #ifndef APP-ANDROID
dataInfo.name = instance.$options.name!
// #ifndef APP-ANDROID
dataInfo.customKey = instance.$options._customKey
dataInfo.mixinDataStr = instance.$options.data!({})!['str']
// #endif
})
defineExpose({
dataInfo
})
defineExpose({
dataInfo
})
</script>
pages/component-instance/options/options-options.uvue
浏览文件 @
5a0eea13
...
...
@@ -19,12 +19,12 @@
<script lang="uts">
import mixins from "./mixins.uts"
type DataInfo = {
name: string
customKey: string
mixinDataStr: string
}
type DataInfo = {
name: string
customKey: string
mixinDataStr: string
}
export default {
mixins: [mixins],
...
...
@@ -32,20 +32,17 @@ export default {
_customKey: "custom key",
data() {
return {
dataInfo: {
name: "",
customKey: "",
mixinDataStr: "",
dataInfo: {
name: "",
customKey: "",
mixinDataStr: "",
} as DataInfo
}
},
mounted() {
// #ifdef APP-ANDROID
this.dataInfo.name = this.$options.name
// #endif
// #ifndef APP-ANDROID
this.dataInfo.name = this.$options.name!
this.dataInfo.customKey = this.$options._customKey
// #ifndef APP-ANDROID
this.dataInfo.customKey = this.$options._customKey
// @ts-ignore
this.dataInfo.mixinDataStr = this.$options.data({})['str']
// #endif
...
...
pages/component-instance/props/object-type-composition.uvue
浏览文件 @
5a0eea13
...
...
@@ -39,7 +39,7 @@ defineProps({
default: false
},
obj: {
type:
Object as PropType<UTSJSONObject>
,
type:
UTSJSONObject
,
default: (): UTSJSONObject => ({})
},
arr: {
...
...
pages/component-instance/props/object-type-options.uvue
浏览文件 @
5a0eea13
...
...
@@ -40,7 +40,7 @@
default: false
},
obj: {
type:
Object as PropType<UTSJSONObject>
,
type:
UTSJSONObject
,
default: (): UTSJSONObject => ({})
},
arr: {
...
...
pages/component-instance/setup-function/RenderFunction.uvue
浏览文件 @
5a0eea13
...
...
@@ -14,7 +14,7 @@
type: Number,
},
obj: {
type:
Object as PropType<UTSJSONObject>
,
type:
UTSJSONObject
,
}
},
emits: ['compUpdateObj'],
...
...
pages/directive/v-bind/v-bind-composition.uvue
浏览文件 @
5a0eea13
<template>
<template>
<!-- #ifdef APP -->
<scroll-view style="flex: 1">
<!-- #endif -->
<view class="page">
<!-- v-bind attribute -->
<button id="disabled-btn" class="mb-10" :disabled="true">
...
...
@@ -25,13 +28,27 @@
<Foo :title="dataInfo.fooProps.title" :num="dataInfo.fooProps.num" :obj="dataInfo.fooProps.obj" />
<!-- v-bind props -->
<Foo checked />
<Foo checked />
<!-- 绑定对象 -->
<Foo id="bindObj1" v-bind="{ title: dataInfo.fooProps.title,num: dataInfo.fooProps.num,obj: dataInfo.fooProps.obj }" />
<!-- 绑定对象合并-->
<Foo id="bindObj2" v-bind="{ title: dataInfo.fooProps.title,num: dataInfo.fooProps.num,obj: dataInfo.fooProps.obj }" title="foo title override" />
<!-- 绑定对象合并-->
<Foo id="bindObj3" title="foo" v-bind="{ title: dataInfo.fooProps.title,num: dataInfo.fooProps.num,obj: dataInfo.fooProps.obj }" />
<!-- 绑定对象合并(UTSJSONObject)-->
<Foo id="bindObj4" v-bind="fooProps" title="foo title(json) override" />
<!-- 绑定对象合并(UTSJSONObject)-->
<Foo id="bindObj5" title="foo" v-bind="fooProps" />
<!-- v-bind in style -->
<!-- #ifdef WEB -->
<view class="mb-10 v-bind-css"></view>
<!-- #endif -->
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script setup lang="uts">
...
...
@@ -60,7 +77,12 @@
},
vBindClassBackgroundColor: 'red',
vBindClassRpxHeight: '300rpx'
} as DataInfo)
} as DataInfo)
const fooProps = reactive({
title: 'foo title(json)',
num: 2,
})
defineExpose({
dataInfo
...
...
@@ -73,6 +95,5 @@
background-color: v-bind(dataInfo.vBindClassBackgroundColor);
height: v-bind(dataInfo.vBindClassRpxHeight);
}
/* #endif */
</style>
\ No newline at end of file
pages/directive/v-bind/v-bind-options.uvue
浏览文件 @
5a0eea13
<template>
<template>
<!-- #ifdef APP -->
<scroll-view style="flex: 1">
<!-- #endif -->
<view class="page">
<!-- v-bind attribute -->
<button id="disabled-btn" class="mb-10" :disabled="true">:disabled true</button>
...
...
@@ -21,13 +24,29 @@
<Foo :title="dataInfo.fooProps.title" :num="dataInfo.fooProps.num" :obj="dataInfo.fooProps.obj" />
<!-- v-bind props -->
<Foo checked />
<Foo checked />
<!-- 绑定对象 -->
<Foo v-bind="{ title: dataInfo.fooProps.title,num: dataInfo.fooProps.num,obj: dataInfo.fooProps.obj }" />
<Foo v-bind="fooProps"/>
<Foo id="bindObj1" v-bind="{ title: dataInfo.fooProps.title,num: dataInfo.fooProps.num,obj: dataInfo.fooProps.obj }" />
<!-- 绑定对象合并 v-bind 在前 -->
<Foo v-bind="{ title: dataInfo.fooProps.title,num: dataInfo.fooProps.num,obj: dataInfo.fooProps.obj }" id="bindObj2" :title="dataInfo.fooProps.title + ' override'" />
<!-- 绑定对象合并 v-bind 在后 -->
<Foo id="bindObj3" title="foo" v-bind="{ title: dataInfo.fooProps.title,num: dataInfo.fooProps.num,obj: dataInfo.fooProps.obj }" />
<!-- 绑定对象合并 v-bind 在中间(UTSJSONObject)-->
<Foo id="bindObj4" v-bind="fooProps" title="foo title(json) override" />
<!-- 绑定对象合并(UTSJSONObject)-->
<Foo id="bindObj5" title="foo" v-bind="fooProps" />
<!-- v-bind in style -->
<!-- #ifdef WEB -->
<view class="mb-10 v-bind-css"></view>
<!-- #endif -->
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script lang="uts">
...
...
@@ -60,7 +79,11 @@
},
vBindClassBackgroundColor: 'red',
vBindClassRpxHeight: '300rpx'
} as DataInfo
} as DataInfo,
fooProps:{
title: 'foo title(json)',
num: 2,
}
}
}
}
...
...
@@ -72,6 +95,5 @@
background-color: v-bind(dataInfo.vBindClassBackgroundColor);
height: v-bind(dataInfo.vBindClassRpxHeight);
}
/* #endif */
</style>
\ No newline at end of file
pages/directive/v-bind/v-bind.test.js
浏览文件 @
5a0eea13
...
...
@@ -44,8 +44,19 @@ describe('v-bind', () => {
const
fooPropsNum
=
await
page
.
$
(
'
#foo-props-num
'
)
expect
(
await
fooPropsNum
.
text
()).
toBe
(
dataInfo
.
fooProps
.
num
.
toString
())
const
fooPropsObjName
=
await
page
.
$
(
'
#foo-props-obj-name
'
)
expect
(
await
fooPropsObjName
.
text
()).
toBe
(
dataInfo
.
fooProps
.
obj
.
name
)
expect
(
await
fooPropsObjName
.
text
()).
toBe
(
dataInfo
.
fooProps
.
obj
.
name
)
const
bindObj1
=
await
page
.
$
(
'
#bindObj1
'
)
expect
(
await
(
await
bindObj1
.
$
(
'
#foo-props-title
'
)).
text
()).
toBe
(
dataInfo
.
fooProps
.
title
)
const
bindObj2
=
await
page
.
$
(
'
#bindObj2
'
)
expect
(
await
(
await
bindObj2
.
$
(
'
#foo-props-title
'
)).
text
()).
toBe
(
dataInfo
.
fooProps
.
title
+
'
override
'
)
const
bindObj3
=
await
page
.
$
(
'
#bindObj3
'
)
expect
(
await
(
await
bindObj3
.
$
(
'
#foo-props-title
'
)).
text
()).
toBe
(
dataInfo
.
fooProps
.
title
)
const
bindObj4
=
await
page
.
$
(
'
#bindObj4
'
)
expect
(
await
(
await
bindObj4
.
$
(
'
#foo-props-title
'
)).
text
()).
toBe
(
`foo title(json) override`
)
const
bindObj5
=
await
page
.
$
(
'
#bindObj5
'
)
expect
(
await
(
await
bindObj5
.
$
(
'
#foo-props-title
'
)).
text
()).
toBe
(
`foo title(json)`
)
if
(
isWeb
)
{
const
vBindCss
=
await
page
.
$
(
'
.v-bind-css
'
)
expect
(
await
vBindCss
.
style
(
'
backgroundColor
'
)).
toBe
(
'
rgb(255, 0, 0)
'
)
...
...
pages/directive/v-model/Foo-composition.uvue
浏览文件 @
5a0eea13
...
...
@@ -8,11 +8,18 @@
<text>v-model:msg in Foo:</text>
<text id="model-msg-text">{{ msg }}</text>
</view>
<view class="mb-10 flex justify-between flex-row">
<text>defineModel num:</text>
<text id="model-num-text">{{ num }}</text>
</view>
<view class="mb-10 flex justify-between flex-row">
<text>defineModel strArr:</text>
<text id="model-str-arr-text">{{ JSON.stringify(strArr) }}</text>
</view>
<view class="mb-10 flex justify-between flex-row">
<text>defineModel numArr:</text>
<text id="model-num-arr-text">{{ JSON.stringify(numArr) }}</text>
</view>
<button class="mb-10" id="update-value-btn" @click="updateValue">
update value
</button>
...
...
@@ -28,9 +35,14 @@ const msg = defineModel('msg', { type: String, default: 'default msg' })
const num = defineModel('num', { type: Number, default: 1 })
const strArr = defineModel<string[]>('strArr', { default: () => [] as string[] })
const numArr = defineModel('numArr', {type: Array as PropType<number[]>, required: true })
const updateValue = () => {
modelValue.value += '1'
msg.value += '2'
num.value++
strArr.value.push(`${strArr.value.length}`)
numArr.value.push(numArr.value.length)
}
</script>
pages/directive/v-model/v-model-composition.test.js
浏览文件 @
5a0eea13
...
...
@@ -19,18 +19,28 @@ describe('defineModel', () => {
const
modelMsgInput
=
await
page
.
$
(
'
#model-msg-input
'
)
expect
(
await
modelMsgInput
.
value
()).
toBe
(
'
msg
'
)
const
modelNumText
=
await
page
.
$
(
'
#model-num-text
'
)
expect
(
await
modelNumText
.
text
()).
toBe
(
'
1
'
)
const
modelNumText
=
await
page
.
$
(
'
#model-num-text
'
)
expect
(
await
modelNumText
.
text
()).
toBe
(
'
1
'
)
const
modelStrArrText
=
await
page
.
$
(
'
#model-str-arr-text
'
)
expect
(
await
modelStrArrText
.
text
()).
toBe
(
'
["0"]
'
)
const
modelNumArrText
=
await
page
.
$
(
'
#model-num-arr-text
'
)
expect
(
await
modelNumArrText
.
text
()).
toBe
(
'
[0]
'
)
const
updateValueBtn
=
await
page
.
$
(
'
#update-value-btn
'
)
await
updateValueBtn
.
tap
()
await
updateValueBtn
.
tap
()
expect
(
await
modelNumText
.
text
()).
toBe
(
'
2
'
)
expect
(
await
modelValueText
.
text
()).
toBe
(
'
str1
'
)
expect
(
await
modelValueInput
.
value
()).
toBe
(
'
str1
'
)
expect
(
await
modelMsgText
.
text
()).
toBe
(
'
msg2
'
)
expect
(
await
modelMsgInput
.
value
()).
toBe
(
'
msg2
'
)
expect
(
await
modelMsgInput
.
value
()).
toBe
(
'
msg2
'
)
expect
(
await
modelStrArrText
.
text
()).
toBe
(
'
["0","1"]
'
)
expect
(
await
modelNumArrText
.
text
()).
toBe
(
'
[0,1]
'
)
const
handleModelValueUpdateRes
=
await
page
.
$
(
'
#handle-model-value-update-res
'
)
expect
(
await
handleModelValueUpdateRes
.
text
()).
toBe
(
'
str1
'
)
...
...
pages/directive/v-model/v-model-composition.uvue
浏览文件 @
5a0eea13
...
...
@@ -3,8 +3,11 @@
<Foo
v-model="str"
v-model:msg="msg"
v-model:strArr="strArr"
v-model:numArr="numArr"
@update:modelValue="handleModelValueUpdate"
@update:msg="handleModelMsgUpdate" />
@update:msg="handleModelMsgUpdate"
/>
<input class="mb-10 input" id="model-value-input" v-model="str" />
<input class="mb-10 input" id="model-msg-input" v-model="msg" />
<view class="mb-10 flex justify-between flex-row">
...
...
@@ -23,6 +26,8 @@ import Foo from './Foo-composition.uvue'
const str = ref('str')
const msg = ref('msg')
const strArr = ref<string[]>(['0'])
const numArr = ref<number[]>([0])
const handleModelValueUpdateRes = ref('')
const handleModelValueUpdate = (val : string) => {
...
...
pages/directive/v-show/Foo.uvue
0 → 100644
浏览文件 @
5a0eea13
<template>
<view id="foo">
component Foo
</view>
</template>
pages/directive/v-show/v-show-composition.uvue
浏览文件 @
5a0eea13
<template>
<view class="page">
<button id="toggle-btn" @click="toggleShow">toggle show/hide</button>
<view class="mt-10" id="v-show-element" v-show="dataInfo.show">
点击上方按钮,切换显示/隐藏
</view>
</view>
</template>
<script setup lang="uts">
type DataInfo = {
show: boolean
}
const dataInfo = reactive({
show: true
} as DataInfo)
const toggleShow = () => {
dataInfo.show = !dataInfo.show
}
defineExpose({
dataInfo
})
</script>
<template>
<view class="page">
<button id="toggle-btn" @click="toggleShow">toggle show/hide</button>
<text>点击上方按钮,切换下方 view 显示/隐藏</text>
<text>show default true: {{dataInfo.showDefaultTrue}}</text>
<view class="mt-10 default-true" id="v-show-element-default-true" v-show="dataInfo.showDefaultTrue"></view>
<text>show default false: {{dataInfo.showDefaultFalse}}</text>
<view class="mt-10 default-false" id="v-show-element-default-false" v-show="dataInfo.showDefaultFalse"></view>
<Foo v-show="dataInfo.showDefaultFalse" />
</view>
</template>
<script setup lang="uts">
import Foo from './Foo.uvue'
type DataInfo = {
showDefaultTrue : boolean
showDefaultFalse : boolean
}
const dataInfo = reactive({
showDefaultTrue: true,
showDefaultFalse: false
} as DataInfo)
const toggleShow = () => {
dataInfo.showDefaultTrue = !dataInfo.showDefaultTrue
dataInfo.showDefaultFalse = !dataInfo.showDefaultFalse
}
defineExpose({
dataInfo
})
</script>
<style>
.default-true,
.default-false {
display: flex;
width: 100px;
height: 50px;
}
.default-true {
background-color: greenyellow;
}
.default-false {
background-color: antiquewhite;
}
</style>
\ No newline at end of file
pages/directive/v-show/v-show-options.uvue
浏览文件 @
5a0eea13
<template>
<view class="page">
<button id="toggle-btn" @click="toggleShow">toggle show/hide</button>
<view class="mt-10" id="v-show-element" v-show="dataInfo.show">
点击上方按钮,切换显示/隐藏
</view>
</view>
</template>
<script lang="uts">
type DataInfo = {
show: boolean
}
export default {
data() {
return {
dataInfo: {
show: true
} as DataInfo
}
},
methods: {
toggleShow() {
this.dataInfo.show = !this.dataInfo.show
}
}
}
</script>
<template>
<view class="page">
<button id="toggle-btn" @click="toggleShow">toggle show/hide</button>
<text>点击上方按钮,切换下方 view 显示/隐藏</text>
<text>show default true: {{dataInfo.showDefaultTrue}}</text>
<view class="mt-10 default-true" id="v-show-element-default-true" v-show="dataInfo.showDefaultTrue"></view>
<text>show default false: {{dataInfo.showDefaultFalse}}</text>
<view class="mt-10 default-false" id="v-show-element-default-false" v-show="dataInfo.showDefaultFalse"></view>
<Foo v-show="dataInfo.showDefaultFalse" />
</view>
</template>
<script lang="uts">
import Foo from './Foo.uvue'
type DataInfo = {
showDefaultTrue : boolean
showDefaultFalse : boolean
}
export default {
components: { Foo },
data() {
return {
dataInfo: {
showDefaultTrue: true,
showDefaultFalse: false
} as DataInfo
}
},
methods: {
toggleShow() {
this.dataInfo.showDefaultTrue = !this.dataInfo.showDefaultTrue
this.dataInfo.showDefaultFalse = !this.dataInfo.showDefaultFalse
}
}
}
</script>
<style>
.default-true,
.default-false {
display: flex;
width: 100px;
height: 50px;
}
.default-true {
background-color: greenyellow;
}
.default-false {
background-color: antiquewhite;
}
</style>
\ No newline at end of file
pages/directive/v-show/v-show.test.js
浏览文件 @
5a0eea13
...
...
@@ -6,23 +6,33 @@ describe('v-show', () => {
const
test
=
async
(
page
)
=>
{
let
dataInfo
=
await
page
.
data
(
'
dataInfo
'
)
expect
(
dataInfo
.
show
).
toBe
(
true
)
const
vShowElement
=
await
page
.
$
(
'
#v-show-element
'
)
expect
(
await
vShowElement
.
style
(
'
display
'
)).
toBe
(
'
flex
'
)
expect
(
dataInfo
.
showDefaultTrue
).
toBe
(
true
)
expect
(
dataInfo
.
showDefaultFalse
).
toBe
(
false
)
const
vShowElementDefaultTrue
=
await
page
.
$
(
'
#v-show-element-default-true
'
)
expect
(
await
vShowElementDefaultTrue
.
style
(
'
display
'
)).
toBe
(
'
flex
'
)
const
vShowElementDefaultFalse
=
await
page
.
$
(
'
#v-show-element-default-false
'
)
expect
(
await
vShowElementDefaultFalse
.
style
(
'
display
'
)).
toBe
(
'
none
'
)
const
foo
=
await
page
.
$
(
'
#foo
'
)
expect
(
await
foo
.
style
(
'
display
'
)).
toBe
(
'
none
'
)
const
toggle
=
await
page
.
$
(
'
#toggle-btn
'
)
await
toggle
.
tap
()
dataInfo
=
await
page
.
data
(
'
dataInfo
'
)
expect
(
dataInfo
.
show
).
toBe
(
false
)
expect
(
await
vShowElement
.
style
(
'
display
'
)).
toBe
(
'
none
'
)
expect
(
dataInfo
.
showDefaultTrue
).
toBe
(
false
)
expect
(
dataInfo
.
showDefaultFalse
).
toBe
(
true
)
expect
(
await
vShowElementDefaultTrue
.
style
(
'
display
'
)).
toBe
(
'
none
'
)
expect
(
await
vShowElementDefaultFalse
.
style
(
'
display
'
)).
toBe
(
'
flex
'
)
expect
(
await
foo
.
style
(
'
display
'
)).
toBe
(
'
flex
'
)
await
toggle
.
tap
()
dataInfo
=
await
page
.
data
(
'
dataInfo
'
)
expect
(
dataInfo
.
show
).
toBe
(
true
)
expect
(
await
vShowElement
.
style
(
'
display
'
)).
toBe
(
'
flex
'
)
expect
(
dataInfo
.
showDefaultTrue
).
toBe
(
true
)
expect
(
dataInfo
.
showDefaultFalse
).
toBe
(
false
)
expect
(
await
vShowElementDefaultTrue
.
style
(
'
display
'
)).
toBe
(
'
flex
'
)
expect
(
await
vShowElementDefaultFalse
.
style
(
'
display
'
)).
toBe
(
'
none
'
)
expect
(
await
foo
.
style
(
'
display
'
)).
toBe
(
'
none
'
)
}
it
(
'
v-show options API
'
,
async
()
=>
{
...
...
pages/error/throw-error/throw-error-composition.uvue
浏览文件 @
5a0eea13
<template>
<view class="page">
<button id="trigger-error" @click="triggerError">trigger error</button>
<button class='mt-10' id="trigger-timeout-error" @click="triggerTimeoutError">trigger timeout error</button>
</view>
</template>
<script setup lang="uts">
import { state } from '@/store/index.uts'
import { state } from '@/store/index.uts'
onReady(() => {
throw new Error('error in error composition page onReady')
})
const triggerError = () => {
throw new Error('trigger error in throw error composition page')
}
const triggerTimeoutError = () => {
setTimeout(() => {
throw new Error('setTimeout trigger error in throw error composition page')
}, 10)
}
// 自动化测试
const getLifeCycleNum = () : number => {
...
...
pages/error/throw-error/throw-error-options.uvue
浏览文件 @
5a0eea13
<template>
<view class="page">
<button id="trigger-error" @click="triggerError">trigger error</button>
</view>
</template>
<script lang="uts">
import { state } from '@/store/index.uts'
export default {
onReady(){
throw new Error('error in error options page onReady')
},
methods: {
triggerError(){
throw new Error('trigger error in throw error options page')
},
// 自动化测试
getLifeCycleNum() : number {
return state.lifeCycleNum
}
},
}
</script>
<template>
<view class="page">
<button id="trigger-error" @click="triggerError">trigger error</button>
<button class='mt-10' id="trigger-timeout-error" @click="triggerTimeoutError">trigger timeout error</button>
</view>
</template>
<script lang="uts">
import { state } from '@/store/index.uts'
export default {
onReady() {
throw new Error('error in error options page onReady')
},
methods: {
triggerError() {
throw new Error('trigger error in throw error options page')
},
triggerTimeoutError() {
setTimeout(() => {
throw new Error('setTimeout trigger error in throw error options page')
}, 10)
},
// 自动化测试
getLifeCycleNum() : number {
return state.lifeCycleNum
}
},
}
</script>
\ No newline at end of file
pages/error/throw-error/throw-error.test.js
浏览文件 @
5a0eea13
const
OPTIONS_PAGE_PATH
=
'
/pages/error/throw-error/throw-error-options
'
const
COMPOSITION_PAGE_PATH
=
'
/pages/error/throw-error/throw-error-composition
'
const
HOME_PAGE_PATH
=
'
/pages/index/index
'
describe
(
'
throw error
'
,
()
=>
{
let
page
let
lifeCycleNum
const
initLifecycle
=
async
()
=>
{
page
=
await
program
.
reLaunch
(
HOME_PAGE_PATH
)
await
page
.
waitFor
(
'
view
'
)
await
page
.
callMethod
(
'
setLifeCycleNum
'
,
0
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
0
)
}
const
test
=
async
(
pagePath
)
=>
{
await
initLifecycle
()
page
=
await
program
.
reLaunch
(
pagePath
)
await
page
.
waitFor
(
'
view
'
)
expect
(
page
.
path
).
toBe
(
pagePath
.
substring
(
1
))
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
100
)
const
triggerErrorBtn
=
await
page
.
$
(
'
#trigger-error
'
)
await
triggerErrorBtn
.
tap
()
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
200
)
page
=
await
program
.
navigateTo
(
HOME_PAGE_PATH
)
await
page
.
waitFor
(
'
view
'
)
expect
(
page
.
path
).
toBe
(
HOME_PAGE_PATH
.
substring
(
1
))
}
it
(
'
onError options API
'
,
async
()
=>
{
await
test
(
OPTIONS_PAGE_PATH
)
})
it
(
'
onError composition API
'
,
async
()
=>
{
await
test
(
COMPOSITION_PAGE_PATH
)
})
afterAll
(
async
()
=>
{
const
resetLifecycleNum
=
1100
await
page
.
callMethod
(
'
setLifeCycleNum
'
,
resetLifecycleNum
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
resetLifecycleNum
)
})
})
const
platformInfo
=
process
.
env
.
uniTestPlatformInfo
.
toLocaleLowerCase
()
const
isAndroid
=
platformInfo
.
includes
(
'
android
'
)
const
isIos
=
platformInfo
.
includes
(
'
ios
'
)
const
OPTIONS_PAGE_PATH
=
'
/pages/error/throw-error/throw-error-options
'
const
COMPOSITION_PAGE_PATH
=
'
/pages/error/throw-error/throw-error-composition
'
const
HOME_PAGE_PATH
=
'
/pages/index/index
'
describe
(
'
throw error
'
,
()
=>
{
let
page
let
lifeCycleNum
const
initLifecycle
=
async
()
=>
{
page
=
await
program
.
reLaunch
(
HOME_PAGE_PATH
)
await
page
.
waitFor
(
'
view
'
)
await
page
.
callMethod
(
'
setLifeCycleNum
'
,
0
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
0
)
}
const
test
=
async
(
pagePath
)
=>
{
await
initLifecycle
()
page
=
await
program
.
reLaunch
(
pagePath
)
await
page
.
waitFor
(
'
view
'
)
expect
(
page
.
path
).
toBe
(
pagePath
.
substring
(
1
))
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
100
)
const
triggerErrorBtn
=
await
page
.
$
(
'
#trigger-error
'
)
await
triggerErrorBtn
.
tap
()
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
200
)
if
(
isAndroid
||
isIos
)
{
const
triggerTimeoutErrorBtn
=
await
page
.
$
(
'
#trigger-timeout-error
'
)
await
triggerTimeoutErrorBtn
.
tap
()
await
page
.
waitFor
(
500
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
300
)
}
page
=
await
program
.
navigateTo
(
HOME_PAGE_PATH
)
await
page
.
waitFor
(
'
view
'
)
expect
(
page
.
path
).
toBe
(
HOME_PAGE_PATH
.
substring
(
1
))
}
it
(
'
onError options API
'
,
async
()
=>
{
await
test
(
OPTIONS_PAGE_PATH
)
})
it
(
'
onError composition API
'
,
async
()
=>
{
await
test
(
COMPOSITION_PAGE_PATH
)
})
afterAll
(
async
()
=>
{
const
resetLifecycleNum
=
1110
await
page
.
callMethod
(
'
setLifeCycleNum
'
,
resetLifecycleNum
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
resetLifecycleNum
)
})
})
\ No newline at end of file
pages/index/index.uvue
浏览文件 @
5a0eea13
...
...
@@ -647,8 +647,8 @@ export default {
{
id: 'directive',
name: '指令',
pages: [
// #ifndef APP-IOS
pages: [
// #ifndef APP-IOS
{
id: 'v-html',
name: 'v-html',
...
...
@@ -664,7 +664,7 @@ export default {
url: 'v-html-composition'
},
]
},
},
// #endif
{
id: 'v-show',
...
...
@@ -1227,13 +1227,13 @@ export default {
// 自动化测试
checkLaunchPath() : boolean {
const app = getApp()
return app.checkLaunchPath()
return app.
vm!.
checkLaunchPath()
},
// #ifndef APP-ANDROID
// 自动化测试
checkAppMixin() : boolean {
const app = getApp()
return app.checkAppMixin()
return app.
vm.
checkAppMixin()
}
// #endif
}
...
...
pages/lifecycle/component/ChildComponentComposition.uvue
浏览文件 @
5a0eea13
...
...
@@ -57,7 +57,7 @@ onUnload(() => {
onBeforeMount(() => {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
console.log('component for lifecycle test
mounted
')
console.log('component for lifecycle test
onBeforeMount
')
})
onMounted(() => {
...
...
@@ -90,10 +90,16 @@ onUnmounted(() => {
console.log('component for lifecycle test unmounted')
})
// TODO: app-android 不触发
onActivated(() => { })
// TODO: app-android 不触发
onDeactivated(() => { })
onActivated(() => {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
console.log('component for lifecycle test onActivated')
})
onDeactivated(() => {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 1)
console.log('component for lifecycle test onDeactivated')
})
const updateTitle = () => {
title.value = 'component for lifecycle test updated'
...
...
pages/lifecycle/component/ChildComponentOptions.uvue
浏览文件 @
5a0eea13
...
...
@@ -54,6 +54,16 @@
setLifeCycleNum(state.lifeCycleNum - 1);
console.log('component for lifecycle test unmounted');
},
activated() {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1);
console.log('component for lifecycle test activated');
},
deactivated() {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 1);
console.log('component for lifecycle test deactivated');
},
methods: {
updateTitle() {
this.title = 'component for lifecycle test updated';
...
...
pages/lifecycle/component/component-composition.test.js
浏览文件 @
5a0eea13
...
...
@@ -4,6 +4,9 @@ const HOME_PATH = '/pages/index/index'
describe
(
'
component-lifecycle
'
,
()
=>
{
let
page
let
lifeCycleNum
const
platformInfo
=
process
.
env
.
uniTestPlatformInfo
.
toLocaleLowerCase
()
const
isAndroid
=
platformInfo
.
includes
(
'
android
'
)
const
isIos
=
platformInfo
.
includes
(
'
ios
'
)
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
HOME_PATH
)
await
page
.
waitFor
(
700
)
...
...
@@ -16,15 +19,29 @@ describe('component-lifecycle', () => {
await
page
.
waitFor
(
700
)
})
afterAll
(
async
()
=>
{
const
resetLifecycleNum
=
11
0
0
const
resetLifecycleNum
=
11
1
0
await
page
.
callMethod
(
'
setLifeCycleNum
'
,
resetLifecycleNum
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
resetLifecycleNum
)
})
it
(
'
onLoad onPageShow onReady onBeforeMount onMounted
'
,
async
()
=>
{
it
(
'
onLoad onPageShow onReady onBeforeMount onMounted onActivated
'
,
async
()
=>
{
lifeCycleNum
=
await
page
.
callMethod
(
'
pageGetLifeCycleNum
'
)
// TODO: android 组合式 API 不触发 onActivated
expect
(
lifeCycleNum
).
toBe
(
isAndroid
?
112
:
113
)
})
it
(
'
onDeactivated
'
,
async
()
=>
{
// TODO: android 组合式 API 不触发 onActivated onDeactivated
const
toggleAliveComponentBtn
=
await
page
.
$
(
'
#toggle-alive-component-btn
'
)
await
toggleAliveComponentBtn
.
tap
()
lifeCycleNum
=
await
page
.
callMethod
(
'
pageGetLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
112
)
await
toggleAliveComponentBtn
.
tap
()
lifeCycleNum
=
await
page
.
callMethod
(
'
pageGetLifeCycleNum
'
)
// TODO: android 端 组合式 API 不触发 activated
expect
(
lifeCycleNum
).
toBe
(
isAndroid
?
112
:
113
)
await
page
.
callMethod
(
'
pageSetLifeCycleNum
'
,
0
)
})
it
(
'
onBeforeUpdate onUpdated
'
,
async
()
=>
{
...
...
@@ -56,17 +73,18 @@ describe('component-lifecycle', () => {
page
=
await
program
.
navigateTo
(
HOME_PATH
)
await
page
.
waitFor
(
'
view
'
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
-
10
)
// App 端页面离开返回不触发 keepAlive 组件 activated deactivated, 详见 https://issues.dcloud.net.cn/pages/issues/detail?id=7419
expect
(
lifeCycleNum
).
toBe
(
isIos
||
isAndroid
?
-
10
:
-
11
)
page
=
await
program
.
navigateBack
()
await
page
.
waitFor
(
'
view
'
)
lifeCycleNum
=
await
page
.
callMethod
(
'
pageGetLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
0
)
await
page
.
callMethod
(
'
pageSetLifeCycleNum
'
,
0
)
})
it
(
'
beforeUnmount unmounted onUnload onBackPress
'
,
async
()
=>
{
it
(
'
onDeactivated
beforeUnmount unmounted onUnload onBackPress
'
,
async
()
=>
{
page
=
await
program
.
navigateBack
()
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
-
112
)
// TODO: android 组合式 API 不触发 onDeactivated
expect
(
lifeCycleNum
).
toBe
(
isAndroid
?
-
112
:
-
113
)
await
page
.
callMethod
(
'
setLifeCycleNum
'
,
0
)
})
})
\ No newline at end of file
pages/lifecycle/component/component-composition.uvue
浏览文件 @
5a0eea13
...
...
@@ -4,8 +4,12 @@
<!-- #endif -->
<view class="page container">
<text class="mb-10">component lifecycle 组合式 API</text>
<child-component @updateIsScroll="updateIsScroll" />
<button class="mt-10" @click="scrollToBottom">scrollToBottom</button>
<keep-alive>
<component :is="aliveComponent" @updateIsScroll="updateIsScroll" />
</keep-alive>
<button class="mt-10" @click="scrollToBottom">scrollToBottom</button>
<button id="toggle-alive-component-btn" class="mt-10" @click="toggleAliveComponent">toggle alive component</button>
<button class="mt-10" @click="navigateToHome">navigateTo home</button>
</view>
<!-- #ifdef APP -->
</scroll-view>
...
...
@@ -16,6 +20,8 @@
import ChildComponent from './ChildComponentComposition.uvue'
import { state, setLifeCycleNum } from '@/store/index.uts'
const aliveComponent = shallowRef<any | null>(ChildComponent)
const isScrolled = ref(false)
// 自动化测试
...
...
@@ -24,7 +30,7 @@
}
// 自动化测试
const pageSetLifeCycleNum = (num : number) => {
const pageSetLifeCycleNum = (num : number) => {
setLifeCycleNum(num)
}
...
...
@@ -44,6 +50,10 @@
scrollTop: 3000,
})
}
const toggleAliveComponent = () => {
aliveComponent.value = aliveComponent.value == null ? ChildComponent : null
}
const updateIsScroll = (val : boolean) => {
isScrolled.value = val
...
...
@@ -52,6 +62,12 @@
// 自动化测试
const getIsScrolled = () : boolean => {
return isScrolled.value
}
const navigateToHome = () => {
uni.navigateTo({
url: '/pages/index/index'
})
}
defineExpose({
...
...
pages/lifecycle/component/component-options.test.js
浏览文件 @
5a0eea13
...
...
@@ -2,39 +2,48 @@ const PAGE_PATH = '/pages/lifecycle/component/component-options'
const
HOME_PATH
=
'
/pages/index/index
'
describe
(
'
component-lifecycle
'
,
()
=>
{
let
page
let
lifeCycleNum
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
HOME_PATH
)
await
page
.
waitFor
(
700
)
const
initLifecycleNum
=
0
await
page
.
callMethod
(
'
setLifeCycleNum
'
,
initLifecycleNum
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
initLifecycleNum
)
let
page
let
lifeCycleNum
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
HOME_PATH
)
await
page
.
waitFor
(
700
)
const
initLifecycleNum
=
0
await
page
.
callMethod
(
'
setLifeCycleNum
'
,
initLifecycleNum
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
initLifecycleNum
)
page
=
await
program
.
navigateTo
(
PAGE_PATH
)
await
page
.
waitFor
(
700
)
})
afterAll
(
async
()
=>
{
const
resetLifecycleNum
=
110
0
await
page
.
callMethod
(
'
setLifeCycleNum
'
,
resetLifecycleNum
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
resetLifecycleNum
)
})
page
=
await
program
.
navigateTo
(
PAGE_PATH
)
await
page
.
waitFor
(
700
)
})
afterAll
(
async
()
=>
{
const
resetLifecycleNum
=
111
0
await
page
.
callMethod
(
'
setLifeCycleNum
'
,
resetLifecycleNum
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
resetLifecycleNum
)
})
it
(
'
beforeCreate created beforeMount mounted
'
,
async
()
=>
{
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
4
)
})
it
(
'
beforeUpdate updated
'
,
async
()
=>
{
const
updateTitleBtn
=
await
page
.
$
(
'
.component-lifecycle-btn
'
)
await
updateTitleBtn
.
tap
()
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
6
)
})
it
(
'
beforeUnmount unmounted
'
,
async
()
=>
{
page
=
await
program
.
navigateBack
()
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
4
)
})
it
(
'
beforeCreate created beforeMount mounted activated
'
,
async
()
=>
{
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
5
)
})
it
(
'
deactivated
'
,
async
()
=>
{
const
toggleAliveComponentBtn
=
await
page
.
$
(
'
#toggle-alive-component-btn
'
)
await
toggleAliveComponentBtn
.
tap
()
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
4
)
await
toggleAliveComponentBtn
.
tap
()
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
5
)
})
it
(
'
beforeUpdate updated
'
,
async
()
=>
{
const
updateTitleBtn
=
await
page
.
$
(
'
.component-lifecycle-btn
'
)
await
updateTitleBtn
.
tap
()
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
7
)
})
it
(
'
deactivated beforeUnmount unmounted
'
,
async
()
=>
{
page
=
await
program
.
navigateBack
()
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
4
)
})
})
\ No newline at end of file
pages/lifecycle/component/component-options.uvue
浏览文件 @
5a0eea13
<template>
<view class="page">
<text class="mb-10">component lifecycle 选项式 API</text>
<child-component />
<keep-alive>
<component :is="aliveComponent" />
</keep-alive>
<button id="toggle-alive-component-btn" class="mt-10" @click="toggleAliveComponent">toggle alive component</button>
<button class="mt-10" @click="navigateToHome">navigateTo home</button>
</view>
</template>
...
...
@@ -11,11 +15,24 @@ import { state } from '@/store/index.uts'
export default {
components: { ChildComponent },
data(){
return {
aliveComponent: ChildComponent as any | null,
}
},
methods: {
// 自动化测试
getLifeCycleNum(): number {
return state.lifeCycleNum
},
toggleAliveComponent(){
this.aliveComponent = this.aliveComponent == null ? ChildComponent : null
},
navigateToHome() {
uni.navigateTo({
url: '/pages/index/index'
})
}
},
}
</script>
pages/lifecycle/page/page.test.js
浏览文件 @
5a0eea13
...
...
@@ -15,7 +15,7 @@ const initLifecycle = async () => {
}
const
testPageLifecycle
=
async
(
pagePath
)
=>
{
// onLoad onShow onReady onResize
page
=
await
program
.
reLaunch
(
pagePath
)
page
=
await
program
.
reLaunch
(
pagePath
)
await
page
.
waitFor
(
1000
)
lifeCycleNum
=
await
page
.
callMethod
(
'
pageGetLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
120
)
...
...
@@ -60,7 +60,7 @@ const testPageLifecycle = async (pagePath) => {
await
page
.
waitFor
(
700
)
lifeCycleNum
=
await
page
.
callMethod
(
'
pageGetLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
120
)
page
=
await
program
.
navigateBack
()
page
=
await
program
.
navigateBack
()
await
page
.
waitFor
(
'
view
'
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
10
)
...
...
@@ -72,21 +72,21 @@ describe('app-lifecycle', () => {
page
=
await
program
.
reLaunch
(
HOME_PATH
)
await
page
.
waitFor
(
700
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
11
0
0
)
expect
(
lifeCycleNum
).
toBe
(
11
1
0
)
})
it
(
'
onLastPageBackPress
'
,
async
()
=>
{
it
(
'
onLastPageBackPress
'
,
async
()
=>
{
if
(
process
.
env
.
uniTestPlatformInfo
.
startsWith
(
'
android
'
))
{
page
=
await
program
.
navigateBack
()
await
page
.
waitFor
(
700
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
1
0
0
)
expect
(
lifeCycleNum
).
toBe
(
1
1
0
)
}
})
})
describe
(
'
page-lifecycle
'
,
()
=>
{
it
(
'
page-lifecycle options API
'
,
async
()
=>
{
await
initLifecycle
()
it
(
'
page-lifecycle options API
'
,
async
()
=>
{
await
initLifecycle
()
await
testPageLifecycle
(
OPTIONS_PAGE_PATH
)
})
...
...
@@ -96,7 +96,7 @@ describe('page-lifecycle', () => {
})
afterAll
(
async
()
=>
{
const
resetLifecycleNum
=
11
0
0
const
resetLifecycleNum
=
11
1
0
await
page
.
callMethod
(
'
setLifeCycleNum
'
,
resetLifecycleNum
)
lifeCycleNum
=
await
page
.
callMethod
(
'
getLifeCycleNum
'
)
expect
(
lifeCycleNum
).
toBe
(
resetLifecycleNum
)
...
...
pages/reactivity/core/reactive/reactive.test.js
浏览文件 @
5a0eea13
const
PAGE_PATH
=
'
/pages/reactivity/core/reactive/reactive
'
describe
(
'
reactive
'
,
()
=>
{
let
page
=
null
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
PAGE_PATH
)
await
page
.
waitFor
(
'
view
'
)
})
it
(
'
basic
'
,
async
()
=>
{
const
count
=
await
page
.
$
(
'
#count
'
)
expect
(
await
count
.
text
()).
toBe
(
'
0
'
)
const
objStr
=
await
page
.
$
(
'
#obj-str
'
)
expect
(
await
objStr
.
text
()).
toBe
(
'
default str
'
)
const
objNum
=
await
page
.
$
(
'
#obj-num
'
)
expect
(
await
objNum
.
text
()).
toBe
(
'
0
'
)
const
objArr
=
await
page
.
$
(
'
#obj-arr
'
)
expect
(
await
objArr
.
text
()).
toBe
(
'
["a","b","c"]
'
)
const
updateCountBtn
=
await
page
.
$
(
'
#update-count-btn
'
)
await
updateCountBtn
.
tap
()
expect
(
await
count
.
text
()).
toBe
(
'
1
'
)
const
updateObjStrBtn
=
await
page
.
$
(
'
#update-obj-str-btn
'
)
await
updateObjStrBtn
.
tap
()
expect
(
await
objStr
.
text
()).
toBe
(
'
new str
'
)
const
updateObjNumBtn
=
await
page
.
$
(
'
#update-obj-num-btn
'
)
await
updateObjNumBtn
.
tap
()
expect
(
await
count
.
text
()).
toBe
(
'
2
'
)
expect
(
await
objNum
.
text
()).
toBe
(
'
2
'
)
const
updateObjArrBtn
=
await
page
.
$
(
'
#update-obj-arr-btn
'
)
await
updateObjArrBtn
.
tap
()
expect
(
await
objArr
.
text
()).
toBe
(
'
["a","b","c","d"]
'
)
})
let
page
=
null
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
PAGE_PATH
)
await
page
.
waitFor
(
'
view
'
)
})
it
(
'
basic
'
,
async
()
=>
{
const
count
=
await
page
.
$
(
'
#count
'
)
expect
(
await
count
.
text
()).
toBe
(
'
0
'
)
const
objStr
=
await
page
.
$
(
'
#obj-str
'
)
expect
(
await
objStr
.
text
()).
toBe
(
'
default str
'
)
const
objNum
=
await
page
.
$
(
'
#obj-num
'
)
expect
(
await
objNum
.
text
()).
toBe
(
'
0
'
)
const
objArr
=
await
page
.
$
(
'
#obj-arr
'
)
expect
(
await
objArr
.
text
()).
toBe
(
'
["a","b","c"]
'
)
const
arr1
=
await
page
.
$
(
'
#arr1
'
)
expect
(
await
arr1
.
text
()).
toBe
(
'
[]
'
)
const
updateCountBtn
=
await
page
.
$
(
'
#update-count-btn
'
)
await
updateCountBtn
.
tap
()
expect
(
await
count
.
text
()).
toBe
(
'
1
'
)
const
updateObjStrBtn
=
await
page
.
$
(
'
#update-obj-str-btn
'
)
await
updateObjStrBtn
.
tap
()
expect
(
await
objStr
.
text
()).
toBe
(
'
new str
'
)
const
updateObjNumBtn
=
await
page
.
$
(
'
#update-obj-num-btn
'
)
await
updateObjNumBtn
.
tap
()
expect
(
await
count
.
text
()).
toBe
(
'
2
'
)
expect
(
await
objNum
.
text
()).
toBe
(
'
2
'
)
const
updateObjArrBtn
=
await
page
.
$
(
'
#update-obj-arr-btn
'
)
await
updateObjArrBtn
.
tap
()
expect
(
await
objArr
.
text
()).
toBe
(
'
["a","b","c","d"]
'
)
const
count1
=
await
page
.
$
(
'
#count1
'
)
expect
(
await
count1
.
text
()).
toBe
(
'
1
'
)
const
updateObj_A_B_C_Btn
=
await
page
.
$
(
'
#update-obj1-a-b-c-btn
'
)
await
updateObj_A_B_C_Btn
.
tap
()
expect
(
await
count1
.
text
()).
toBe
(
'
2
'
)
const
updateArr1Btn
=
await
page
.
$
(
'
#update-arr1-btn
'
)
await
updateArr1Btn
.
tap
()
expect
(
await
arr1
.
text
()).
toBe
(
JSON
.
stringify
([
1
,
2
,
3
]))
const
updateArr1ReactiveBtn
=
await
page
.
$
(
'
#update-arr1-reactive-btn
'
)
await
updateArr1ReactiveBtn
.
tap
()
expect
(
await
arr1
.
text
()).
toBe
(
JSON
.
stringify
([
4
,
5
,
6
]))
})
})
\ No newline at end of file
pages/reactivity/core/reactive/reactive.uvue
浏览文件 @
5a0eea13
<template>
<view class="page">
<view class="flex justify-between flex-row mb-10">
<text>count:</text>
<text id="count">{{ count }}</text>
<view class="page">
<view class="flex justify-between flex-row mb-10">
<text>count:</text>
<text id="count">{{ count }}</text>
</view>
<view class="flex justify-between flex-row mb-10">
<text>obj.str:</text>
<text id="obj-str">{{ obj['str'] }}</text>
</view>
<view class="flex justify-between flex-row mb-10">
<text>obj.num:</text>
<text id="obj-num">{{ obj['num'] }}</text>
</view>
<view class="flex justify-between flex-row mb-10">
<text>obj.arr:</text>
<text id="obj-arr">{{ JSON.stringify(obj['arr']) }}</text>
</view>
<view class="flex justify-between flex-row mb-10">
<text>count1:</text>
<text id="count1">{{ count1 }}</text>
</view>
<view class="flex justify-between flex-row mb-10">
<text>obj1.a.b.c:</text>
<text id="obj1-a-b-c">{{ obj1.getString('a.b.c') }}</text>
</view>
<view class="flex justify-between flex-row mb-10">
<text>arr1(spread):</text>
<text id="arr1">{{ JSON.stringify(arr1) }}</text>
</view>
<button class='mb-10' id="update-count-btn" @click="updateCount">update count</button>
<button class='mb-10' id="update-obj-str-btn" @click="updateObjStr">update obj.str</button>
<button class='mb-10' id="update-obj-num-btn" @click="updateObjNum">update obj.num</button>
<button class='mb-10' id="update-obj-arr-btn" @click="updateObjArr">update obj.arr</button>
<button class='mb-10' id="update-obj1-a-b-c-btn" @click="updateObj1_A_B_C">update obj1.a.b.c</button>
<button class='mb-10' id="update-arr1-btn" @click="updateArr1(false)">update arr1 without reactive</button>
<button class='mb-10' id="update-arr1-reactive-btn" @click="updateArr1(true)">update arr1 with reactive</button>
</view>
<view class="flex justify-between flex-row mb-10">
<text>obj.str:</text>
<text id="obj-str">{{ obj['str'] }}</text>
</view>
<view class="flex justify-between flex-row mb-10">
<text>obj.num:</text>
<text id="obj-num">{{ obj['num'] }}</text>
</view>
<view class="flex justify-between flex-row mb-10">
<text>obj.arr:</text>
<text id="obj-arr">{{ JSON.stringify(obj['arr']) }}</text>
</view>
<button class='mb-10' id="update-count-btn" @click="updateCount">update count</button>
<button class='mb-10' id="update-obj-str-btn" @click="updateObjStr">update obj.str</button>
<button class='mb-10' id="update-obj-num-btn" @click="updateObjNum">update obj.num</button>
<button class='mb-10' id="update-obj-arr-btn" @click="updateObjArr">update obj.arr</button>
</view>
</template>
<script setup lang="uts">
const count = ref(0)
// TODO: 待支持后补充泛型示例
const obj = reactive({
str: 'default str',
num: count,
arr: ['a', 'b', 'c']
})
const updateObjStr = () => {
obj['str'] = 'new str';
}
const updateObjNum = () => {
obj['num'] = (obj['num'] as number) + 1
}
const updateCount = () => {
count.value++
}
const updateObjArr = () => {
(obj['arr'] as string[]).push('d')
}
const count = ref(0)
// TODO: 待支持后补充泛型示例
const obj = reactive({
str: 'default str',
num: count,
arr: ['a', 'b', 'c']
})
const updateObjStr = () => {
obj['str'] = 'new str';
}
const updateObjNum = () => {
obj['num'] = (obj['num'] as number) + 1
}
const updateCount = () => {
count.value++
}
const updateObjArr = () => {
(obj['arr'] as string[]).push('d')
}
const obj1 = reactive({
a: { b: { c: 'c' } }
})
const count1 = ref(0)
watchEffect(() => {
count1.value++
// 测试getString等keyPath触发依赖收集
obj1.getString("a.b.c")
})
function updateObj1_A_B_C() {
((obj1["a"] as UTSJSONObject)["b"] as UTSJSONObject)["c"] = "c1-" + Date.now()
}
const arr1 = ref<number[]>([])
function test(...args : number[]) {
arr1.value = args
}
function updateArr1(isReactive : boolean) {
if (isReactive) {
test(...reactive([4, 5, 6]))
} else {
test(...[1, 2, 3])
}
}
</script>
\ No newline at end of file
pages/reactivity/core/watch/watch-options.uvue
浏览文件 @
5a0eea13
...
...
@@ -156,7 +156,7 @@
watch: {
obj: {
handler(obj : Obj, prevObj ?: Obj) {
if (prevObj ==
=
null) {
if (prevObj == null) {
this.watchObjRes = `obj: {"num":${obj.num},"str":"${obj.str}","bool":${obj.bool},"arr":${JSON.stringify(obj.arr)}}, prevObj: ${JSON.stringify(prevObj)}`
} else {
// #ifdef WEB
...
...
pages/render-function/render/Foo.uvue
0 → 100644
浏览文件 @
5a0eea13
<template>
<view>
<slot name="header"></slot>
<slot name="footer"></slot>
</view>
</template>
\ No newline at end of file
pages/render-function/render/render-composition.uvue
浏览文件 @
5a0eea13
<script setup lang="uts">
import CompForHFunction from '@/components/CompForHFunction.uvue'
import CompForHFunction from '@/components/CompForHFunction.uvue'
import CompForHFunctionWithSlot from '@/components/CompForHFunctionWithSlot.uvue'
import Foo from './Foo.uvue'
const msg = ref('default msg')
// 故意外部声明为UTSJSONObject
const msgProps = { class: 'uni-common-mt msg', style: { color: 'blue' } }
const render = ():VNode => h('view', { class: 'page' }, [
h(CompForHFunction, {}, (): VNode[] => [h('text', { class: 'comp-slot' }, 'component slot')]),
h('text', { class: 'uni-common-mt msg', style: { color: 'blue' } }, msg.value),
h(CompForHFunctionWithSlot, {}, () : VNode[] => [h('text', { class: 'comp-slot' }, 'component slot')]),
h(CompForHFunction, { msg: msg.value }),
h('text', msgProps, msg.value),
h(Foo, null, {
header: (): VNode[] => [h('text', { id: "header" }, 'header')],
footer: (): VNode[] => [h('text', { id: "footer" }, 'footer')]
}),
h(
'button',
{
...
...
pages/render-function/render/render-options.uvue
浏览文件 @
5a0eea13
<script lang="uts">
import CompForHFunction from '@/components/CompForHFunction.uvue'
export default {
data() {
return {
msg: 'default msg'
}
},
render(): VNode {
return h('view', { class: 'page' }, [
h(CompForHFunction, {}, (): VNode[] => [h('text', { class: 'comp-slot' }, 'component slot')]),
h('text', { class: 'uni-common-mt msg', style: { color: 'blue' } }, this.msg),
h(
'button',
{
class: 'uni-common-mt btn',
type: 'primary',
onClick: () => {
this.msg = 'new msg'
}
},
'click'
)
])
}
}
</script>
<style>
.btn {
color: red;
}
<script lang="uts">
import CompForHFunction from '@/components/CompForHFunction.uvue'
import CompForHFunctionWithSlot from '@/components/CompForHFunctionWithSlot.uvue'
import Foo from './Foo.uvue'
// 故意外部声明为UTSJSONObject
const msgProps = { class: 'uni-common-mt msg', style: { color: 'blue' } }
export default {
data() {
return {
msg: 'default msg'
}
},
render() : VNode {
return h('view', { class: 'page' }, [
h(CompForHFunctionWithSlot, {}, () : VNode[] => [h('text', { class: 'comp-slot' }, 'component slot')]),
h(CompForHFunction, { msg: this.msg }),
h('text', msgProps, this.msg),
h(Foo, null, {
header: (): VNode[] => [h('text', { id: "header" }, 'header')],
footer: (): VNode[] => [h('text', { id: "footer" }, 'footer')]
}),
h(
'button',
{
class: 'uni-common-mt btn',
type: 'primary',
onClick: () => {
this.msg = 'new msg'
}
},
'click'
)
])
}
}
</script>
<style>
.btn {
color: red;
}
</style>
\ No newline at end of file
pages/render-function/render/render.test.js
浏览文件 @
5a0eea13
...
...
@@ -18,19 +18,26 @@ describe('render-function render', () => {
const
ComForRenderFunction
=
await
page
.
$
(
'
.component-for-h-function
'
)
expect
(
await
ComForRenderFunction
.
text
()).
toEqual
(
'
component for h()
'
'
component for h()
with slot
'
)
const
compSlot
=
await
page
.
$
(
'
.comp-slot
'
)
expect
(
await
compSlot
.
text
()).
toEqual
(
'
component slot
'
)
let
msgEl
=
await
page
.
$
(
'
.msg
'
)
expect
(
await
msgEl
.
text
()).
toEqual
(
'
default msg
'
)
compForHFunctionMsg
=
await
page
.
$
(
'
#comp-for-h-function-msg
'
)
expect
(
await
compForHFunctionMsg
.
text
()).
toEqual
(
'
default msg
'
)
const
btnEl
=
await
page
.
$
(
'
.btn
'
)
expect
(
await
btnEl
.
property
(
'
type
'
)).
toBe
(
'
primary
'
)
await
btnEl
.
tap
()
msgEl
=
await
page
.
$
(
'
.msg
'
)
expect
(
await
msgEl
.
text
()).
toEqual
(
'
new msg
'
)
compForHFunctionMsg
=
await
page
.
$
(
'
#comp-for-h-function-msg
'
)
expect
(
await
compForHFunctionMsg
.
text
()).
toEqual
(
'
new msg
'
)
expect
(
await
(
await
page
.
$
(
'
#header
'
)).
text
()).
toEqual
(
'
header
'
)
expect
(
await
(
await
page
.
$
(
'
#footer
'
)).
text
()).
toEqual
(
'
footer
'
)
}
it
(
'
render options API
'
,
async
()
=>
{
...
...
testSequencer.js
0 → 100644
浏览文件 @
5a0eea13
const
Sequencer
=
require
(
"
@jest/test-sequencer
"
).
default
const
sortTestFilePaths
=
[
"
pages/App.test.js
"
,
]
class
CustomSequencer
extends
Sequencer
{
sort
(
tests
)
{
// 测试例排序
const
sortedTests
=
sortTestFilePaths
.
map
((
filePath
)
=>
{
return
tests
.
find
((
test
)
=>
test
.
path
.
endsWith
(
filePath
))
})
.
filter
(
Boolean
)
return
[...
new
Set
([...
sortedTests
,
...
tests
])]
}
}
module
.
exports
=
CustomSequencer
uni_modules/call-easy-method/components/call-easy-method-uni-modules/call-easy-method-uni-modules.vue
浏览文件 @
5a0eea13
...
...
@@ -4,10 +4,17 @@
<
script
>
export
default
{
props
:
{
},
data
()
{
return
{
result
:
''
}
},
emits
:[
'
propsChanged
'
],
watch
:
{
},
methods
:
{
foo1
()
{
...
...
@@ -28,4 +35,4 @@
}
}
}
</
script
>
\ No newline at end of file
</
script
>
uni_modules/test-props/changelog.md
0 → 100644
浏览文件 @
5a0eea13
uni_modules/test-props/package.json
0 → 100644
浏览文件 @
5a0eea13
{
"id"
:
"test-props"
,
"displayName"
:
"test-props"
,
"version"
:
"1.0.0"
,
"description"
:
"test-props"
,
"keywords"
:
[
"test-props"
],
"repository"
:
""
,
"engines"
:
{
"HBuilderX"
:
"^3.7.0"
},
"dcloudext"
:
{
"type"
:
"component-uts"
,
"sale"
:
{
"regular"
:
{
"price"
:
"0.00"
},
"sourcecode"
:
{
"price"
:
"0.00"
}
},
"contact"
:
{
"qq"
:
""
},
"declaration"
:
{
"ads"
:
""
,
"data"
:
""
,
"permissions"
:
""
},
"npmurl"
:
""
},
"uni_modules"
:
{
"dependencies"
:
[],
"encrypt"
:
[],
"platforms"
:
{
"cloud"
:
{
"tcb"
:
"u"
,
"aliyun"
:
"u"
,
"alipay"
:
"u"
},
"client"
:
{
"Vue"
:
{
"vue2"
:
"u"
,
"vue3"
:
"u"
},
"App"
:
{
"app-android"
:
"u"
,
"app-ios"
:
"u"
},
"H5-mobile"
:
{
"Safari"
:
"u"
,
"Android Browser"
:
"u"
,
"微信浏览器(Android)"
:
"u"
,
"QQ浏览器(Android)"
:
"u"
},
"H5-pc"
:
{
"Chrome"
:
"u"
,
"IE"
:
"u"
,
"Edge"
:
"u"
,
"Firefox"
:
"u"
,
"Safari"
:
"u"
},
"小程序"
:
{
"微信"
:
"u"
,
"阿里"
:
"u"
,
"百度"
:
"u"
,
"字节跳动"
:
"u"
,
"QQ"
:
"u"
,
"钉钉"
:
"u"
,
"快手"
:
"u"
,
"飞书"
:
"u"
,
"京东"
:
"u"
},
"快应用"
:
{
"华为"
:
"u"
,
"联盟"
:
"u"
}
}
}
}
}
\ No newline at end of file
uni_modules/test-props/readme.md
0 → 100644
浏览文件 @
5a0eea13
# test-props
### 开发文档
[
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
uni_modules/test-props/utssdk/app-android/event.uts
0 → 100644
浏览文件 @
5a0eea13
import { PropsChangeEvent, PropsChangeEventDetail } from './index.uts'
export class PropChangeEventImpl extends UniCustomEvent<PropsChangeEventDetail> implements PropsChangeEvent {
constructor(detail : PropsChangeEventDetail) {
super("propChange", detail);
}
}
uni_modules/test-props/utssdk/app-android/index.uts
0 → 100644
浏览文件 @
5a0eea13
import { IPropsChangeEvent,IPropsChangeEventDetail } from '../interface.uts'
export type PropsChangeEvent = IPropsChangeEvent
export type PropsChangeEventDetail = IPropsChangeEventDetail
uni_modules/test-props/utssdk/app-android/index.vue
0 → 100644
浏览文件 @
5a0eea13
<
template
>
<view>
</view>
</
template
>
<
script
lang=
"uts"
>
/**
* 引用 Android 系统库
* [可选实现,按需引入]
*/
import
TextUtils
from
'
android.text.TextUtils
'
;
import
Button
from
'
android.widget.Button
'
;
import
View
from
'
android.view.View
'
;
import
{
IObjItem
,
IPropsChangeEvent
}
from
'
../interface.uts
'
import
{
PropChangeEventImpl
}
from
'
./event.uts
'
/**
* 引入三方库
* [可选实现,按需引入]
*
* 在 Android 平台引入三方库有以下两种方式:
* 1、[推荐] 通过 仓储 方式引入,将 三方库的依赖信息 配置到 config.json 文件下的 dependencies 字段下。详细配置方式[详见](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html#dependencies)
* 2、直接引入,将 三方库的aar或jar文件 放到libs目录下。更多信息[详见](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html#android%E5%B9%B3%E5%8F%B0%E5%8E%9F%E7%94%9F%E9%85%8D%E7%BD%AE)
*
* 在通过上述任意方式依赖三方库后,使用时需要在文件中 import
* import { LottieAnimationView } from 'com.airbnb.lottie.LottieAnimationView'
*/
/**
* UTSAndroid 为平台内置对象,不需要 import 可直接调用其API,[详见](https://uniapp.dcloud.net.cn/uts/utsandroid.html#utsandroid)
*/
//原生提供以下属性或方法的实现
export
default
{
/**
* 组件名称,也就是开发者使用的标签
*/
name
:
"
test-props
"
,
/**
* 组件涉及的事件声明,只有声明过的事件,才能被正常发送
*/
emits
:
[
'
buttonclick
'
,
'
numListChange
'
,
'
objListChange
'
],
/**
* 属性声明,组件的使用者会传递这些属性值到组件
*/
props
:
{
"
buttontext
"
:
{
type
:
String
,
default
:
"
点击触发
"
},
numList
:
{
type
:
Array
as
PropType
<
number
[]
>
,
default
:
()
=>
[]
as
number
[]
},
objList
:
{
type
:
Array
as
PropType
<
IObjItem
[]
>
,
default
:
()
=>
[]
as
IObjItem
[]
}
},
/**
* 组件内部变量声明
*/
data
()
{
return
{}
},
/**
* 属性变化监听器实现
*/
watch
:
{
"
buttontext
"
:
{
/**
* 这里监听属性变化,并进行组件内部更新
*/
handler
(
newValue
:
string
,
oldValue
:
string
)
{
if
(
!
TextUtils
.
isEmpty
(
newValue
)
&&
newValue
!=
oldValue
)
{
this
.
$el
?.
setText
(
newValue
);
}
},
immediate
:
false
// 创建时是否通过此方法更新属性,默认值为false
},
numList
:
{
handler
(
newVal
:
number
[],
oldVal
:
number
[])
{
let
detail
=
new
Map
<
string
,
number
[]
>
()
detail
.
set
(
"
value
"
,
newVal
)
let
data
=
new
Map
<
string
,
any
>
()
data
.
set
(
"
detail
"
,
detail
)
// const event = new PropChangeEventImpl(newVal)
this
.
$emit
(
'
numListChange
'
,
data
)
},
immediate
:
true
},
objList
:
{
handler
(
newVal
:
any
[],
oldVal
:
any
[])
{
let
detail
=
new
Map
<
string
,
any
>
()
detail
.
set
(
"
value
"
,
newVal
)
let
data
=
new
Map
<
string
,
any
>
()
data
.
set
(
"
detail
"
,
detail
)
this
.
$emit
(
'
objListChange
'
,
data
)
},
immediate
:
true
}
},
/**
* 规则:如果没有配置expose,则methods中的方法均对外暴露,如果配置了expose,则以expose的配置为准向外暴露
* ['publicMethod'] 含义为:只有 `publicMethod` 在实例上可用
*/
expose
:
[
'
doSomething
'
],
methods
:
{
/**
* 对外公开的组件方法
*
* uni-app中调用示例:
* this.$refs["组件ref"].doSomething("uts-button");
*
* uni-app x中调用示例:
* 1、引入对应Element
* import { UtsButtonElement(组件名称以upper camel case方式命名 + Element) } from 'uts.sdk.modules.utsComponent(组件目录名称以lower camel case方式命名)';
* 2、(this.$refs["组件ref"] as UtsButtonElement).doSomething("uts-button");
* 或 (uni.getElementById("组件id") as UtsButtonElement).doSomething("uts-button");
*/
doSomething
(
param
:
string
)
{
console
.
log
(
param
);
},
/**
* 内部使用的组件方法
*/
privateMethod
()
{
}
},
/**
* [可选实现] 组件被创建,组件第一个生命周期,
* 在内存中被占用的时候被调用,开发者可以在这里执行一些需要提前执行的初始化逻辑
*/
created
()
{
},
/**
* [可选实现] 对应平台的view载体即将被创建,对应前端beforeMount
*/
NVBeforeLoad
()
{
},
/**
* [必须实现] 创建原生View,必须定义返回值类型
* 开发者需要重点实现这个函数,声明原生组件被创建出来的过程,以及最终生成的原生组件类型
* (Android需要明确知道View类型,需特殊校验)
*/
NVLoad
()
:
Button
{
let
button
=
new
Button
(
$androidContext
!
);
button
.
setText
(
"
点击触发
"
);
button
.
setOnClickListener
(
new
ButtonClickListener
(
this
));
return
button
;
},
/**
* [可选实现] 原生View已创建
*/
NVLoaded
()
{
},
/**
* [可选实现] 原生View布局完成
*/
NVLayouted
()
{
},
/**
* [可选实现] 原生View将释放
*/
NVBeforeUnload
()
{
},
/**
* [可选实现] 原生View已释放,这里可以做释放View之后的操作
*/
NVUnloaded
()
{
},
/**
* [可选实现] 组件销毁
*/
unmounted
()
{
},
/**
* [可选实现] 自定组件布局尺寸,用于告诉排版系统,组件自身需要的宽高
* 一般情况下,组件的宽高应该是由终端系统的排版引擎决定,组件开发者不需要实现此函数
* 但是部分场景下,组件开发者需要自己维护宽高,则需要开发者重写此函数
*/
NVMeasure
(
size
:
UTSSize
)
:
UTSSize
{
// size.width = 300.0.toFloat();
// size.height = 200.0.toFloat();
return
size
;
}
}
/**
* 定义按钮点击后触发回调的类
* [可选实现]
*/
class
ButtonClickListener
extends
View
.
OnClickListener
{
/**
* 如果需要在回调类或者代理类中对组件进行操作,比如调用组件方法,发送事件等,需要在该类中持有组件对应的原生类的对象
* 组件原生类的基类为 UTSComponent,该类是一个泛型类,需要接收一个类型变量,该类型变量就是原生组件的类型
*/
private
comp
:
UTSComponent
<
Button
>
;
constructor
(
comp
:
UTSComponent
<
Button
>
)
{
super
();
this
.
comp
=
comp
;
}
/**
* 按钮点击回调方法
*/
override
onClick
(
v
?:
View
)
{
console
.
log
(
"
按钮被点击
"
);
// 发送事件
this
.
comp
.
$emit
(
"
buttonclick
"
);
}
}
</
script
>
<
style
>
</
style
>
uni_modules/test-props/utssdk/app-ios/index.vue
0 → 100644
浏览文件 @
5a0eea13
<
template
>
<view
class=
"defaultStyles"
>
</view>
</
template
>
<
script
lang=
"uts"
>
/**
* 引用 iOS 系统库
* [可选实现,按需引入]
*/
import
{
UIButton
,
UIControl
}
from
"
UIKit
"
/**
* 引入三方库
* [可选实现,按需引入]
*
* 在 iOS 平台引入三方库有以下两种方式:
* 1、通过引入三方库framework 或者.a 等方式,需要将 .framework 放到 ./Frameworks 目录下,将.a 放到 ./Libs 目录下。更多信息[详见](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html#ios-平台原生配置)
* 2、通过 cocoaPods 方式引入,将要引入的 pod 信息配置到 config.json 文件下的 dependencies-pods 字段下。详细配置方式[详见](https://uniapp.dcloud.net.cn/plugin/uts-ios-cocoapods.html)
*
* 在通过上述任意方式依赖三方库后,使用时需要在文件中 import:
* 示例:import { LottieAnimationView, LottieAnimation, LottieLoopMode } from 'Lottie'
*/
/**
* UTSiOS、UTSComponent 为平台内置对象,不需要 import 可直接调用其API,[详见](https://uniapp.dcloud.net.cn/uts/utsios.html)
*/
import
{
UTSComponent
}
from
"
DCloudUTSFoundation
"
import
{
IObjItem
}
from
'
../interface.uts
'
//原生提供以下属性或方法的实现
export
default
{
data
()
{
return
{
};
},
/**
* 组件名称,也就是开发者使用的标签
*/
name
:
"
test-props
"
,
/**
* 组件涉及的事件声明,只有声明过的事件,才能被正常发送
*/
emits
:
[
'
buttonclick
'
,
'
numListChange
'
,
'
objListChange
'
],
/**
* 属性声明,组件的使用者会传递这些属性值到组件
*/
props
:
{
/**
* 字符串类型 属性:buttontext 需要设置默认值
*/
"
buttontext
"
:
{
type
:
String
,
default
:
"
点击触发
"
},
numList
:
{
type
:
Array
as
PropType
<
number
[]
>
,
default
:
()
=>
[]
as
number
[]
},
objList
:
{
type
:
Array
as
PropType
<
IObjItem
[]
>
,
default
:
()
=>
[]
as
IObjItem
[]
}
},
/**
* 组件内部变量声明
*/
/**
* 属性变化监听器实现
*/
watch
:
{
"
buttontext
"
:
{
/**
* 这里监听属性变化,并进行组件内部更新
*/
handler
(
newValue
:
String
,
oldValue
:
String
)
{
this
.
$el
.
setTitle
(
newValue
,
for
=
UIControl
.
State
.
normal
)
},
/**
* 创建时是否通过此方法更新属性,默认值为false
*/
immediate
:
false
},
numList
:
{
handler
(
newVal
:
number
[],
oldVal
:
number
[])
{
let
detail
=
new
Map
<
string
,
any
>
()
detail
.
set
(
"
value
"
,
newVal
)
let
data
=
new
Map
<
string
,
any
>
()
data
.
set
(
"
detail
"
,
detail
)
this
.
$emit
(
'
numListChange
'
,
data
)
},
immediate
:
true
},
objList
:
{
handler
(
newVal
:
any
[],
oldVal
:
any
[])
{
let
detail
=
new
Map
<
string
,
any
>
()
detail
.
set
(
"
value
"
,
newVal
)
let
data
=
new
Map
<
string
,
any
>
()
data
.
set
(
"
detail
"
,
detail
)
this
.
$emit
(
'
objListChange
'
,
data
)
},
immediate
:
true
}
},
/**
* 规则:如果没有配置expose,则methods中的方法均对外暴露,如果配置了expose,则以expose的配置为准向外暴露
* ['publicMethod'] 含义为:只有 `publicMethod` 在实例上可用
*/
expose
:
[
'
doSomething
'
],
methods
:
{
/**
* 对外公开的组件方法
* 在uni-app中调用组件方法,可以通过指定ref的方式,例如指定uts-button 标签的ref 为 ’button‘, 调用时使用:this.$refs["button"].doSomething('message');
*/
doSomething
(
paramA
:
string
)
{
// 这是组件的自定义方法
console
.
log
(
paramA
,
'
this is in uts-button component
'
)
},
/**
* 内部使用的组件方法
*/
},
/**
* 组件被创建,组件第一个生命周期,
* 在内存中被占用的时候被调用,开发者可以在这里执行一些需要提前执行的初始化逻辑
* [可选实现]
*/
created
()
{
},
/**
* 对应平台的view载体即将被创建,对应前端beforeMount
* [可选实现]
*/
NVBeforeLoad
()
{
},
/**
* 创建原生View,必须定义返回值类型
* 开发者需要重点实现这个函数,声明原生组件被创建出来的过程,以及最终生成的原生组件类型
* [必须实现]
*/
NVLoad
()
:
UIButton
{
//必须实现
buttonClickListsner
=
new
ButtonClickListsner
(
this
)
let
button
=
new
UIButton
()
button
.
setTitle
(
this
.
buttontext
,
for
=
UIControl
.
State
.
normal
)
// 在 swift target-action 对应的方法需要以OC的方式来调用,那么OC语言中用Selector来表示一个方法的名称(又称方法选择器),创建一个Selector可以使用 Selector("functionName") 的方式。
const
method
=
Selector
(
"
buttonClickAction
"
)
if
(
buttonClickListsner
!=
null
)
{
button
.
addTarget
(
buttonClickListsner
!
,
action
=
method
,
for
=
UIControl
.
Event
.
touchUpInside
)
}
return
button
},
/**
* 原生View已创建
* [可选实现]
*/
NVLoaded
()
{
/**
* 通过 this.$el 来获取原生控件。
*/
this
.
$el
.
setTitle
(
this
.
buttontext
,
for
=
UIControl
.
State
.
normal
)
},
/**
* 原生View布局完成
* [可选实现]
*/
NVLayouted
()
{
},
/**
* 原生View将释放
* [可选实现]
*/
NVBeforeUnload
()
{
},
/**
* 原生View已释放,这里可以做释放View之后的操作
* [可选实现]
*/
NVUnloaded
()
{
},
/**
* 组件销毁
* [可选实现]
*/
unmounted
()
{
}
/**
* 更多组件开发的信息详见:https://uniapp.dcloud.net.cn/plugin/uts-component.html
*/
}
/**
* 定义按钮点击后触发回调的类
* [可选实现]
*/
class
ButtonClickListsner
{
/**
* 如果需要在回调类或者代理类中对组件进行操作,比如调用组件方法,发送事件等,需要在该类中持有组件对应的原生类的对象。
* 组件原生类的基类为 UTSComponent,该类是一个泛型类,需要接收一个类型变量,该类型变量就是原生组件的类型。
*/
private
component
:
UTSComponent
<
UIButton
>
constructor
(
component
:
UTSComponent
<
UIButton
>
)
{
this
.
component
=
component
super
.
init
()
}
/**
* 按钮点击回调方法
* 在 swift 中,所有target-action (例如按钮的点击事件,NotificationCenter 的通知事件等)对应的 action 函数前面都要使用 @objc 进行标记。
* [可选实现]
*/
@
objc
buttonClickAction
()
{
console
.
log
(
"
按钮被点击
"
)
// 发送事件
this
.
component
.
__$$emit
(
"
buttonclick
"
);
}
}
/**
* 定义回调类或者代理类的实例
* [可选实现]
*/
let
buttonClickListsner
:
ButtonClickListsner
|
null
=
null
</
script
>
<
style
>
</
style
>
uni_modules/test-props/utssdk/interface.uts
0 → 100644
浏览文件 @
5a0eea13
export type IObjItem = {
id : string
}
export type IPropsChangeEventDetail = {
value : number
}
export interface IPropsChangeEvent extends UniVideoEvent {
detail : IPropsChangeEventDetail[]
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录