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