提交 1c08da99 编写于 作者: dcloud_wdl's avatar dcloud_wdl

Merge remote-tracking branch 'origin/alpha'

<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
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())
},
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',
})
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',
})
firstBackTime = Date.now()
setTimeout(() => {
firstBackTime = 0
}, 2000)
} else if (Date.now() - firstBackTime < 2000) {
firstBackTime = Date.now()
uni.exit()
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
}
return true
},
onExit() {
console.log('App Exit')
},
// #endif
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
// #ifndef APP-ANDROID
checkAppMixin() : boolean {
if(this.globalMixinDataMsg1 != '通过 defineMixin 定义全局 mixin data') {
return false
}
if(this.appMixinDataMsg != 'App.uvue mixin data msg') {
return false
}
// #endif
return true
}
// #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
## 1.0.18
* update 4.23.2024070309-alpha
## 1.0.17(2024-06-25)
* update 4.22.2024062415-alpha
## 1.0.16
* update 4.22.2024062415-alpha
## 1.0.15
* update 4.21.2024061818-alpha
......
......@@ -2,7 +2,7 @@
"id": "hello-uvue-alpha",
"name": "hello-uvue-alpha",
"displayName": "hello-uvue-alpha",
"version": "1.0.15",
"version": "1.0.18",
"description": "uvue的vue语法示例工程",
"main": "env.js",
"scripts": {
......@@ -20,10 +20,6 @@
"HBuilderX": "^3.96"
},
"dcloudext": {
"category": [
"前端页面模板",
"uni-app前端项目模板"
],
"sale": {
"regular": {
"price": "0.00"
......@@ -40,7 +36,8 @@
"data": "无",
"permissions": "无"
},
"npmurl": ""
"npmurl": "",
"type": "uniapp-template-project"
},
"uni_modules": {
"dependencies": [],
......@@ -48,7 +45,8 @@
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
......
......@@ -824,6 +824,12 @@
"navigationBarTitleText": "自定义组件中使用 class 定制另一个自定义组件根节点样式 组合式 API"
}
},
{
"path": "pages/examples/multiple-style-script/multiple-style-script",
"style": {
"navigationBarTitleText": "多个 style 和 script"
}
},
{
"path": "pages/type/type",
"style": {
......@@ -842,6 +848,18 @@
"style": {
"navigationBarTitleText": "runtime error 组合式 API"
}
},
{
"path": "pages/error/throw-error/throw-error-options",
"style": {
"navigationBarTitleText": "throw error 选项式 API"
}
},
{
"path": "pages/error/throw-error/throw-error-composition",
"style": {
"navigationBarTitleText": "throw error 组合式 API"
}
}
],
"globalStyle": {
......
......@@ -30,10 +30,10 @@
})
const triggerParentFn = () => {
// #ifdef APP-ANDROID
// #ifdef APP-ANDROID || WEB
parentNum.value = instance.$parent!.$callMethod('callMethodByChild') as number
// #endif
// #ifndef APP-ANDROID
// #ifndef APP-ANDROID || WEB
parentNum.value = instance.$parent!['callMethodByChild']()
// #endif
}
......
......@@ -27,10 +27,10 @@
},
methods: {
triggerParentFn() {
// #ifdef APP-ANDROID
// #ifdef APP-ANDROID || WEB
this.parentNum = this.$parent!.$callMethod('callMethodByChild') as number
// #endif
// #ifndef APP-ANDROID
// #ifndef APP-ANDROID || WEB
this.parentNum = this.$parent!['callMethodByChild']()
// #endif
}
......
......@@ -3,11 +3,11 @@
<text class="mb-10 bold">withDefaults</text>
<view class="mb-10 flex flex-row justify-between">
<text>msg</text>
<text>{{ props.msg }}</text>
<text id="prop-msg">{{ props.msg }}</text>
</view>
<view class="mb-10 flex flex-row justify-between">
<text>labels</text>
<text>{{ JSON.stringify(props.labels) }}</text>
<text id="prop-labels">{{ JSON.stringify(props.labels) }}</text>
</view>
</view>
</template>
......
......@@ -36,6 +36,11 @@ describe('props', () => {
const sameNamePropDefaultValueArr = await page.$('#same-name-prop-default-value-arr')
expect(await sameNamePropDefaultValueArr.text()).toBe('[1,2,3]')
const propMsg = await page.$('#prop-msg')
expect(await propMsg.text()).toBe('hello')
const propLabels = await page.$('#prop-labels')
expect(await propLabels.text()).toBe('["a","b"]')
}
it('props 选项式 API', async () => {
......
......@@ -24,6 +24,10 @@ defineProps({
num: {
type: Number,
default: 0
},
checked: {
type: Boolean,
default: false
},
obj: {
// #ifdef APP-ANDROID
......
......@@ -25,6 +25,10 @@
num: {
type: Number,
default: 0
},
checked: {
type: Boolean,
default: false
},
obj: {
// #ifdef APP-ANDROID
......
......@@ -30,6 +30,9 @@
:num="dataInfo.fooProps.num"
:obj="dataInfo.fooProps.obj" />
<!-- v-bind props -->
<Foo checked />
<!-- v-bind in style -->
<!-- #ifdef WEB -->
<view class="mb-10 v-bind-css"></view>
......
......@@ -20,6 +20,9 @@
<!-- v-bind props -->
<Foo :title="dataInfo.fooProps.title" :num="dataInfo.fooProps.num" :obj="dataInfo.fooProps.obj" />
<!-- v-bind props -->
<Foo checked />
<!-- v-bind in style -->
<!-- #ifdef WEB -->
<view class="mb-10 v-bind-css"></view>
......
<template>
<view class="page">
<button id="trigger-error" @click="triggerError">trigger error</button>
</view>
</template>
<script setup lang="uts">
import { state } from '@/store/index.uts'
onReady(() => {
throw Error('error in error composition page onReady')
})
const triggerError = () => {
throw Error('trigger error in throw error composition page')
}
// 自动化测试
const getLifeCycleNum = () : number => {
return state.lifeCycleNum
}
defineExpose({
getLifeCycleNum
})
</script>
\ No newline at end of file
<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 Error('error in error options page onReady')
},
methods: {
triggerError(){
throw Error('trigger error in throw error options page')
},
// 自动化测试
getLifeCycleNum() : number {
return state.lifeCycleNum
}
},
}
</script>
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 PAGE_PATH = '/pages/examples/multiple-style-script/multiple-style-script'
describe(PAGE_PATH, () => {
const platformInfo = process.env.uniTestPlatformInfo.toLowerCase()
const isAndroid = platformInfo.startsWith('android')
const isWeb = platformInfo.startsWith('web')
let page
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
await page.waitFor('view')
})
it('测试多 style 和 script', async () => {
const msg = await page.$('#msg')
expect(await msg.text()).toBe('Hello World')
if (!isAndroid) {
const num = await page.$('#num')
expect(await num.text()).toBe('0')
}
const textRed = await page.$('.text-red')
expect(await textRed.style('color')).toBe(isWeb ? 'rgb(255, 0, 0)': '#FF0000')
const textGreen = await page.$('.text-green')
expect(await textGreen.style('color')).toBe(isWeb ? 'rgb(0, 128, 0)': '#008000')
const fontBold = await page.$('.font-bold')
expect(await fontBold.style('fontWeight')).toBe(isWeb ? '700' : 'bold')
})
})
\ No newline at end of file
<template>
<view class="page">
<view class="mb-10 flex flex-row justify-between">
<text>msg: </text>
<text id="msg">{{ msg }}</text>
</view>
<!-- #ifndef APP-ANDROID -->
<view class="mb-10 flex flex-row justify-between">
<text>num: </text>
<text id="num">{{ num }}</text>
</view>
<!-- #endif -->
<view class="mb-10">
<text class="text-red">text red</text>
</view>
<view class="mb-10">
<text class="text-green">text green</text>
</view>
<view class="mb-10">
<text class="font-bold">font bold</text>
</view>
</view>
</template>
<script lang="uts">
export default {
data(){
return {
msg: 'Hello World'
}
}
}
</script>
<!-- #ifndef APP-ANDROID -->
<script setup lang="uts">
const num = ref(0)
</script>
<!-- #endif -->
<style>
.text-green {
color: green;
}
</style>
<style>
.font-bold {
font-weight: bold;
}
</style>
......@@ -1142,6 +1142,11 @@ export default {
id: 'unrecognized-component',
name: 'unrecognized-component',
url: 'unrecognized-component/unrecognized-component'
},
{
id: 'multiple-style-script',
name: '多个 style 和 script',
url: 'multiple-style-script/multiple-style-script'
}
] as Page[]
},
......@@ -1164,6 +1169,22 @@ export default {
url: 'runtime-error-composition'
},
]
},
{
id: 'throw-error',
name: 'throw error',
children: [
{
id: 'throw-error-options',
name: 'throw error 选项式 API',
url: 'throw-error-options'
},
{
id: 'throw-error-composition',
name: 'throw error 组合式 API',
url: 'throw-error-composition'
},
]
}
]
}
......@@ -1196,13 +1217,13 @@ export default {
const app = getApp()
return app.checkLaunchPath()
},
// #ifndef APP-ANDROID
// #ifndef APP-ANDROID
// 自动化测试
checkAppMixin() : boolean {
const app = getApp()
return app.checkAppMixin()
}
// #endif
// #endif
}
}
</script>
......
......@@ -19,12 +19,21 @@ describe('reactive', () => {
const objArr = await page.$('#obj-arr')
expect(await objArr.text()).toBe('["a","b","c"]')
const updateBtn = await page.$('#update-btn')
await updateBtn.tap()
const updateCountBtn = await page.$('#update-count-btn')
await updateCountBtn.tap()
expect(await count.text()).toBe('1')
expect(await count.text()).toBe('2')
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"]')
})
})
\ No newline at end of file
......@@ -16,24 +16,36 @@
<text>obj.arr:</text>
<text id="obj-arr">{{ JSON.stringify(obj['arr']) }}</text>
</view>
<button id="update-btn" @click="update">update</button>
<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)
const count = ref(0)
// TODO: 待支持后补充泛型示例
const obj = reactive({
str: 'default str',
num: count,
arr: ['a', 'b', 'c']
})
// TODO: 待支持后补充泛型示例
const obj = reactive({
str: 'default str',
num: count,
arr: ['a', 'b', 'c']
})
const update = () => {
obj['str'] = 'new str';
obj['num'] = (obj['num'] as number) + 1
count.value++
(obj['arr'] as string[]).push('d')
}
</script>
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')
}
</script>
\ No newline at end of file
......@@ -55,9 +55,11 @@ const updateData = () => {
data.arr.push('d')
}
const updateReadonlyData = () => {
readonlyData.str = 'new readonly str'
readonlyData.num++
readonlyData.arr.push('e')
const updateReadonlyData = () => {
// #ifndef WEB
readonlyData.str = 'new readonly str'
readonlyData.num++
readonlyData.arr.push('e')
// #endif
}
</script>
......@@ -18,13 +18,24 @@ describe('ref', () => {
const counterCount = await page.$('#counter-count')
expect(await counterCount.text()).toBe('0')
const changeDataBtn = await page.$('#change-data-btn')
await changeDataBtn.tap()
const changeCountBtn = await page.$('#change-count-btn')
await changeCountBtn.tap()
expect(await count.text()).toBe('1')
const changeStrBtn = await page.$('#change-str-btn')
await changeStrBtn.tap()
expect(await str.text()).toBe('new str')
const changeBoolBtn = await page.$('#change-bool-btn')
await changeBoolBtn.tap()
expect(await bool.text()).toBe('true')
const changeArrBtn = await page.$('#change-arr-btn')
await changeArrBtn.tap()
expect(await arr.text()).toBe('[1,2,3,4]')
const changeCounterBtn = await page.$('#change-counter-btn')
await changeCounterBtn.tap()
expect(await counterCount.text()).toBe('1')
})
......
......@@ -20,31 +20,43 @@
<text>counter.count:</text>
<text id="counter-count">{{ counter.count }}</text>
</view>
<button id="change-data-btn" @click="changeData">change data</button>
<button class='mb-10' id="change-count-btn" @click="changeCount">change count</button>
<button class='mb-10' id='change-str-btn' @click='changeStr'>change str</button>
<button class='mb-10' id='change-bool-btn' @click='changeBool'>change bool</button>
<button class='mb-10' id='change-arr-btn' @click='changeArr'>change arr</button>
<button class='mb-10' id='change-counter-btn' @click='changeCounter'>change counter</button>
</view>
</template>
<script setup lang="uts">
// 基础数据类型可自动推导类型
const count = ref(0)
const str = ref('default str')
const bool = ref(false)
// 基础数据类型可自动推导类型
const count = ref(0)
const str = ref('default str')
const bool = ref(false)
// 可通过泛型指定类型
const arr = ref<number[]>([1, 2, 3])
type Counter = {
count : number
}
// 可通过泛型指定类型
const counter = ref<Counter>({
count: 0
})
// 可通过泛型指定类型
const arr = ref<number[]>([1, 2, 3])
type Counter = {
count : number
}
// 可通过泛型指定类型
const counter = ref<Counter>({
count: 0
})
const changeData = () => {
count.value++
str.value = 'new str'
bool.value = !bool.value
arr.value.push(arr.value.length + 1)
counter.value.count++
}
</script>
const changeCount = () => {
count.value++
}
const changeStr = () => {
str.value = 'new str'
}
const changeBool = () => {
bool.value = !bool.value
}
const changeArr = () => {
arr.value.push(arr.value.length + 1)
}
const changeCounter = () => {
counter.value.count++
}
</script>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册