refactor: 确立独立子工程架构 (backend, admin, mpuniapp) 并同步更新 AGENTS.md 规范
这个提交包含在:
@@ -0,0 +1,34 @@
|
||||
const platformInfo = process.env.uniTestPlatformInfo.toLocaleLowerCase()
|
||||
const isWeb = platformInfo.startsWith('web')
|
||||
const isMP = platformInfo.startsWith('mp')
|
||||
const isDom2 = process.env.UNI_APP_X_DOM2 === "true"
|
||||
|
||||
const PAGE_PATH = '/pages/API/create-selector-query/create-selector-query-onScroll'
|
||||
|
||||
describe('create-selector-query-onScroll', () => {
|
||||
if (isWeb || isMP || isDom2 || process.env.UNI_TEST_DEVICES_DIRECTION == 'landscape') {
|
||||
it('not support', () => {
|
||||
expect(1).toBe(1)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
let page
|
||||
beforeAll(async () => {
|
||||
page = await program.reLaunch(PAGE_PATH)
|
||||
await page.waitFor(500);
|
||||
})
|
||||
|
||||
|
||||
it('test-createSelectorQuery-onScroll', async () => {
|
||||
|
||||
let x = 100
|
||||
let y = 250
|
||||
// 滑动事件
|
||||
await program.device.swipe( x, y, x, y-100, 300)
|
||||
|
||||
await page.waitFor(600);
|
||||
const ret = await page.data('data.ret')
|
||||
expect(ret).toBe(true)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<scroll-view @scroll="onScroll" style="flex: 1;">
|
||||
<view v-for="i in 60" class="content-item">
|
||||
<text class="text">item-{{i}}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
|
||||
const instance = getCurrentInstance()!.proxy!
|
||||
|
||||
type DataType = {
|
||||
ret: boolean,
|
||||
}
|
||||
|
||||
const count = ref(0)
|
||||
const data = reactive({
|
||||
ret: true,
|
||||
} as DataType)
|
||||
|
||||
function onScroll() {
|
||||
count.value++
|
||||
console.log("scroll: ", count.value)
|
||||
uni.createSelectorQuery()
|
||||
.in(instance)
|
||||
.selectAll('content-item')
|
||||
.boundingClientRect()
|
||||
.exec((result) => {
|
||||
count.value--
|
||||
})
|
||||
console.log("scroll: ", count.value)
|
||||
|
||||
if (count.value > 0) {
|
||||
data.ret = false
|
||||
}
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
data
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,168 @@
|
||||
const platformInfo = process.env.uniTestPlatformInfo.toLocaleLowerCase()
|
||||
const isMP = platformInfo.startsWith('mp')
|
||||
const isWeb = platformInfo.startsWith('web')
|
||||
const isDom2 = process.env.UNI_APP_X_DOM2 === "true"
|
||||
|
||||
describe('nodes-info', () => {
|
||||
if (isMP) {
|
||||
it('skip', () => {
|
||||
expect(1).toBe(1)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const PAGE_PATH = '/pages/API/create-selector-query/create-selector-query'
|
||||
const RECT_LEFT = 15;
|
||||
const RECT_WIDTH = 150;
|
||||
const RECT_HEIGHT = 100;
|
||||
|
||||
let page
|
||||
beforeAll(async () => {
|
||||
page = await program.reLaunch(PAGE_PATH)
|
||||
await page.waitFor('view')
|
||||
})
|
||||
|
||||
// 查询到的元素涉及设备精度问题,截图对比差异较大,不在截图对比,已有值断言比较
|
||||
// it("screenshot", async () => {
|
||||
// const image = await program.screenshot({ fullPage: true });
|
||||
// expect(image).toSaveImageSnapshot();
|
||||
// })
|
||||
|
||||
it('get-root-node-info', async () => {
|
||||
// 测试 class 选择器
|
||||
await getRootNode('.page')
|
||||
|
||||
// 测试 id 选择器
|
||||
await getRootNode('#page')
|
||||
|
||||
// 测试 标签 选择器
|
||||
// await getRootNode('page')
|
||||
})
|
||||
it('get-node-info', async () => {
|
||||
const btnGetNodeInfo = await page.$('.btn-get-node-info')
|
||||
|
||||
await btnGetNodeInfo.tap()
|
||||
await page.waitFor(50)
|
||||
|
||||
const data = await page.data('data')
|
||||
|
||||
// TODO 和浏览器的计算存在差异
|
||||
const nodeInfo = data.nodeInfoList[0]
|
||||
expect(Math.round(nodeInfo.left)).toBe(RECT_LEFT)
|
||||
expect(Math.round(nodeInfo.width)).toBe(RECT_WIDTH)
|
||||
expect(Math.round(nodeInfo.height)).toBe(RECT_HEIGHT)
|
||||
})
|
||||
it('get-all-node-info', async () => {
|
||||
const btnGetAllNodeInfo = await page.$('.btn-get-all-node-info')
|
||||
|
||||
await btnGetAllNodeInfo.tap()
|
||||
await page.waitFor(50)
|
||||
|
||||
const data = await page.data('data')
|
||||
|
||||
const nodeInfo1 = data.nodeInfoList[0]
|
||||
expect(Math.round(nodeInfo1.left)).toBe(RECT_LEFT)
|
||||
expect(nodeInfo1.top > 220).toBe(true)
|
||||
expect(Math.round(nodeInfo1.width)).toBe(RECT_WIDTH)
|
||||
expect(Math.round(nodeInfo1.height)).toBe(RECT_HEIGHT)
|
||||
|
||||
const nodeInfo2 = data.nodeInfoList[1]
|
||||
expect(nodeInfo2.left > 180).toBe(true)
|
||||
expect(nodeInfo2.top > 220).toBe(true)
|
||||
expect(Math.round(nodeInfo2.width)).toBe(RECT_WIDTH)
|
||||
expect(Math.round(nodeInfo2.height)).toBe(RECT_HEIGHT)
|
||||
})
|
||||
if(!isMP) {
|
||||
// 小程序端启用了虚拟host,无法获取到子组件
|
||||
it('get-node-info-child', async () => {
|
||||
const child = await page.$('.node-child')
|
||||
const childData = await child.data('data')
|
||||
console.log('get-node-info-child.childData.top', childData.top);
|
||||
expect(childData.top > 100).toBe(true)
|
||||
})
|
||||
}
|
||||
|
||||
it('multi-child', async () => {
|
||||
const pageData = await page.data('data')
|
||||
console.log('multi-child.pageData', pageData)
|
||||
expect(pageData.selectCount).toBe(1)
|
||||
expect(pageData.selectAllCount).toBe(2)
|
||||
})
|
||||
|
||||
// #ifdef APP
|
||||
//检测onResize获取BoundingClientRect信息是否有效
|
||||
/* it('check_resizeRectValid', async () => {
|
||||
const resizeRectValid = await page.data('resizeRectValid')
|
||||
expect(resizeRectValid).toBe(true)
|
||||
}) */
|
||||
// #endif
|
||||
|
||||
if (!(isWeb || isMP)) {
|
||||
it('test fields', async () => {
|
||||
const pageData = await page.data('data')
|
||||
expect(pageData.fieldsResultContainNode).toBe(true)
|
||||
})
|
||||
|
||||
it('test node', async () => {
|
||||
const pageData = await page.data('data')
|
||||
expect(pageData.nodeResultContainNode).toBe(true)
|
||||
})
|
||||
}
|
||||
|
||||
// 测试 text 组件查询
|
||||
it('get-text-node-info', async () => {
|
||||
await page.callMethod('getTextNodeInfo')
|
||||
await page.waitFor(100)
|
||||
const textNodeInfo = await page.data('data.textNodeInfo')
|
||||
expect(textNodeInfo).not.toBe(null)
|
||||
expect(textNodeInfo.left).toBeCloseTo(15, 0);
|
||||
expect(Math.round(textNodeInfo.right) > 300).toBe(true)
|
||||
expect(Math.round(textNodeInfo.top) > 200).toBe(true)
|
||||
expect(Math.round(textNodeInfo.bottom) > 200).toBe(true)
|
||||
expect(Math.round(textNodeInfo.width) > 300).toBe(true)
|
||||
expect(Math.round(textNodeInfo.height) > 30).toBe(true)
|
||||
})
|
||||
|
||||
// 测试 image 组件查询
|
||||
it('get-image-node-info', async () => {
|
||||
await page.callMethod('getImageNodeInfo')
|
||||
await page.waitFor(100)
|
||||
const imageNodeInfo = await page.data('data.imageNodeInfo')
|
||||
expect(imageNodeInfo).not.toBe(null)
|
||||
expect(imageNodeInfo.left).toBeCloseTo(15, 0);
|
||||
expect(imageNodeInfo.right).toBeCloseTo(115, 0);
|
||||
expect(Math.round(imageNodeInfo.top) > 380).toBe(true)
|
||||
expect(Math.round(imageNodeInfo.bottom) > 480).toBe(true)
|
||||
expect(imageNodeInfo.width).toBeCloseTo(100, 0);
|
||||
expect(imageNodeInfo.height).toBeCloseTo(100, 0)
|
||||
})
|
||||
|
||||
// 测试 scroll-view 组件查询
|
||||
it('get-scroll-view-node-info', async () => {
|
||||
await page.callMethod('getScrollViewNodeInfo')
|
||||
await page.waitFor(100)
|
||||
const scrollViewNodeInfo = await page.data('data.scrollViewNodeInfo')
|
||||
expect(scrollViewNodeInfo).not.toBe(null)
|
||||
expect(scrollViewNodeInfo.left).toBeCloseTo(15, 0);
|
||||
expect(scrollViewNodeInfo.right).toBeCloseTo(315, 0);
|
||||
expect(Math.round(scrollViewNodeInfo.top) > 560).toBe(true)
|
||||
expect(Math.round(scrollViewNodeInfo.bottom) > 660).toBe(true)
|
||||
expect(scrollViewNodeInfo.width).toBeCloseTo(300, 0);
|
||||
expect(scrollViewNodeInfo.height).toBeCloseTo(100, 0)
|
||||
})
|
||||
})
|
||||
|
||||
async function getRootNode(selector) {
|
||||
const page = await program.currentPage()
|
||||
|
||||
await page.setData({
|
||||
data:{rootNodeInfo: null,}
|
||||
})
|
||||
await page.waitFor(100)
|
||||
|
||||
await page.callMethod('getRootNodeInfo', selector)
|
||||
await page.waitFor(100)
|
||||
|
||||
const data = await page.data('data')
|
||||
expect(data.rootNodeInfo != null).toBe(true)
|
||||
}
|
||||
@@ -0,0 +1,452 @@
|
||||
<template>
|
||||
<!-- #ifdef APP && !VUE3-VAPOR -->
|
||||
<scroll-view class="page-scroll-view">
|
||||
<!-- #endif -->
|
||||
<view class="page uni-list-cell-db-text" style="padding-bottom: var(--uni-safe-area-inset-bottom);" id="page">
|
||||
<page-head :title="data.title"></page-head>
|
||||
<page-intro content="本页演示 uni.createSelectorQuery:通过 select/selectAll 与 boundingClientRect 获取节点布局信息(left、top、right、bottom、width、height);含 view、text、image、scroll-view 及子组件多根节点等查询示例,可测试 .fields/.node 结果;底部可跳转「滚动容器中的 createSelectorQuery」子页。"></page-intro>
|
||||
<button class="btn btn-get-node-info" @click="getNodeInfo">getNodeInfo</button>
|
||||
<button class="btn btn-get-all-node-info" @click="getAllNodeInfo">getAllNodeInfo</button>
|
||||
<view id="rect-1-2" class="rect-1-2">
|
||||
<view class="rect rect1"></view>
|
||||
<view class="rect rect2"></view>
|
||||
</view>
|
||||
<view class="rect-info-1-2">
|
||||
<view class="rect-info" v-for="(nodeInfo, index) in data.nodeInfoList" :key="index">
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">left: </text>
|
||||
<text class="node-info-item-v">{{nodeInfo.left}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">top: </text>
|
||||
<text class="node-info-item-v">{{nodeInfo.top}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">right: </text>
|
||||
<text class="node-info-item-v">{{nodeInfo.right}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">bottom: </text>
|
||||
<text class="node-info-item-v">{{nodeInfo.bottom}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">width: </text>
|
||||
<text class="node-info-item-v">{{nodeInfo.width}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">height: </text>
|
||||
<text class="node-info-item-v">{{nodeInfo.height}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<node-child class="node-child"></node-child>
|
||||
<text>子组件多根节点</text>
|
||||
<multi-child ref="multiChildRef" id="multi-child"></multi-child>
|
||||
<text>子组件多根节点(仅测试,用于验证查询是否超出范围)</text>
|
||||
<multi-child id="multi-child-2"></multi-child>
|
||||
<view>
|
||||
<text>测试.fields</text>
|
||||
<text>{{data.fieldsResultContainNode}}</text>
|
||||
</view>
|
||||
<view>
|
||||
<text>测试.node</text>
|
||||
<text>{{data.nodeResultContainNode}}</text>
|
||||
</view>
|
||||
<canvas id="canvas1"></canvas>
|
||||
|
||||
<!-- text 组件 -->
|
||||
<view class="uni-common-mt">
|
||||
<text class="uni-title-text">Text 组件查询示例</text>
|
||||
<text id="test-text" class="test-text">这是一个测试文本元素</text>
|
||||
<button class="btn" @click="getTextNodeInfo">查询 Text 节点信息</button>
|
||||
<view v-if="data.textNodeInfo" class="rect-info">
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">left: </text>
|
||||
<text class="node-info-item-v">{{data.textNodeInfo!.left}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">right: </text>
|
||||
<text class="node-info-item-v">{{data.textNodeInfo!.right}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">top: </text>
|
||||
<text class="node-info-item-v">{{data.textNodeInfo!.top}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">bottom: </text>
|
||||
<text class="node-info-item-v">{{data.textNodeInfo!.bottom}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">width: </text>
|
||||
<text class="node-info-item-v">{{data.textNodeInfo!.width}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">height: </text>
|
||||
<text class="node-info-item-v">{{data.textNodeInfo!.height}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- image 组件 -->
|
||||
<view class="uni-common-mt">
|
||||
<text class="uni-title-text">Image 组件查询示例</text>
|
||||
<image id="test-image" class="test-image" src="/static/test-image/logo.png" mode="aspectFit"></image>
|
||||
<button class="btn" @click="getImageNodeInfo">查询 Image 节点信息</button>
|
||||
<view v-if="data.imageNodeInfo" class="rect-info">
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">left: </text>
|
||||
<text class="node-info-item-v">{{data.imageNodeInfo!.left}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">right: </text>
|
||||
<text class="node-info-item-v">{{data.imageNodeInfo!.right}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">top: </text>
|
||||
<text class="node-info-item-v">{{data.imageNodeInfo!.top}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">bottom: </text>
|
||||
<text class="node-info-item-v">{{data.imageNodeInfo!.bottom}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">width: </text>
|
||||
<text class="node-info-item-v">{{data.imageNodeInfo!.width}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">height: </text>
|
||||
<text class="node-info-item-v">{{data.imageNodeInfo!.height}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- scroll-view 组件 -->
|
||||
<view class="uni-common-mt">
|
||||
<text class="uni-title-text">Scroll-view 组件查询示例</text>
|
||||
<scroll-view id="test-scroll-view" class="test-scroll-view">
|
||||
<view style="padding: 10px;">
|
||||
<text v-for="i in 10" :key="i">Scroll-view 第 {{i}} 行</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<button class="btn" @click="getScrollViewNodeInfo">查询 Scroll-view 节点信息</button>
|
||||
<view v-if="data.scrollViewNodeInfo" class="rect-info">
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">left: </text>
|
||||
<text class="node-info-item-v">{{data.scrollViewNodeInfo!.left}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">right: </text>
|
||||
<text class="node-info-item-v">{{data.scrollViewNodeInfo!.right}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">top: </text>
|
||||
<text class="node-info-item-v">{{data.scrollViewNodeInfo!.top}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">bottom: </text>
|
||||
<text class="node-info-item-v">{{data.scrollViewNodeInfo!.bottom}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">width: </text>
|
||||
<text class="node-info-item-v">{{data.scrollViewNodeInfo!.width}}</text>
|
||||
</view>
|
||||
<view class="node-info-item">
|
||||
<text class="node-info-item-k">height: </text>
|
||||
<text class="node-info-item-v">{{data.scrollViewNodeInfo!.height}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<navigator url="/pages/API/create-selector-query/create-selector-query-onScroll"><button>滚动容器中的createSelectorQuery</button></navigator>
|
||||
</view>
|
||||
<!-- #ifdef APP && !VUE3-VAPOR -->
|
||||
</scroll-view>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import nodeChild from './nodes-info-child.uvue'
|
||||
import multiChild from './selector-query-child-multi.uvue'
|
||||
|
||||
type NodeInfoType = {
|
||||
left : number | null,
|
||||
top : number | null,
|
||||
right : number | null,
|
||||
bottom : number | null,
|
||||
width : number | null,
|
||||
height : number | null,
|
||||
}
|
||||
|
||||
type DataType = {
|
||||
title: string;
|
||||
nodeInfoList: NodeInfoType[];
|
||||
rootNodeInfo: NodeInfoType | null;
|
||||
selectCount: number;
|
||||
selectAllCount: number;
|
||||
fieldsResultContainNode: boolean;
|
||||
nodeResultContainNode: boolean;
|
||||
textNodeInfo: NodeInfoType | null;
|
||||
imageNodeInfo: NodeInfoType | null;
|
||||
scrollViewNodeInfo: NodeInfoType | null;
|
||||
}
|
||||
// 使用reactive避免ref数据在自动化测试中无法访问
|
||||
const data = reactive({
|
||||
title: 'createSelectorQuery',
|
||||
nodeInfoList: [],
|
||||
// 仅用于自动化测试
|
||||
rootNodeInfo: null,
|
||||
//供自动化测试使用
|
||||
// resizeRectValid: false
|
||||
// TODO
|
||||
selectCount: 0,
|
||||
selectAllCount: 0,
|
||||
fieldsResultContainNode: false,
|
||||
nodeResultContainNode: false,
|
||||
textNodeInfo: null,
|
||||
imageNodeInfo: null,
|
||||
scrollViewNodeInfo: null
|
||||
} as DataType)
|
||||
|
||||
const multiChildRef = ref<ComponentPublicInstance | null>(null)
|
||||
|
||||
// 仅用于自动化测试
|
||||
const onChildReady = (count: number, allCount: number) => {
|
||||
// 通过事件传递数据,子组件在ready时通过事件发送数据
|
||||
data.selectCount = count
|
||||
data.selectAllCount = allCount
|
||||
}
|
||||
|
||||
// 仅用于自动化测试
|
||||
const getRootNodeInfo = (selector: string) => {
|
||||
uni.createSelectorQuery().select(selector).boundingClientRect().exec((ret) => {
|
||||
if (ret.length == 1) {
|
||||
const nodeInfo = ret[0] as NodeInfo;
|
||||
const nodeType = {
|
||||
left: nodeInfo.left,
|
||||
top: nodeInfo.top,
|
||||
right: nodeInfo.right,
|
||||
bottom: nodeInfo.bottom,
|
||||
width: nodeInfo.width,
|
||||
height: nodeInfo.height,
|
||||
} as NodeInfoType;
|
||||
data.rootNodeInfo = nodeType
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getNodeInfo = () => {
|
||||
uni.createSelectorQuery().select('.rect1').boundingClientRect().exec((ret) => {
|
||||
data.nodeInfoList.length = 0
|
||||
const i = ret[0] as NodeInfo
|
||||
data.nodeInfoList.push({
|
||||
left: i.left,
|
||||
top: i.top,
|
||||
right: i.right,
|
||||
bottom: i.bottom,
|
||||
width: i.width,
|
||||
height: i.height,
|
||||
} as NodeInfoType)
|
||||
})
|
||||
}
|
||||
|
||||
const getAllNodeInfo = () => {
|
||||
uni.createSelectorQuery().selectAll('.rect').boundingClientRect().exec((ret) => {
|
||||
data.nodeInfoList.length = 0
|
||||
const array = ret[0] as NodeInfo[]
|
||||
array.forEach((i) => {
|
||||
data.nodeInfoList.push({
|
||||
left: i.left,
|
||||
top: i.top,
|
||||
right: i.right,
|
||||
bottom: i.bottom,
|
||||
width: i.width,
|
||||
height: i.height,
|
||||
} as NodeInfoType)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// test .fields
|
||||
const testFields = () => {
|
||||
uni.createSelectorQuery().select('.rect1').fields({
|
||||
node: true
|
||||
} as NodeField, (ret) => {
|
||||
const isElement = (ret as NodeInfo).node instanceof UniElement
|
||||
if (isElement) {
|
||||
data.fieldsResultContainNode = true
|
||||
} else {
|
||||
data.fieldsResultContainNode = false
|
||||
}
|
||||
}).exec()
|
||||
}
|
||||
|
||||
// test .node
|
||||
const testNode = () => {
|
||||
uni.createSelectorQuery().select('#canvas1').node((ret) => {
|
||||
const isElement = (ret as NodeInfo).node instanceof UniElement
|
||||
const isCanvasElement = ((ret as NodeInfo).node as UniCanvasElement).tagName == 'CANVAS'
|
||||
if (isElement && isCanvasElement) {
|
||||
data.nodeResultContainNode = true
|
||||
} else {
|
||||
data.nodeResultContainNode = false
|
||||
}
|
||||
}).exec()
|
||||
}
|
||||
|
||||
// 查询 text 节点信息
|
||||
const getTextNodeInfo = () => {
|
||||
uni.createSelectorQuery().select('#test-text').boundingClientRect().exec((ret) => {
|
||||
if (ret.length > 0) {
|
||||
const i = ret[0] as NodeInfo
|
||||
data.textNodeInfo = {
|
||||
left: i.left,
|
||||
top: i.top,
|
||||
right: i.right,
|
||||
bottom: i.bottom,
|
||||
width: i.width,
|
||||
height: i.height,
|
||||
} as NodeInfoType
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 查询 image 节点信息
|
||||
const getImageNodeInfo = () => {
|
||||
uni.createSelectorQuery().select('#test-image').boundingClientRect().exec((ret) => {
|
||||
if (ret.length > 0) {
|
||||
const i = ret[0] as NodeInfo
|
||||
data.imageNodeInfo = {
|
||||
left: i.left,
|
||||
top: i.top,
|
||||
right: i.right,
|
||||
bottom: i.bottom,
|
||||
width: i.width,
|
||||
height: i.height,
|
||||
} as NodeInfoType
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 查询 scroll-view 节点信息
|
||||
const getScrollViewNodeInfo = () => {
|
||||
uni.createSelectorQuery().select('#test-scroll-view').boundingClientRect().exec((ret) => {
|
||||
if (ret.length > 0) {
|
||||
const i = ret[0] as NodeInfo
|
||||
data.scrollViewNodeInfo = {
|
||||
left: i.left,
|
||||
top: i.top,
|
||||
right: i.right,
|
||||
bottom: i.bottom,
|
||||
width: i.width,
|
||||
height: i.height,
|
||||
} as NodeInfoType
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
uni.$on('childDataReady', onChildReady)
|
||||
})
|
||||
|
||||
onUnload(() => {
|
||||
uni.$off('childDataReady', onChildReady)
|
||||
})
|
||||
|
||||
onReady(() => {
|
||||
testFields()
|
||||
testNode()
|
||||
})
|
||||
|
||||
onResize(() => {
|
||||
//供自动化测试使用
|
||||
/* var rect12Element = uni.getElementById("rect-1-2")
|
||||
if(rect12Element != null) {
|
||||
var domRect = rect12Element.getBoundingClientRect()
|
||||
if(domRect.width > 100) {
|
||||
data.resizeRectValid = true
|
||||
}
|
||||
} */
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
data,
|
||||
getRootNodeInfo,
|
||||
getTextNodeInfo,
|
||||
getImageNodeInfo,
|
||||
getScrollViewNodeInfo
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.page {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.rect-1-2 {
|
||||
flex-direction: row;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.rect {
|
||||
width: 150px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.rect1 {
|
||||
background-color: dodgerblue;
|
||||
}
|
||||
|
||||
.rect2 {
|
||||
margin-left: auto;
|
||||
background-color: seagreen;
|
||||
}
|
||||
|
||||
.rect-info-1-2 {
|
||||
flex-direction: row;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.rect-info {
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.node-info-item {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.node-info-item-k {
|
||||
width: 72px;
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
.node-info-item-v {
|
||||
font-weight: bold;
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
.test-text {
|
||||
padding: 10px;
|
||||
background-color: #d6d6d6;
|
||||
margin: 10px 0;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.test-image {
|
||||
margin: 10px 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.test-scroll-view {
|
||||
margin: 10px 0;
|
||||
width: 300px;
|
||||
height: 100px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<view class="selector-query-child-view">
|
||||
<text class="selector-query-child-text">selector-query-child</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
|
||||
const instance = getCurrentInstance()!.proxy!
|
||||
|
||||
type DataType = {
|
||||
top: number,
|
||||
}
|
||||
|
||||
const data = reactive({
|
||||
top: 0,
|
||||
} as DataType)
|
||||
|
||||
onMounted(() => {
|
||||
uni.createSelectorQuery().in(instance).select('.selector-query-child-view').boundingClientRect().exec((ret) => {
|
||||
if (ret.length == 1) {
|
||||
const nodeInfo = ret[0] as NodeInfo;
|
||||
data.top = nodeInfo.top!
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
data
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.selector-query-child-view {
|
||||
margin-top: 15px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<view class="selector-query-view">
|
||||
<text>selector-query</text>
|
||||
<text class="text red">{{text1}}</text>
|
||||
</view>
|
||||
<view class="selector-query-view">
|
||||
<text>selector-query</text>
|
||||
<text class="text green">{{text2}}</text>
|
||||
</view>
|
||||
<view v-if="text1.length>0">1</view>
|
||||
<text>{{text3}}</text>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
const instance = getCurrentInstance()!.proxy!
|
||||
|
||||
const text1 = ref("")
|
||||
const text2 = ref("")
|
||||
const text3 = ref("test-text-node")
|
||||
const viewCount = ref(0)
|
||||
const selectCount = ref(0)
|
||||
const selectAllCount = ref(0)
|
||||
const show = ref(false)
|
||||
const testCounter = ref(0)
|
||||
|
||||
function _dispatchEvent() {
|
||||
if (testCounter.value == 2) {
|
||||
// 通过事件传递数据,避免UTS无法访问动态属性的问题
|
||||
uni.$emit('childDataReady', selectCount.value, selectAllCount.value)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
uni.createSelectorQuery().in(instance).select('.selector-query-view').boundingClientRect().exec((ret) => {
|
||||
text1.value = JSON.stringify(ret, null, 2)
|
||||
if (ret.length == 1) {
|
||||
selectCount.value = ret.length
|
||||
}
|
||||
testCounter.value++
|
||||
_dispatchEvent()
|
||||
})
|
||||
uni.createSelectorQuery().in(instance).selectAll('.selector-query-view').boundingClientRect().exec((ret) => {
|
||||
text2.value = JSON.stringify(ret, null, 2)
|
||||
if (ret.length == 1) {
|
||||
selectAllCount.value = (ret[0] as NodeInfo[]).length
|
||||
}
|
||||
testCounter.value++
|
||||
_dispatchEvent()
|
||||
})
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
selectCount,
|
||||
selectAllCount
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.green {
|
||||
border: 3px solid green;
|
||||
}
|
||||
|
||||
.red {
|
||||
border: 3px solid red;
|
||||
}
|
||||
|
||||
.view {
|
||||
border: 3px dashed lime;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.text {
|
||||
margin-top: 20px;
|
||||
padding: 5px;
|
||||
}
|
||||
</style>
|
||||
在新工单中引用
屏蔽一个用户