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

来源:https://www.cnblogs.com/weizwz/p/18002189
-Advertisement-
Play Games

已經用 uni-app+vue3+ts 開發了一段時間,記錄一下日常遇見的問題和解決辦法 uni-app 中的單端代碼 uni-app 是支持多端,如果你想讓你的代碼,只在部分平臺使用,那麼就需要用的它的單端處理語法 //#ifdef 和 //#ifndef 等。 1. //#ifdef xxx 只 ...


已經用 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()

文章作者:唯之為之

文章出處:https://www.cnblogs.com/weizwz/p/18002189

版權聲明:本博客所有文章除特別聲明外,均採用 「CC BY-NC-SA 4.0 DEED」 國際許可協議,轉載請註明出處!

內容粗淺,如有錯誤,歡迎大佬批評指正


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我們是袋鼠雲數棧 UED 團隊,致力於打造優秀的一站式數據中台產品。我們始終保持工匠精神,探索前端道路,為社區積累並傳播經驗價值。 本文作者:佳嵐 The more your tests resemble the way your software is used, the more confide ...
  • 聽我說 從 條件渲染 那一篇,我學習到瞭如何用Vue對dom節點根據條件顯示 但單單有條件還不夠啊,有時候數據是一大坨一大坨的數據,如果Vue不提供咱要麼使用“v-html” 要麼就沒辦法實現 v-html又感覺太low了,Vue提供了另外的指令更好的實現,那便是:列表渲染 列表渲染:v-for 簡 ...
  • 與其說是年終總結,更像是一場回顧,看看這一年 Fantastic-admin 都做了哪些與眾不同的功能,也給大家提供一些創造思路。 ...
  • 回顧 大致掌握了上一節的 插值語法 我已經可以把想要的數據顯示到頁面上,並且僅需要修改變數,頁面就會跟著實時改變 但如果對於已經熟悉前端的人來說,單單有數據還是不太行,還需要css對數據進行樣式的修飾,讓頁面更加好看 所本篇將記錄記錄 Class 與 Style 綁定 的學習 總所周知,想要給DOM ...
  • 回顧 大致掌握了上一節的 插值語法 我已經可以把想要的數據顯示到頁面上,並且僅需要修改變數,頁面就會跟著實時改變 但如果對於已經熟悉前端的人來說,單單有數據還是不太行,還需要css對數據進行樣式的修飾,讓頁面更加好看 所本篇將記錄記錄 Class 與 Style 綁定 的學習 總所周知,想要給DOM ...
  • `async` 和 `defer` 是兩種不同的JavaScript特性,它們的主要區別在於它們的執行順序和時間點。 `async` 意味著函數或代碼塊會被非同步執行。當瀏覽器遇到帶有 `async` 屬性的資源時,它會立即開始下載該資源,同時繼續載入頁面。這樣可以避免由於同步執行而導致的頁面載入阻 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 如何實現一個雨滴落下效果 前言 下雨天坐在車窗前,看著雨滴順著車窗漸漸落下,這一唯美的場景,忍不住想記錄下來。最近在糾結電腦壁紙時,無意間看到有類似的場景,可以將自己喜歡的壁紙加上這種效果。作為多年切圖仔,不由地想到了用css動畫應該可以 ...
  • 描述 這是一個用於 Tampermonkey 或其他支持用戶腳本的瀏覽器擴展的油猴腳本。 看到論壇經常有小伙伴們需要下載某創力文檔-某人文庫一些免費文檔,但是相關網站瀏覽體驗不好各種廣告,各種登錄驗證,需要很多步驟才能下載文檔,該腳本就是為瞭解決您的煩惱而誕生,儘可能做到自動化。 安裝 安裝 Tam ...
一周排行
    -Advertisement-
    Play Games
  • 前言 微服務架構已經成為搭建高效、可擴展系統的關鍵技術之一,然而,現有許多微服務框架往往過於複雜,使得我們普通開發者難以快速上手並體驗到微服務帶了的便利。為瞭解決這一問題,於是作者精心打造了一款最接地氣的 .NET 微服務框架,幫助我們輕鬆構建和管理微服務應用。 本框架不僅支持 Consul 服務註 ...
  • 先看一下效果吧: 如果不會寫動畫或者懶得寫動畫,就直接交給Blend來做吧; 其實Blend操作起來很簡單,有點類似於在操作PS,我們只需要設置關鍵幀,滑鼠點來點去就可以了,Blend會自動幫我們生成我們想要的動畫效果. 第一步:要創建一個空的WPF項目 第二步:右鍵我們的項目,在最下方有一個,在B ...
  • Prism:框架介紹與安裝 什麼是Prism? Prism是一個用於在 WPF、Xamarin Form、Uno 平臺和 WinUI 中構建鬆散耦合、可維護和可測試的 XAML 應用程式框架 Github https://github.com/PrismLibrary/Prism NuGet htt ...
  • 在WPF中,屏幕上的所有內容,都是通過畫筆(Brush)畫上去的。如按鈕的背景色,邊框,文本框的前景和形狀填充。藉助畫筆,可以繪製頁面上的所有UI對象。不同畫筆具有不同類型的輸出( 如:某些畫筆使用純色繪製區域,其他畫筆使用漸變、圖案、圖像或繪圖)。 ...
  • 前言 嗨,大家好!推薦一個基於 .NET 8 的高併發微服務電商系統,涵蓋了商品、訂單、會員、服務、財務等50多種實用功能。 項目不僅使用了 .NET 8 的最新特性,還集成了AutoFac、DotLiquid、HangFire、Nlog、Jwt、LayUIAdmin、SqlSugar、MySQL、 ...
  • 本文主要介紹攝像頭(相機)如何採集數據,用於類似攝像頭本地顯示軟體,以及流媒體數據傳輸場景如傳屏、視訊會議等。 攝像頭採集有多種方案,如AForge.NET、WPFMediaKit、OpenCvSharp、EmguCv、DirectShow.NET、MediaCaptre(UWP),網上一些文章以及 ...
  • 前言 Seal-Report 是一款.NET 開源報表工具,擁有 1.4K Star。它提供了一個完整的框架,使用 C# 編寫,最新的版本採用的是 .NET 8.0 。 它能夠高效地從各種資料庫或 NoSQL 數據源生成日常報表,並支持執行複雜的報表任務。 其簡單易用的安裝過程和直觀的設計界面,我們 ...
  • 背景需求: 系統需要對接到XXX官方的API,但因此官方對接以及管理都十分嚴格。而本人部門的系統中包含諸多子系統,系統間為了穩定,程式間多數固定Token+特殊驗證進行調用,且後期還要提供給其他兄弟部門系統共同調用。 原則上:每套系統都必須單獨接入到官方,但官方的接入複雜,還要官方指定機構認證的證書 ...
  • 本文介紹下電腦設備關機的情況下如何通過網路喚醒設備,之前電源S狀態 電腦Power電源狀態- 唐宋元明清2188 - 博客園 (cnblogs.com) 有介紹過遠程喚醒設備,後面這倆天瞭解多了點所以單獨加個隨筆 設備關機的情況下,使用網路喚醒的前提條件: 1. 被喚醒設備需要支持這WakeOnL ...
  • 前言 大家好,推薦一個.NET 8.0 為核心,結合前端 Vue 框架,實現了前後端完全分離的設計理念。它不僅提供了強大的基礎功能支持,如許可權管理、代碼生成器等,還通過採用主流技術和最佳實踐,顯著降低了開發難度,加快了項目交付速度。 如果你需要一個高效的開發解決方案,本框架能幫助大家輕鬆應對挑戰,實 ...