uni-app+vue3會遇到哪些問題

uni-app 中的單端代碼

uni-app 是支持多端,如果你想讓你的代碼荣刑,只在部分平臺使用合溺,那么就需要用的它的單端處理語法 //#ifdef//#ifndef 等。

  1. //#ifdef xxx只在xxx平臺生效
//#ifdef MP-WEIXIN
menuButtonInfo = '微信'
//#endif
  1. //#ifndef xxx除了xxx平臺则果,其他都生效
//#ifndef MP-WEIXIN
menuButtonInfo = '只要不是微信,其他都可以'
//#endif

安全邊距

  1. 異形屏
    因?yàn)橛挟愋问謾C(jī)屏的存在顽决,最頂部有攝像頭短条,最下面有導(dǎo)航條,為了避免界面內(nèi)容出現(xiàn)在這些位置才菠,所以每次在界面初始要設(shè)置安全邊距茸时。
<script setup lang="ts">
// 獲取屏幕邊界到安全區(qū)域距離
const { safeAreaInsets } = uni.getSystemInfoSync()
</script>
 
<template>
  <view class="specification-panel flex-column" :style="{ paddingTop: safeAreaInsets.top + 'px' }">
    <!-- 底部導(dǎo)航 -->
    <view class="bottomNav" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }"></view>
  </view>
</template>
  1. 微信膠囊
    由于微信小程序右上角有微信膠囊,很多時候我們?yōu)榱吮3纸缑嬲R赋访,需要獲取微信膠囊的位置可都,來讓我們得元素和它對齊。
// 微信膠囊一定處于安全位置蚓耽,所以有微信膠囊就拿膠囊的位置渠牲,否則再去獲取安全邊距
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 里配置,代碼如下:

// 組件自動導(dǎo)入
"easycom": {
  // 開啟自動掃描
  "autoscan": true,
  "custom": {
    // 使用了uni-ui 規(guī)則如下配置
    "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue",
    // 自定義組件步悠,需要使用正則表達(dá)式
    "^Weiz(.*)": "@/components/Weiz$1/index.vue"
  }
}

使用的時候签杈,直接在界面使用即可,無需再導(dǎo)入。

<WeizCarousel class="categories-banner" size="small" />

獲取DOM信息

有的時候我們需要去拿到界面元素的相關(guān)信息答姥,然后進(jìn)行一些處理铣除,uni-app 提供了相關(guān)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>

是的你沒看錯尚粘,不需要給元素設(shè)置ref

url 傳參

url 跳轉(zhuǎn)界面有兩種方式,一種是使用 navigator標(biāo)簽敲长,一種是使用 uni.navigateTo方法郎嫁。
需要注意的是url有長度限制,太長的字符串會傳遞失敗祈噪,而且參數(shù)中出現(xiàn)空格等特殊字符時需要對參數(shù)進(jìn)行編碼泽铛,如使用 encodeURIComponent等。

  1. 傳遞參數(shù)
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>
  1. 接受參數(shù)
    pages/test界面
onLoad: function(option) {
  console.log(option.id, option.name)
  // 如果傳遞的是經(jīng)過編碼的參數(shù)
  const item = JSON.parse(decodeURIComponent(option.item));
}

父子組件通信

簡單參數(shù)
子組件:

<script setup lang="ts">
  // 使用 defineProps 來接受參數(shù)钳降,非必要參數(shù)使用 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>

父組件:

// 由于是全局組件厚宰,所以無需再引入腌巾,如果不是全局組件遂填,需要單獨(dú)引入 <WeizTitle title="詳情" />

復(fù)雜參數(shù)
如果參數(shù)比較復(fù)雜,可以直接用 TS 去定義類型澈蝙,下面舉例:

子組件:

<script setup lang="ts">
  // 引入?yún)?shù)類型
  import type { CategoryItem } from '@/types/api'
 
  // 定義 props 接收數(shù)據(jù)
  defineProps<{
    list: CategoryItem[]
  }>()
</script>

父組件:

<script setup lang="ts">
  import { ref } from 'vue'
  import { onLoad } from '@dcloudio/uni-app'
  // 引入數(shù)據(jù)類型
  import type { CategoryItem } from '@/types/api'
  // 引入接口
  import { getCategoryIndexAPI } from '@/api/category'
 
  // 定義響應(yīng)式數(shù)據(jù)
  const categoryList = ref<CategoryItem[]>([])
  // 獲取數(shù)據(jù)方法
  const getCategoryList = async () => {
    const res = await getCategoryIndexAPI()
    // 拿到數(shù)據(jù)賦值
    categoryList.value = res.result
  }
  // 調(diào)用方法
  onLoad(() => {
    getCategoryList()
  })
</script>
 
<template>
  <WeizCategory :list="categoryList" @refresh="getCategoryList" />
</template>

父調(diào)子方法
父調(diào)子需要子組件通過defineExpose暴露方法給父組件吓坚,然后父組件拿到子組件實(shí)例再去調(diào)用子組件方法。

  1. 子組件暴露方法
// 定義方法
const getCurrentSpec = () => {
  return currentSpec.value
}
// 暴露方法給父組件
defineExpose({
  getCurrentSpec
})
  1. 父組件拿到實(shí)例調(diào)用
    可參考章節(jié)TS 相關(guān) - 定義組件實(shí)例類型灯荧,調(diào)用子組件需要先拿到子組件的實(shí)例礁击,拿到實(shí)例后直接調(diào)用即可。
// 拿到子組件實(shí)例 WeizCategoryInstance 需要我們?nèi)?ts 里定義
const weizCategory = ref<WeizCategoryInstance>()
// 調(diào)用子組件實(shí)例的方法
weizCategory.value.getCurrentSpec()

子調(diào)父方法
子調(diào)父方法逗载,需要父組件去給子組件添加自定義事件哆窿,然后子組件通過 defineEmits 去觸發(fā)。

  1. 父組件聲明自定義事件
<script setup lang="ts">
  const handleUpdate = (value: string) => {
    console.log('拿到子組件的傳值厉斟,并且調(diào)用了父組件', value)
  }
</script>
 
<template>
  <WeizCategory :list="categoryList" @update="handleUpdate" />
</template>
  1. 子組件使用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">觸發(fā)父組件方法</button>
  </div>
</template>

TS 相關(guān)

定義組件實(shí)例類型
定義組件實(shí)例類型文件xxx.d.ts

// 導(dǎo)入組件
import WeizCardList from '@/components/WeizCardList/index.vue'
// 什么全局類型
declare module 'vue' {
  export interface GlobalComponents {
    WeizCardList: typeof WeizCardList
  }
}
// 導(dǎo)出組件實(shí)例類型, 需要用到 InstanceType
export type CardListInstance = InstanceType<typeof WeizCardList>
在 vue 頁面里使用:

// 導(dǎo)入組件實(shí)例類型
import type { CardListInstance } from '@/types/components'
// 拿到組件實(shí)例
const cardList = ref<CardListInstance>()
// 調(diào)用組件實(shí)例的方法
cardList.value?.resetData()

謝謝觀看挚躯,如果覺得可以就給個小贊!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末擦秽,一起剝皮案震驚了整個濱河市码荔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌感挥,老刑警劉巖缩搅,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異触幼,居然都是意外死亡硼瓣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門置谦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來堂鲤,“玉大人噪猾,你說我怎么就攤上這事≈郏” “怎么了袱蜡?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長慢宗。 經(jīng)常有香客問我坪蚁,道長,這世上最難降的妖魔是什么镜沽? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任敏晤,我火速辦了婚禮,結(jié)果婚禮上缅茉,老公的妹妹穿的比我還像新娘嘴脾。我一直安慰自己,他們只是感情好蔬墩,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布译打。 她就那樣靜靜地躺著,像睡著了一般拇颅。 火紅的嫁衣襯著肌膚如雪奏司。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天樟插,我揣著相機(jī)與錄音韵洋,去河邊找鬼。 笑死黄锤,一個胖子當(dāng)著我的面吹牛搪缨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鸵熟,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼副编,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了旅赢?” 一聲冷哼從身側(cè)響起齿桃,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎煮盼,沒想到半個月后短纵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡僵控,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年香到,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡悠就,死狀恐怖千绪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情梗脾,我是刑警寧澤荸型,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站炸茧,受9級特大地震影響瑞妇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜梭冠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一辕狰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧控漠,春花似錦蔓倍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至毙驯,卻和暖如春倒堕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爆价。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留媳搪,地道東北人铭段。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像秦爆,于是被迫代替她去往敵國和親序愚。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容