uni-app+vue3会遇到哪些问题
已经用 uni-app+vue3+ts 开发了一段时间,记录一下日常遇见的问题和解决办法
uni-app 中的单端代码
uni-app 是支持多端,如果你想让你的代码,只在部分平台使用,那么就需要用的它的单端处理语法 //#ifdef 和 //#ifndef 等。
1. //#ifdef xxx 只在xxx平台生效
//#ifdef MP-WEIXIN
menuButtonInfo = '微信'
//#endif
2. //#ifndef xxx 除了xxx平台,其他都生效
//#ifndef MP-WEIXIN
menuButtonInfo = '只要不是微信,其他都可以'
//#endif
安全边距
1. 异形屏
因为有异形手机屏的存在,最顶部有摄像头,最下面有导航条,为了避免界面内容出现在这些位置,所以每次在界面初始要设置安全边距。
<script setup lang="ts">
// 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync()
</script>
<template>
<view class="specification-panel flex-column" :style="{ paddingTop: safeAreaInsets.top + 'px' }">
<!-- 底部导航 -->
<view class="bottomNav" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }"></view>
</view>
</template>
2. 微信胶囊
由于微信小程序右上角有微信胶囊,很多时候我们为了保持界面整齐,需要获取微信胶囊的位置,来让我们得元素和它对齐。
// 微信胶囊一定处于安全位置,所以有微信胶囊就拿胶囊的位置,否则再去获取安全边距
export const safeTop = () => {
const { safeAreaInsets } = uni.getWindowInfo()
// 获取胶囊信息 https://uniapp.dcloud.net.cn/api/ui/menuButton.html#getmenubuttonboundingclientrect
let menuButtonInfo = { top: 0 }
//#ifdef MP-WEIXIN
menuButtonInfo = uni.getMenuButtonBoundingClientRect()
//#endif
const top = menuButtonInfo.top || safeAreaInsets?.top
return {
top
}
}
全局组件
全局组件 目前只能在 src/pages.json 里配置,代码如下:
// 组件自动导入
"easycom": {
// 开启自动扫描
"autoscan": true,
"custom": {
// 使用了uni-ui 规则如下配置
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue",
// 自定义组件,需要使用正则表达式
"^Weiz(.*)": "@/components/Weiz$1/index.vue"
}
}
使用的时候,直接在界面使用即可,无需再导入。
<WeizCarousel class="categories-banner" size="small" />
获取DOM信息
有的时候我们需要去拿到界面元素的相关信息,然后进行一些处理,uni-app 提供了相关API,但需要和 vue3 配合使用
<script setup lang="ts">
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
const getNodeInfo = () => {
const query = uni.createSelectorQuery().in(instance)
query
.select('.similar') // 获取界面元素,也可以传id
.boundingClientRect((data) => {
const nodeInfo: UniApp.NodeInfo = data as UniApp.NodeInfo
console.log(nodeInfo)
})
.exec()
}
</script>
是的你没看错,不需要给元素设置 ref
url 传参
url 跳转界面有两种方式,一种是使用 navigator 标签,一种是使用 uni.navigateTo 方法。
需要注意的是url有长度限制,太长的字符串会传递失败,而且参数中出现空格等特殊字符时需要对参数进行编码,如使用 encodeURIComponent 等。
1. 传递参数
uni.navigateTo({
url: 'pages/test?id=1&name=uniapp'
});
或者
<script setup lang="ts">
const item = ref({ id: 1, name: 'uniapp' })
</script>
<template>
<navigator :url="'/pages/test/test?item='+ encodeURIComponent(JSON.stringify(item))"></navigator>
</template>
2. 接受参数
在 pages/test 界面
onLoad: function(option) {
console.log(option.id, option.name)
// 如果传递的是经过编码的参数
const item = JSON.parse(decodeURIComponent(option.item));
}
父子组件通信
简单参数
子组件:
<script setup lang="ts">
// 使用 defineProps 来接受参数,非必要参数使用 xxx? 的形式
defineProps<{
title: string
subTitle?: string
}>()
</script>
<template>
<view class="weiz-title">
<view class="title">{{ title }}</view>
<view class="sub-title">{{ subTitle }}</view>
</view>
</template>
父组件:
// 由于是全局组件,所以无需再引入,如果不是全局组件,需要单独引入 <WeizTitle title="详情" />
复杂参数
如果参数比较复杂,可以直接用 TS 去定义类型,下面举例:
子组件:
<script setup lang="ts">
// 引入参数类型
import type { CategoryItem } from '@/types/api'
// 定义 props 接收数据
defineProps<{
list: CategoryItem[]
}>()
</script>
父组件:
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
// 引入数据类型
import type { CategoryItem } from '@/types/api'
// 引入接口
import { getCategoryIndexAPI } from '@/api/category'
// 定义响应式数据
const categoryList = ref<CategoryItem[]>([])
// 获取数据方法
const getCategoryList = async () => {
const res = await getCategoryIndexAPI()
// 拿到数据赋值
categoryList.value = res.result
}
// 调用方法
onLoad(() => {
getCategoryList()
})
</script>
<template>
<WeizCategory :list="categoryList" @refresh="getCategoryList" />
</template>
父调子方法
父调子需要子组件通过 defineExpose 暴露方法给父组件,然后父组件拿到子组件实例再去调用子组件方法。
1. 子组件暴露方法
// 定义方法
const getCurrentSpec = () => {
return currentSpec.value
}
// 暴露方法给父组件
defineExpose({
getCurrentSpec
})
2. 父组件拿到实例调用
可参考章节 TS 相关 - 定义组件实例类型,调用子组件需要先拿到子组件的实例,拿到实例后直接调用即可。
// 拿到子组件实例 WeizCategoryInstance 需要我们去 ts 里定义
const weizCategory = ref<WeizCategoryInstance>()
// 调用子组件实例的方法
weizCategory.value.getCurrentSpec()
子调父方法
子调父方法,需要父组件去给子组件添加自定义事件,然后子组件通过 defineEmits 去触发。
1. 父组件声明自定义事件
<script setup lang="ts">
const handleUpdate = (value: string) => {
console.log('拿到子组件的传值,并且调用了父组件', value)
}
</script>
<template>
<WeizCategory :list="categoryList" @update="handleUpdate" />
</template>
2. 子组件使用 defineEmits
<script setup lang="ts">
import { ref, defineEmits } from 'vue'
const message = ref('子组件的值')
const popupEmit = defineEmits(['update'])
function sendMessage() {
popupEmit('update', message.value)
}
</script>
<template>
<div>
<button @click="sendMessage">触发父组件方法</button>
</div>
</template>
TS 相关
定义组件实例类型
定义组件实例类型文件 xxx.d.ts
// 导入组件
import WeizCardList from '@/components/WeizCardList/index.vue'
// 什么全局类型
declare module 'vue' {
export interface GlobalComponents {
WeizCardList: typeof WeizCardList
}
}
// 导出组件实例类型, 需要用到 InstanceType
export type CardListInstance = InstanceType<typeof WeizCardList>
在 vue 页面里使用:
// 导入组件实例类型
import type { CardListInstance } from '@/types/components'
// 拿到组件实例
const cardList = ref<CardListInstance>()
// 调用组件实例的方法
cardList.value?.resetData()
uni-app+vue3会遇到哪些问题的更多相关文章
- uni app中使用自定义图标库
项目中难免会用到自定义图标,那在uni app中应该怎么使用呢? 首先, 将图标目录放在static资源目录下: 在main.js中引入就可以全局使用了 import '@/static/icon-o ...
- uni app 零基础小白到项目实战-1
uni-app是一个使用vue.js开发跨平台应用的前端框架. 开发者通过编写vue.js代码,uni-app将其编译到Ios,android,微信小程序等多个平台,保证其正确并达到优秀体验. Uni ...
- uni app以及小程序 --环境搭建以及编辑器
https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html 根据以上网页下载自己电脑相应的版本的微信开发者工具(目录 ...
- uni app canvas 不生效
canvas 创建canvas绘图上下文. <canvas style="width: 300px; height: 200px;" canvas-id="firs ...
- uni app 零基础小白到项目实战2
<template> <scroll-view v-for="(card, index) in list" :key="index"> ...
- uni app 零基础小白到项目实战
$emit 子组件传给父组件 $ref 父组件操作子组件 公用模板 uni-app全局变量的几种实现方法 const websiteUrl = 'http' const now = Date.now ...
- uni app中关于图片的分包加载
因为在项目中使用了大量的静态资源图片,使得主包体积过大, 而把这些图片全部放到服务器又有点麻烦,就想能不能把图片也分包,但是直接放在分包下的话导致图片资源找不到了, 在社区中看到大佬分享的十分有用,特 ...
- 5G到来,App的未来,是JavaScript,Flutter还是Native ?
Native App React Native(RN)发布于2015年,也是使用JavaScript语言进行跨平台APP的开发.与H5开发不同的是,它使用JS桥接技术在运行时编译成各个平台的Nativ ...
- Vue3实战系列:Vue3.0 + Vant3.0 搭建种子项目
最近在用 Vue3 写一个开源的商城项目,开源后让大家也可以用现成的 Vue3 大型商城项目源码来练练手,目前处于开发阶段,过程中用到了 Vant3.0,于是就整理了这篇文章来讲一下如何使用 Vue3 ...
- vue3.0API详解
Vue 3.0 于 2020-09-18 发布了,使用了 Typescript 进行了大规模的重构,带来了 Composition API RFC 版本,类似 React Hook 一样的写 Vue, ...
随机推荐
- Codeforces Round #725 (Div. 3) A~G 题解记录
补题链接:Here 1538A. Stone Game 数组 \(a\) 的大小为 \(n\) ,请问每次可以删除最左和最右侧的元素,请问最少执行多少次能删除掉数组中的最大值和最小值 (\(1\le ...
- Vue和Android交互,Android回调Vue的方法
https://blog.csdn.net/Zhizhiwei/article/details/80425204 Android webview 与 js(Vue) 交互 https://blog.c ...
- 全流程机器视觉工程开发(一)环境准备,paddledetection和labelme
前言 我现在在准备做一个全流程的机器视觉的工程,之前做了很多理论相关的工作.大概理解了机器视觉的原理,然后大概了解了一下,我发现现在的库其实已经很发展了,完全不需要用到非常多的理论,只需要知道开发过程 ...
- 如何开发一套苹果cms前端模板
本文运用了苹果cms官网的模板开发教程,开发了一套苹果cms的前端模板,感兴趣的同学可以去github下载使用. 什么是模板 模板是网站的主题外观,也被称为主题或皮肤.通过使用不同的模板,网站的前台可 ...
- ASIC 功能验证SVTB
System Verilog进行验证是可以不综合的 发现DUT中的功能问题 预备知识:Linux/verilog/gvim System Verilog学习目录 System Verilog Test ...
- Oracle数据库期末考试--学堂在线
1.单选题 (2分) 在Oracle数据库中,下面哪类索引最适合SQL范围查找? 2.单选题 (2分) 在创建Oracle数据库表时,下面哪个元素不出现在CREATE TABLE语句中? 3.单选题 ...
- JMS微服务开发示例(三)使用分布式锁和编写定时任务
分布式锁 在Controller当中,提供了分布式锁的功能,代码如下: class HelloworldController : MicroServiceControllerBase { static ...
- [转帖]【我和CloudQuery 的故事】安装部署CloudQuery 初体验—-前篇
https://www.modb.pro/db/1694256553947910144 一.前言 在日常数据库运维中,为连接多种数据库,经常要安装不同的客户端,非常繁琐,且占用大量存储空间.如果能有一 ...
- [转帖]oracle数据库中RMAN备份格式化format解释
格式化解释: 使用格式串 更改格式命令: RMAN> configure channel device type disk format ' E:\app\Administrator\db_ba ...
- [转帖]shell脚本字符串截取的8种方法
https://www.cnblogs.com/zwgblog/p/6031256.html 假设有变量 var=http://www.aaa.com/123.htm. 1. # 号截取,删除左边字符 ...