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 MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...