uni-app+vue3会遇到哪些问题

这篇具有很好参考价值的文章主要介绍了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 页面里使用:文章来源地址https://www.toymoban.com/news/detail-825135.html

// 导入组件实例类型
import type { CardListInstance } from '@/types/components'
// 拿到组件实例
const cardList = ref<CardListInstance>()
// 调用组件实例的方法
cardList.value?.resetData()

到了这里,关于uni-app+vue3会遇到哪些问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • uni-app vue3+ts+vite开发小程序采坑说明

    uniapp v3 搭建项目使用官方推荐命令 或者是使用 uniapp官方gitee 模板库 在项目启动前UI调用,建议使用 扩展组件(uni-ui)里面有很多组件,不能满足需求自己可以手动修改 uni_modules 为在插件市场下载出来的插件目录(uni-app官方维护的组件库,能够兼容vue3) 自动引用components文件

    2024年02月09日
    浏览(31)
  • uni-app微信小程序分享微信好友与分享到朋友圈功能【vue3+ts+uni-app+vite】

    微信小程序开发结束之后,点击右上角三个点显示: 1、创建share.ts文件 2、全局使用, 在 main.ts 里面 添加全局的 mixin 这样配置结束之后整个小程序所有页面点击右上角转发分享都走的这个文件,如果需要单个页面可以转发,可以看第三点 3、在需要的页面进行调用就行啦 a.

    2024年02月14日
    浏览(36)
  • 手写类似于BetterScroll样式的左右联动菜单 uni-app+vue3+ts (使用了script setup语法糖)

     注意:在模拟器用鼠标滚动是不会切换光标的,因为使用的是触摸滑动。【自定义类型贴在最后了】 script 部分如下:  template部分如下: scss样式:  category.d.ts main-arr.d.ts  

    2024年02月05日
    浏览(27)
  • uni-app+vue3+vite+微信小程序开发的问题点

    目录名称不能为api,否则会出现 ├F10: PM┤ [vite] getaddrinfo ENOTFOUND rivtrust.jz-xxx.xyz ,修改为_api; vue3的全局变量挂载 或者 全局变量的引入: 或者 axios在微信小程序上使用的问题: 安装模块 出现adapter is not a function的解决方法 需要axios自定义适配器配置 整体代码request.js: un

    2024年02月13日
    浏览(55)
  • uni_app+vite+vue3+ts开发小程序,解决getUserProfile()获取用户信息问题

    最近开发小程序,开发环境uni_app+vue3等。在获取小程序平台用户信息是报错: {errMsg: \\\"getUserProfile:fail must be invoked by user tap gesture\\\", errNo: 21500} 我在抖音上查了下错误码: 看到这个解释也是瞬间无语了,然后在平台查找错误,找了半天终于在vue2 升级vue3文档里面找到解决办法

    2024年02月04日
    浏览(49)
  • uni-app+vue3+ts+pinia报错【“hasInjectionContext“ is not exported by “node_modules/.store/pinia@2.1.7/n】

    【完整报错】\\\"hasInjectionContext\\\" is not exported by \\\"node_modules/.store/pinia@2.1.7/node_modules/vue-demi/lib/index.mjs\\\", imported by \\\"node_modules/.store/pinia@2.1.7/node_modules/pinia/dist/pinia.mjs\\\". 【报错原因】版本不匹配 查看package.json下pinia和vue版本 【版本参考界面】https://github.com/vuejs/pinia/blob/v2/packages/pini

    2024年04月11日
    浏览(35)
  • 如果遇到 uni-app 下载文件后缀为.bin格式问题

    使用uni-app 下载并预览文件功能,但是因为后台提供的地址是 http://10.121.2.215:8041/×××/×××/1479324207283898626 而不是带.jpg/.docx/.pdf等带后缀那种 1、导致下载的文件后缀名 是 .bin 格式 2、预览失败(打不开)或者 下载也没办法正常打开 根本的原因是 就是因为后端需要在 content

    2024年02月13日
    浏览(34)
  • uni-app:vue3 + uni-app 在微信小程序中无法使用app.component全局注册组件

    按上文中的代码执行后,会发现在微信小程序开发中全局注册的组件是无法显示的,这是uniapp的一个未解决bug, 在uniapp中出了可以通过vue实例的component方法注册全局组件外,uniapp支持另一种全局注册的方式,就是通过 easycom 扫描注册,步骤如下 easycom 的扫描流程是:通过代码

    2024年02月16日
    浏览(50)
  • VUE3、uni-app、SpringBoot登录密码加密

    aes.js import {Encrypt} from \\\'@/utils/aes.js\\\'; loginForm.value.password = Encrypt(password.value); new Aes().decrypt(loginBody.getPassword()) CryptoJS.js aes.js import {Encrypt} from \\\'@/utils/aes.js\\\' Encrypt(this.password)

    2024年02月08日
    浏览(25)
  • uni-app开发微信小程序经常遇到的一些问题及解决方案

       可以使用uni.getUserInfo接口获取用户信息。需要用户授权。   可以使用uni-app提供的页面组件内置下拉刷新功能,也可以自定义下拉刷新组件。   可以在页面onReachBottom方法中监听上拉事件,当触发上拉事件时,触发加载更多数据的操作。     可以使用uni.uploadFile接口实现图

    2024年02月14日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包