uni-app 是组合了 Vue 和微信小程序的相关技术知识,要求大家同时俱备 Vue 和原生小程序的开发基础。
在此再次强调一下原生小程序中并没有 DOM 操作相关的内容,也因此在 uni-app 中也是无法对 DOM 进行操作的,但在实际开发过程中是有获取节点信息,如宽高、位置等信息的需求的,这一节就来学习在 uni-app 中如何获取节点的宽高及位置等信息。
在网页中可以直接使用 document.querySelector
来查找 DOM 节点,在 uni-app 或小程序中则没有这样一个方法,取而代之的是调用 API uni.createSelectorQuery
创建一个查询实例(查询器),进而调用该实例的方法来查询页面中的节点元素。
<!-- pages/wiki/index.vue -->
<script setup>
?import { onMounted } from 'vue'
?// 在生命周期中调用
?onMounted(() => {
? ?// 节点查询器(实例)
? ?const selectorQuery = uni.createSelectorQuery()
console.log(selectorQuery)
})
</script>
?
<template>
?<view class="container">
? ?<view class="box">获取这个盒子的宽高、位置等信息</view>
?</view>
</template>
?
<style lang="scss">
?page {
? ?padding: 30rpx;
}
?
?.box {
? ?width: 300rpx;
? ?height: 300rpx;
? ?margin-top: 40rpx;
? ?background-color: pink;
}
</style>
?
注意事项:
onMounted
或 onReady
生命周期中调用in
方法并传入当前页面实例(后面会例子来演示)在查询节点时分成 3 种情形,获取到的结果为节点信息对象(NodesRef)
select
根据选择器的要求,只查找符合条件的第一个节点,结果是一个对象
selectAll
根据选择器的要求,查找符合条件的全部节点,结果是一个对象数组
selectViewport
特指获取视口,查找视口的尺寸、滚动位置等信息
<script setup>
?import { onMounted } from 'vue'
?
?onMounted(() => {
? ?// 1. 节点查询器(实例)
? ?const selectorQuery = uni.createSelectorQuery()
? ?
? ?// 2. 查找节点
?
? ?// 2.1 查找单个节点
? ?selectorQuery.select('.box').boundingClientRect((rect) => {
? ? ?// 获取宽高和位置
? ? ?console.log(rect)
? })
?
? ?// 2.2 查找全部节点
? ?selectorQuery.selectAll('.box').boundingClientRect((rects) => {
? ? ?// 获取宽高和位置
? ? ?console.log(rects)
? })
?
? ?// 2.3 查找视口信息
? ?selectorQuery.selectViewport().boundingClientRect((rect) => {
? ? ?console.log(rect)
? })
?
? ?// 3. 执行请求结果
? ?selectorQuery.exec()
})
</script>
?
<template>
?<view class="container">
? ?<view class="box">获取这个盒子的宽高、位置等信息</view>
? ?<view class="box"> 类选择器名称一样的另一个盒子 </view>
?</view>
</template>
?
<style lang="scss"></style>
注意事项:
exec
方法,将获取不到任何的节点信息
exec
即可,避免重复查询
exec
方法代表执行结束,因此务必保证最后再调用
节点信息对象中包含了若干的信息,根据需要调用不同的方法进行获取:
boundingClientRect
节点的宽高及位置,长度单位是 px
scrollOffset
节点滚动的位置,仅支持 scroll-view
组件或页面( viewport)
<script setup>
?import { onMounted } from 'vue'
?
?onMounted(() => {
? ?// 1. 节点查询器(实例)
? ?const selectorQuery = uni.createSelectorQuery()
? ?
? ?// 2. 查找节点
?
// 省略了部分代码
?
? ?// 2.3 查找视口信息
? ?selectorQuery.selectViewport().boundingClientRect((rect) => {
? ? ?console.log(rect)
? })
? ?
? ?selectorQuery.selectViewport().scrollOffset((offset) => {
? ? ?console.log(offset)
? })
?
? ?// 3. 执行请求结果
? ?selectorQuery.exec()
})
</script>
?
<template>
?<view class="container">
? ?<view class="box">获取这个盒子的宽高、位置等信息</view>
? ?<view class="box"> 类选择器名称一样的另一个盒子 </view>
?</view>
</template>
?
<style lang="scss"></style>
注意事项:
在 uni-app 中自定义组件的定义与 Vue 组件基本一致,不要参照原生小程序方式来定义组件。
easycom 是 uni-app 自定义的加载组件的规范,按该规范定义的组件可以实现自动导入,其规范要求如下:
components
目录下,并符合 components/组件名称/组件名称.vue
uni_modules/插件ID/components/组件名称/组件名称.vue
大家回忆一下扩展组件 uni ui 是不是就是在没有引入的情况下自动导入的,其原因就是符合 easycom 组件规范。
标签页(tabs)的切换在开发中是经常会使用到的一种交互方式,【优医咨询】项目就用到这种交互方式,接下来我们自已封装一个标签页组件,按着 easycom 的规范创建组件目录及文件:
接下来将上次课中完成的 tabs 部分的布局代码迁移到当前组件中:
<view class="custom-tabs">
?<view class="custom-tabs-bar active">
? ?<text class="tabbar-text">关注</text>
?</view>
?<view class="custom-tabs-bar">
? ?<text class="tabbar-text">推荐</text>
?</view>
?<view class="custom-tabs-bar">
? ?<text class="tabbar-text">护肤</text>
?</view>
?<view class="custom-tabs-bar">
? ?<text class="tabbar-text">减脂</text>
?</view>
?<view class="custom-tabs-bar">
? ?<text class="tabbar-text">饮食</text>
?</view>
?<view class="custom-tabs-cursor"></view>
</view>
// 自定义tabbar
.custom-tabs {
?display: flex;
?position: relative;
?padding: 0 30rpx;
}
?
.custom-tabs-bar {
?height: 80rpx;
?line-height: 80rpx