国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

網(wǎng)站開(kāi)發(fā)有那些費(fèi)用推廣互聯(lián)網(wǎng)推廣

網(wǎng)站開(kāi)發(fā)有那些費(fèi)用,推廣互聯(lián)網(wǎng)推廣,做銷售的如何在網(wǎng)站,阿里云備案網(wǎng)站建設(shè)方案書(shū)目錄 問(wèn):uni-app 組件庫(kù)的解決方案?(xx 分鐘) 必答? 加分? 深入? 再深入? 參考鏈接? 問(wèn):在 uni-app 中,如何進(jìn)行全局狀態(tài)管理?請(qǐng)介紹一下你對(duì) Vuex 和 Pinia 的了解。? 必答? 加…

目錄

問(wèn):uni-app 組件庫(kù)的解決方案?(xx 分鐘)

必答?

加分?

深入?

再深入?

參考鏈接?

問(wèn):在 uni-app 中,如何進(jìn)行全局狀態(tài)管理?請(qǐng)介紹一下你對(duì) Vuex 和 Pinia 的了解。?

必答?

加分?

參考鏈接?

問(wèn):uni-app 中的組件和 Vue.js 中的組件有什么區(qū)別??

必答?

加分?

深入?

參考鏈接?

問(wèn):請(qǐng)介紹一下 uni-app 的網(wǎng)絡(luò)請(qǐng)求庫(kù) uni.request 與 axios 相比,它有哪些優(yōu)缺點(diǎn)??

必答?

加分?

參考鏈接?

問(wèn):為什么用 VSCode 開(kāi)發(fā) uni-app 項(xiàng)目而不使用 Hbuilder??

必答?

加分?

參考鏈接?

問(wèn):如何在 uni-app 中實(shí)現(xiàn)自定義導(dǎo)航欄??

必答?

加分?

深入?

參考鏈接?

問(wèn):如何在 uni-app 項(xiàng)目中進(jìn)行代碼優(yōu)化或性能優(yōu)化??

必答?

加分?

深入?

再深入-防抖和節(jié)流?

參考鏈接

?uni-app 中,如何實(shí)現(xiàn)下拉刷新和上拉加載更多功能??

必答-下拉刷新?

必答-分頁(yè)加載?

如何在 uni-app 中處理表單元素??

必答?

加分-表單校驗(yàn)?

參考鏈接?

問(wèn):請(qǐng)談?wù)勀阍谑褂?uni-app 過(guò)程中遇到的問(wèn)題,以及如何解決它們。?

必答?

參考鏈接?

問(wèn):請(qǐng)簡(jiǎn)述代碼規(guī)范在團(tuán)隊(duì)協(xié)作中的重要性??

必答?

深入?

問(wèn):請(qǐng)介紹 uni-app 中的條件編譯和平臺(tái)差異化處理??

必答?

加分?


問(wèn):uni-app 組件庫(kù)的解決方案?(xx 分鐘)

必答?

(總)我們項(xiàng)目使用的是?uni-ui?組件庫(kù),這是官方出品的組件庫(kù),有官方的技術(shù)支持和持續(xù)維護(hù)并且 uni-ui 組件庫(kù)比較相對(duì)精簡(jiǎn),組件自動(dòng)按需導(dǎo)入,有利于減小項(xiàng)目體積。

(分)兩個(gè)核心步驟是:

  1. 安裝?@dcloudio/uni-ui(組件庫(kù)) 和?scss。
  2. 在?pages.json?文件中配置?easycom?規(guī)則,實(shí)現(xiàn)?uni-ui?組件的自動(dòng)導(dǎo)入和注冊(cè)。

加分?

雖然?uni-ui官方并沒(méi)有類型聲明文件,但我們?cè)陧?xiàng)目中還配置了?uni-ui?的?TS?組件類型支持,可以校驗(yàn)組件的屬性,類型更安全,書(shū)寫(xiě)時(shí)也有代碼提示。

實(shí)現(xiàn)類型支持其實(shí)也就多了兩個(gè)步驟:

  1. 安裝?@uni-helper/uni-ui-type?第三方類型聲明文件。
  2. 再配置?tsconfig.json,將類型聲明文件添加到?types?數(shù)組就可以了。

深入?

TIP

準(zhǔn)備充分的同學(xué),可以自己融入加分回答中,或者引導(dǎo)面試官往自己準(zhǔn)備的方向提問(wèn)。

其實(shí)?uni-app?和?uni-ui?目前還沒(méi)有 TS 官方支持,所以默認(rèn)情況下組件是沒(méi)有類型校驗(yàn)的,如果自己手寫(xiě)組件類型聲明效率太低了?;谶@個(gè)問(wèn)題,我們團(tuán)隊(duì)做過(guò)一些充分的調(diào)研,uni-helper?雖然是非官方組織,但這個(gè)第三方組織是 uni-app 生態(tài)類型聲明文件做的非常好,更新頻率也非常及時(shí)。其實(shí)在我們開(kāi)發(fā)的過(guò)程中遇到些小問(wèn)題,我們?cè)?github?倉(cāng)庫(kù)提的?issue?也有及時(shí)解決。最后,我們也保持關(guān)注官方文檔和更新,確保項(xiàng)目的穩(wěn)定性和兼容性。

再深入?

  • ? 問(wèn): 為什么項(xiàng)目中使用?uni-ui?而不選擇?uview-ui。

  • 🙋?♂? 答: 我們團(tuán)隊(duì)主要是考慮以下三點(diǎn)做出的選擇:

    1. uni-ui?是官方出品的組件庫(kù),有官方的技術(shù)支持和持續(xù)維護(hù)(最重要)。
    2. uni-ui?比較相對(duì)精簡(jiǎn),有利于減小項(xiàng)目體積。
    3. uview-ui?暫不支持?Vue3?開(kāi)發(fā),稍微落后。

當(dāng)然?uview-ui?組件庫(kù)也不錯(cuò),是目前?uni-app?插件市場(chǎng)下載量最高的第三方 Vue2 組件庫(kù),社區(qū)中也有熱心的小伙伴為?uview-ui?做了 Vue3 版,但目前可能作者太忙了,處于沒(méi)更新?tīng)顟B(tài),不穩(wěn)定,所以綜合考慮,我們選擇官方維護(hù)的?uni-ui

參考鏈接?

  • uni-ui 組件庫(kù)
  • uview-ui 組件庫(kù)
  • vk-uview-ui 組件庫(kù)-不更新
  • uni-helper 組織
  • uni-ui-types 類型聲明
  • uni-helper 組織的 VS Code 插件-下載量 14k
  • uView,有計(jì)劃支持 vue3.0 嗎?

類似問(wèn)題

  • 如何在 uni-app 中引入和使用第三方組件庫(kù)?
  • 請(qǐng)介紹幾個(gè)常用的 uni-app 組件庫(kù),以及它們的特點(diǎn)和使用場(chǎng)景?
  • 組件庫(kù)的 TS 類型怎么處理?

問(wèn):在 uni-app 中,如何進(jìn)行全局狀態(tài)管理?請(qǐng)介紹一下你對(duì) Vuex 和 Pinia 的了解。?

必答?

(總)我們項(xiàng)目使用的是 Pinia 進(jìn)行全局狀態(tài)管理,Vuex 或 Pinia 都是官方提供的狀態(tài)管理庫(kù)。

(分)我先說(shuō)一下我對(duì) VueX 的了解: Vuex 采用單一狀態(tài)樹(shù)的概念,將全局狀態(tài)集中管理,方便追蹤狀態(tài)變化。Vuex 主要包含以下幾個(gè)核心概念:

  • State:用于存儲(chǔ)全局狀態(tài)。
  • Getter:用于從 State 中派生出一些狀態(tài),例如計(jì)算屬性。
  • Mutation:用于同步修改 State,嚴(yán)格遵循單向數(shù)據(jù)流。
  • Action:用于異步操作,可以包含異步 API 請(qǐng)求、異步提交 Mutation 等。

我對(duì) Pinia 的了解是 Pinia 可以理解為就是?Vuex5,是一個(gè)輕量級(jí)的、兼容 Vue 3 和 Vue 2 的狀態(tài)管理庫(kù)。Pinia 和 VueX 主要區(qū)別是廢棄了經(jīng)常被認(rèn)為是極其冗余的 mutation,Pinia 主要包含以下幾個(gè)核心概念:

  • Store:用于存儲(chǔ)全局狀態(tài)和處理狀態(tài)變化的方法,類似于 Vuex 的 State、Getter 和 Action 的集合。
  • 可以創(chuàng)建和使用多個(gè) Store 實(shí)例,每個(gè) Store 都有自己獨(dú)立的狀態(tài)和方法。

(總)所以我們項(xiàng)目最終選擇的是 Pinia 進(jìn)行全局狀態(tài)管理。

加分?

(總)其實(shí)我們的項(xiàng)目還配置了 pinia 的持久化存儲(chǔ)方案。

(分)我們用到了?pinia-plugin-persistedstate?插件實(shí)現(xiàn)持久化,周下載量?61k,但是這個(gè)插件默認(rèn)使用?localStorage?實(shí)現(xiàn)持久化,小程序端不兼容,所以必須修改一下配置,替換為?uni-app?支持多端的持久化 API,也就是?uni.setStorageSync()?和?uni.getStorageSync()。

(總)持久化存儲(chǔ)配置完成后,就會(huì)自動(dòng)將用戶數(shù)據(jù)保存在客戶端,即使用戶關(guān)閉了小程序,數(shù)據(jù)依然可以保留。

配置參考

// stores/modules/member.ts
export const useMemberStore = defineStore('member',() => {//…省略},{// 配置持久化persist: {// 調(diào)整為兼容多端的APIstorage: {setItem(key, value) {uni.setStorageSync(key, value) },getItem(key) {return uni.getStorageSync(key) },},},},
)

?

參考鏈接?

  • Vuex 官方文檔
  • Pinia 官方文檔
  • Pinia 對(duì)比 Vuex 3.x/4.x 官方說(shuō)明
  • pinia-plugin-persistedstate 插件的 storage 配置

類似問(wèn)題

  • 在 uni-app 中如何實(shí)現(xiàn)全局狀態(tài)管理?
  • 在 uni-app 中如何實(shí)現(xiàn)持久化存儲(chǔ)?

問(wèn):uni-app 中的組件和 Vue.js 中的組件有什么區(qū)別??

必答?

(總)uni-app 是基于 Vue.js 構(gòu)建的跨平臺(tái)開(kāi)發(fā)框架,因此?uni-app 中的組件與 Vue.js 中的組件在很多方面是相似的。然而,由于 uni-app 需要支持多個(gè)平臺(tái),包括微信小程序、App 端和 H5 端,所以在某些方面會(huì)有一些差異。

(分)根據(jù)自身理解,選其中幾點(diǎn)回答即可:

以下是 uni-app 中的組件與 Vue.js 中的組件的一些主要區(qū)別:

  1. 跨平臺(tái):Vue.js 主要用于開(kāi)發(fā)網(wǎng)頁(yè)應(yīng)用,而 uni-app 可以讓你用同一套代碼開(kāi)發(fā)微信小程序、App、H5 等多個(gè)平臺(tái)的應(yīng)用。

  2. 基礎(chǔ)組件:uni-app 提供了一套與 Vue.js 不同的基礎(chǔ)組件。這些組件是為了適應(yīng)不同平臺(tái)的 UI 要求而設(shè)計(jì)的,它們?cè)谖⑿判〕绦?、App 端和 H5 端上有統(tǒng)一的表現(xiàn)。在使用這些組件時(shí),需要注意它們?cè)诓煌脚_(tái)之間的差異,封裝自定義組件的時(shí)候更推薦?<view>、<text>?等基礎(chǔ)組件,而非?<div>、<span>。

  3. 生命周期:雖然 uni-app 和 Vue.js 的組件都有生命周期鉤子,但是 uni-app 為了適應(yīng)不同平臺(tái)而引入了一些額外的生命周期鉤子,例如?onLaunch、onShow?和?onHide。

  4. 樣式差異:某些 CSS 選擇器不受支持如?*?通配符選擇器。此外,uni-app 支持一種叫做?rpx?的相對(duì)單位,它可以自動(dòng)適應(yīng)不同屏幕尺寸。

  5. 條件編譯:由于 uni-app 支持多個(gè)平臺(tái),所以提供了條件編譯功能。開(kāi)發(fā)者可以通過(guò)條件編譯在特定平臺(tái)上使用平臺(tái)特有的 API 或組件,從而實(shí)現(xiàn)平臺(tái)相關(guān)的功能。

(總)總的來(lái)說(shuō),uni-app 和 Vue.js 的組件在很多方面是相似的,但是由于 uni-app 需要支持多個(gè)平臺(tái),所以在一些細(xì)節(jié)上會(huì)有所區(qū)別,平時(shí)開(kāi)發(fā)時(shí)要注意平臺(tái)相關(guān)的組件、生命周期、樣式的差異。

加分?

可以展開(kāi) uni-app 生命周期,分為三部分:

  • 應(yīng)用生命周期:與?小程序?應(yīng)用的生命周期一致(onLaunch、onShow、onHide 等)
  • 頁(yè)面生命周期:與?小程序?頁(yè)面的生命周期一致(onLoad、onUnload、onShow 等)
  • 組件生命周期:與?Vue.js?組件的生命周期一致(mounted、created 等)

我們的購(gòu)物車頁(yè)面需要借助?onShow?生命周期鉤子獲取最新的購(gòu)物車列表數(shù)據(jù),因?yàn)樵谏唐吩斍轫?yè)中進(jìn)行添加購(gòu)物車操作。添加成功后,打開(kāi)購(gòu)物車頁(yè)面應(yīng)展示最新的購(gòu)物車數(shù)據(jù)。因此,每次?購(gòu)物車頁(yè)面 onShow?時(shí),都應(yīng)獲取最新的購(gòu)物車列表數(shù)據(jù)。收貨地址列表頁(yè)同理。

深入?

(總)小程序是一個(gè)獨(dú)立的應(yīng)用平臺(tái),有自己的一套生命周期,如 onLaunch、onShow、onHide,在 uni-app 項(xiàng)目還支持 Vue 的生命周期鉤子。

(分)

  • onLaunch?生命周期鉤子在 App.vue 根組件中就類似?created?或?mounted?鉤子。

  • Vue.js?本身并沒(méi)有提供?onShow?和?onHide?生命周期鉤子,但是可以通過(guò)監(jiān)聽(tīng)頁(yè)面的?visibilitychange?事件來(lái)模擬實(shí)現(xiàn)這兩個(gè)鉤子。從而在一定程度上模擬 onShow 和 onHide 的行為。

(總)我們的 uni-app 項(xiàng)目主要是做小程序端,所以我們的頁(yè)面組件優(yōu)先使用小程序的生命周期鉤子,也就是 onShow、onHide 這些,普通組件就用 Vue 生命周期鉤子。

參考代碼

mounted() {document.addEventListener('visibilitychange', this.handleVisibilityChange);
},
beforeDestroy() {document.removeEventListener('visibilitychange', this.handleVisibilityChange);
},
methods: {handleVisibilityChange() {if (document.hidden) {this.onHide();} else {this.onShow();}},onShow() {console.log('頁(yè)面顯示');},onHide() {console.log('頁(yè)面隱藏');}
}

這樣,當(dāng)頁(yè)面變?yōu)殡[藏狀態(tài)時(shí),onHide?方法會(huì)被調(diào)用;當(dāng)頁(yè)面重新顯示時(shí),onShow?方法會(huì)被調(diào)用。

注意,在組件銷毀時(shí),要記得移除?visibilitychange?事件監(jiān)聽(tīng),以避免內(nèi)存泄漏。

參考鏈接?

  • uni-app 應(yīng)用生命周期
  • uni-app 頁(yè)面生命周期
  • uni-app 組件生命周期
  • WebAPI - visibilitychange 事件

類似問(wèn)題

  • uni-app 與 Vue 區(qū)別?
  • 在 uni-app 中實(shí)現(xiàn)自定義組件,有什么區(qū)別嗎?
  • 在 uni-app 中如何處理 CSS 樣式的差異?
  • 請(qǐng)介紹 uni-app 的生命周期函數(shù),以及它們?cè)诓煌脚_(tái)下的差異。
  • 談?wù)?uni-app 組件的生命周期,以及它們與 Vue.js 組件生命周期的異同。
  • 如何實(shí)現(xiàn) uni-app 中的跨平臺(tái)開(kāi)發(fā)?請(qǐng)談?wù)?uni-app 的條件編譯。

?

問(wèn):請(qǐng)介紹一下 uni-app 的網(wǎng)絡(luò)請(qǐng)求庫(kù) uni.request 與 axios 相比,它有哪些優(yōu)缺點(diǎn)??

必答?

(總)uni-app 的?uni.request?是一個(gè)用于發(fā)起網(wǎng)絡(luò)請(qǐng)求的 API。它是 uni-app 框架內(nèi)置的網(wǎng)絡(luò)請(qǐng)求庫(kù),兼容多端(包括小程序、App、H5 等),無(wú)需額外安裝。使用?uni.request?可以發(fā)起 GET、POST、PUT、DELETE 等 HTTP 請(qǐng)求。

(分)與 axios 相比,uni.request?的優(yōu)缺點(diǎn)如下:

優(yōu)點(diǎn):

  1. 內(nèi)置于 uni-app 框架,不需要額外安裝和引入第三方庫(kù)。
  2. 兼容多端,可以方便地在不同平臺(tái)上使用。

缺點(diǎn):

  1. 功能相對(duì)于 axios 較為簡(jiǎn)單,缺少一些高級(jí)功能,例如攔截器需要自己實(shí)現(xiàn)。
  2. 錯(cuò)誤處理不如 axios 完善。axios 可以輕松區(qū)分網(wǎng)絡(luò)錯(cuò)誤和業(yè)務(wù)錯(cuò)誤,而在?uni.request?中需要手動(dòng)判斷狀態(tài)碼。

(總)其實(shí)在我們的項(xiàng)目中也借鑒 axios 的思想,基于?uni.request?封裝了自己的網(wǎng)絡(luò)請(qǐng)求庫(kù),可以用于處理常見(jiàn)的請(qǐng)求場(chǎng)景。

加分?

(總)我們自己實(shí)現(xiàn)了一個(gè)基于 uni-app 的網(wǎng)絡(luò)請(qǐng)求庫(kù)。通過(guò)添加攔截器,實(shí)現(xiàn)了對(duì)請(qǐng)求前處理和請(qǐng)求后的處理,提高了代碼的復(fù)用性。

(分)具體來(lái)說(shuō),代碼實(shí)現(xiàn)了以下功能:

  1. 添加攔截器:攔截?request?請(qǐng)求和?uploadFile?文件上傳。
  2. 非?http?開(kāi)頭的請(qǐng)求 URL 自動(dòng)拼接基礎(chǔ)地址?baseURL。
  3. 如果存在 token,則將其添加到請(qǐng)求頭?Authorization
  4. 封裝了一個(gè)?http?函數(shù),該函數(shù)返回一個(gè) Promise 對(duì)象,支持泛型,方便處理返回?cái)?shù)據(jù)的類型。
  5. 當(dāng)請(qǐng)求成功時(shí)(狀態(tài)碼為 2xx),執(zhí)行?resolve()?表示成功,并提取核心數(shù)據(jù)res.data
  6. 當(dāng)請(qǐng)求失敗時(shí):
    • 如果狀態(tài)碼為 401,則清除用戶信息并跳轉(zhuǎn)到登錄頁(yè)面。
    • 如果是其他錯(cuò)誤,則根據(jù)后端錯(cuò)誤信息進(jìn)行提示。
    • 如果是網(wǎng)絡(luò)錯(cuò)誤,則提示用戶更換網(wǎng)絡(luò)。

(總)我們借鑒 axios 的思想,基于?uni.request?封裝了自己的網(wǎng)絡(luò)請(qǐng)求庫(kù),可以用于處理常見(jiàn)的請(qǐng)求場(chǎng)景。

參考代碼

import { useMemberStore } from '@/stores'// 服務(wù)器基地址
const baseURL = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'// 添加攔截器
const httpInterceptor = {// 攔截前觸發(fā)invoke(options: UniApp.RequestOptions) {// 1. 非 http 開(kāi)頭需拼接地址if (!options.url.startsWith('http')) {options.url = baseURL + options.url}// 2. 請(qǐng)求超時(shí), 默認(rèn) 60soptions.timeout = 10000// 3. 添加小程序端請(qǐng)求頭標(biāo)識(shí)options.header = {...options.header,'source-client': 'miniapp',}// 4. 添加 token 請(qǐng)求頭標(biāo)識(shí)const memberStore = useMemberStore()const token = memberStore.profile?.tokenif (token) {options.header.Authorization = token}},
}// 添加攔截器
uni.addInterceptor('request', httpInterceptor)
uni.addInterceptor('uploadFile', httpInterceptor)type Data<T> = {code: stringmsg: stringresult: T
}
// 2.2 添加類型,支持泛型
export const http = <T>(options: UniApp.RequestOptions) => {// 1. 返回 Promise 對(duì)象return new Promise<Data<T>>((resolve, reject) => {uni.request({...options,// 響應(yīng)成功success(res) {// 狀態(tài)碼 2xx, axios 就是這樣設(shè)計(jì)的if (res.statusCode >= 200 && res.statusCode < 300) {// 2.1 提取核心數(shù)據(jù) res.dataresolve(res.data as Data<T>)} else if (res.statusCode === 401) {// 401錯(cuò)誤  -> 清理用戶信息,跳轉(zhuǎn)到登錄頁(yè)const memberStore = useMemberStore()memberStore.clearProfile()uni.navigateTo({ url: '/pages/login/login' })reject(res)} else {// 其他錯(cuò)誤 -> 根據(jù)后端錯(cuò)誤信息輕提示uni.showToast({icon: 'none',title: (res.data as Data<T>).msg || '請(qǐng)求錯(cuò)誤',})reject(res)}},// 響應(yīng)失敗fail(err) {uni.showToast({icon: 'none',title: '網(wǎng)絡(luò)錯(cuò)誤,換個(gè)網(wǎng)絡(luò)試試',})reject(err)},})})
}

?

參考鏈接?

uni.request 網(wǎng)絡(luò)請(qǐng)求

uni.uploadFile 上傳文件

uni.addInterceptor 攔截器

拓展閱讀 - uni 攔截器其他用法

問(wèn):為什么用 VSCode 開(kāi)發(fā) uni-app 項(xiàng)目而不使用 Hbuilder??

必答?

(總)其實(shí) Hbuilder 我也有使用,不過(guò)最終體驗(yàn)下來(lái)還是選擇了?VS Code?。

(分)我主要是有 2 個(gè)出發(fā)點(diǎn)考慮:

  1. 熟悉度:VSCode 是我最熟悉并習(xí)慣使用的代碼編輯器,常用的代碼片段,快捷鍵,可以我的開(kāi)發(fā)效率。
  2. 插件生態(tài):我針對(duì) uni-app 項(xiàng)目安裝了對(duì)應(yīng)的插件,代碼提示,快速新建頁(yè)面并注冊(cè)路由,鼠標(biāo)懸停查文檔,這些功能我都在 VSCode 找到對(duì)應(yīng)的插件,非常好用。

(總)其實(shí)還是我自己不想換開(kāi)發(fā)工具,也不是刻意去比較兩者誰(shuí)好誰(shuí)壞,哪一個(gè)編輯器自己用起來(lái)更習(xí)慣,能提高效率就用哪個(gè)。

溫馨提示:Hbuilder 編輯器對(duì) TS 的類型支持還不夠完善,就好比 image 組件的 mode 取值寫(xiě)錯(cuò)了,之前用 Hbuilder 的時(shí)候校驗(yàn)不出來(lái),而 VSCode 可以校驗(yàn)出錯(cuò)誤,期待 Hbuilder 的進(jìn)步。(如果面試官特別喜歡用 Hbuilder 就不建議提這個(gè),尊重每個(gè)人的喜好)

加分?

如果面試官對(duì) VS Code 的配置感興趣,可以繼續(xù)展開(kāi)如何配置:

(總)用 VS Code 開(kāi)發(fā) uni-app 進(jìn)行 3 步配置就可以了,也可以給面試官您分享一下:

(分)

  1. 安裝 uni-app 插件

    • uni-create-view?:快速創(chuàng)建 uni-app 頁(yè)面
    • uni-helper?:uni-app 代碼提示
    • uniapp 小程序擴(kuò)展?:鼠標(biāo)懸停查文檔
  2. JSON 注釋報(bào)錯(cuò)問(wèn)題,設(shè)置文件關(guān)聯(lián)即可,把?manifest.json?和?pages.json?設(shè)置為?jsonc

  3. 針對(duì) TS 項(xiàng)目增加 TS 類型校驗(yàn)

    • 安裝類型聲明文件?pnpm i -D miniprogram-api-typings @uni-helper/uni-app-types
    • 配置?tsconfig.json

(總) HBuilder 也有它的優(yōu)點(diǎn),針對(duì) uni-app 開(kāi)發(fā)的專屬功能、內(nèi)置的調(diào)試工具,如果要打包和調(diào)試 App 端還要用到 Hbuilder 工具。選擇哪一個(gè)編輯器寫(xiě)代碼取決于開(kāi)發(fā)者的個(gè)人喜好和項(xiàng)目需求。

參考鏈接?

  • uni-helper 插件
  • uni-create-view 插件
  • VSCode 開(kāi)發(fā) uni-app 教程-Vue2 版

?

問(wèn):如何在 uni-app 中實(shí)現(xiàn)自定義導(dǎo)航欄??

必答?

我們項(xiàng)目的首頁(yè),訂單詳情頁(yè),個(gè)人信息頁(yè),等頁(yè)面都用到了自定義導(dǎo)航欄,核心步驟如下:

  1. 隱藏默認(rèn)導(dǎo)航欄:在?pages.json?文件中按需設(shè)置?navigationStyle?為?"custom"?。
  2. 按設(shè)計(jì)稿要求編寫(xiě)自定義導(dǎo)航欄的結(jié)構(gòu)、樣式和腳本。
  3. 封裝左上角返回按鈕,通過(guò)?getCurrentPages?獲取路由棧,如果路由棧數(shù)組長(zhǎng)度只有 1,通過(guò)?switchTab?返回首頁(yè),其他情況應(yīng)該是用?navigateBack?返回上一頁(yè)。
  4. 最后,還可以根據(jù)需要抽離封裝成一個(gè)通用的組件,預(yù)留標(biāo)題插槽等,方便復(fù)用。

如果自定義導(dǎo)航欄要求不高,其實(shí)也可以直接用 uni-ui 的?uni-nav-bar?,或者從?插件市場(chǎng)?中下載與項(xiàng)目要求接近的插件,再進(jìn)行二次開(kāi)發(fā)適配自己的項(xiàng)目。

加分?

我們項(xiàng)目中的自定義導(dǎo)航欄其實(shí)還做了安全區(qū)的樣式適配,通過(guò)?uni.getSystemInfoSync()?獲取頂部到安全區(qū)的距離,在模板中綁定行內(nèi)樣式,避免劉海屏或前置攝像頭遮擋導(dǎo)航欄標(biāo)題或 logo 等重要內(nèi)容。

如果左側(cè)按鈕要對(duì)齊右側(cè)的膠囊,還可以通過(guò)?wx.getMenuButtonBoundingClientRect?獲取膠囊信息實(shí)現(xiàn)對(duì)齊。

參考代碼

// src/pages.json
{"path": "pages/index/index","style": {"navigationStyle": "custom" // 隱藏默認(rèn)導(dǎo)航}
}

?

<!-- CustomNavbar.vue -->
<script setup lang="ts">
// 獲取頁(yè)面棧
const pages = getCurrentPages()
// 獲取屏幕邊界到安全區(qū)域距離
const { safeAreaInsets } = uni.getSystemInfoSync()
</script><template><!-- 頂部安全區(qū)占位 --><view class="navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }"><view class="wrap"><navigatorv-if="pages.length > 1"open-type="navigateBack"class="back icon-left"></navigator><navigator v-else url="/pages/index/index" open-type="switchTab" class="back icon-home"></navigator><view class="title"><!-- 插槽 --><slot>導(dǎo)航欄標(biāo)題</slot></view></view></view>
</template>

深入?

其實(shí)我們項(xiàng)目的訂單詳情頁(yè)(或者某個(gè)頁(yè)),給自定義導(dǎo)航欄加了滾動(dòng)驅(qū)動(dòng)動(dòng)畫(huà),增強(qiáng)用戶視覺(jué)效果:

  1. scroll-view?滾動(dòng)容器設(shè)置一個(gè)?id,用于綁定動(dòng)畫(huà)效果和滾動(dòng)容器偏移量。
  2. 獲取當(dāng)前頁(yè)面實(shí)例,因?yàn)檫@個(gè)功能目前只有微信小程序端支持,H5 端不支持,還需要寫(xiě)條件編譯。
  3. onReady 綁定生命周期鉤子中,通過(guò) animate 設(shè)置動(dòng)畫(huà)配置,并通過(guò)?id?綁定滾動(dòng)容器,設(shè)置觸發(fā)偏移量等信息。

\

<script setup lang="ts">
// 獲取屏幕邊界到安全區(qū)域距離
const { safeAreaInsets } = uni.getSystemInfoSync()
// 獲取頁(yè)面棧
const pages = getCurrentPages()// #ifdef MP-WEIXIN
// 獲取當(dāng)前頁(yè)面實(shí)例,數(shù)組最后一項(xiàng)
const pageInstance = pages.at(-1) as any// 頁(yè)面渲染完畢,綁定動(dòng)畫(huà)效果
onReady(() => {// 動(dòng)畫(huà)效果,導(dǎo)航欄背景色pageInstance.animate('.navbar',[{ backgroundColor: 'transparent' }, { backgroundColor: '#f8f8f8' }],1000,{scrollSource: '#scroller',timeRange: 1000,startScrollOffset: 0,endScrollOffset: 50,},)
})
// #endif
</script><template><!-- 自定義導(dǎo)航欄: 默認(rèn)透明不可見(jiàn), scroll-view 滾動(dòng)到 50 時(shí)展示 --><view class="navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }"><view class="wrap"><navigatorv-if="pages.length > 1"open-type="navigateBack"class="back icon-left"></navigator><navigator v-else url="/pages/index/index" open-type="switchTab" class="back icon-home"></navigator><view class="title">訂單詳情</view></view></view><scroll-view class="viewport" scroll-y enable-back-to-top id="scroller">...滾動(dòng)容器</scroll-view>
</template>

參考鏈接?

  • uni-nav-bar 自定義導(dǎo)航欄
  • 插件市場(chǎng) 自定義導(dǎo)航欄
  • 獲取系統(tǒng)信息
  • 滾動(dòng)驅(qū)動(dòng)的動(dòng)畫(huà)

問(wèn):如何在 uni-app 項(xiàng)目中進(jìn)行代碼優(yōu)化或性能優(yōu)化??

必答?

(總)其實(shí)代碼優(yōu)化和性能優(yōu)化是一個(gè)持續(xù)進(jìn)行的過(guò)程,我們的項(xiàng)目主要是做了以下的優(yōu)化:

(分)根據(jù)自身理解,選其中幾點(diǎn)回答即可,大部分其實(shí)在項(xiàng)目中都有體現(xiàn):

  1. 頁(yè)面加載優(yōu)化:
    • 按需加載:使用圖片懶加載,只在需要時(shí)加載(商品圖片添加 lazy-load 屬性即可)。
    • 分包加載:項(xiàng)目模塊拆分為多個(gè)包,按需加載對(duì)應(yīng)的包,降低初始加載時(shí)間。(項(xiàng)目的分包,分包頁(yè)面的圖片等資源也可放到分包的文件夾中,減少主包資源體積)
  2. 代碼優(yōu)化:
    • 代碼分層:按功能模塊化代碼,提高代碼可讀性和可維護(hù)性(goods.ts、home.ts 等劃分)。
    • 使用枚舉:枚舉提供了一種更有意義的命名方式,使代碼更具可讀性,類型也更安全 。
    • 條件編譯:在處理多端的時(shí)候,按條件編譯平臺(tái)所需代碼,減少冗余。(登錄界面等)
    • 類型安全:為組件 TS 提供了靜態(tài)類型檢查,有助于在編譯階段發(fā)現(xiàn)潛在的類型錯(cuò)誤。這可以減少運(yùn)行時(shí)錯(cuò)誤,提高代碼的可靠性。(安裝 uni-app-types、uni-ui-types)
  3. 數(shù)據(jù)處理優(yōu)化:
    • 數(shù)據(jù)獲取:僅獲取和處理需要的數(shù)據(jù),避免不必要的數(shù)據(jù)處理,分頁(yè)時(shí)設(shè)計(jì)合理的頁(yè)容量,減少一次性渲染的節(jié)點(diǎn)數(shù)量。 (如:訂單列表的容量為 5,因?yàn)橛唵涡畔⑤^多,實(shí)際情況是屏幕大概能放 3 個(gè))
    • 數(shù)據(jù)緩存:緩存獲取的數(shù)據(jù),減少不必要的數(shù)據(jù)請(qǐng)求(配置持久化存儲(chǔ))。
    • 優(yōu)化數(shù)據(jù)更新:在 uni-app 中,定義在 data/ref 里面的數(shù)據(jù)每次變化時(shí)都會(huì)通知視圖層重新渲染頁(yè)面。所以如果不是視圖所需要的變量,可以不定義在 data/ref 中,可定義普通變量,以避免造成資源浪費(fèi)。(如分頁(yè)的參數(shù),僅用于發(fā)送請(qǐng)求和判斷條件,不用于界面渲染,沒(méi)有用 ref 定義這份變化的數(shù)據(jù))
  4. 組件化開(kāi)發(fā):
    • 組件復(fù)用:對(duì)于通用功能,將其封裝為組件,提高代碼復(fù)用性。(猜你喜歡組件,輪播圖組件)
  5. 優(yōu)化資源文件:
    • 減少本地圖片:除了 tabBar 圖片,logo 等重要的圖片,其他圖片進(jìn)可能使用 CND 圖片。
    • 壓縮圖片:避免使用大圖,對(duì)圖片進(jìn)行壓縮,減少圖片文件大小。(素材已壓縮尺寸,在線壓縮圖片)
    • 網(wǎng)絡(luò)環(huán)境適配:獲取設(shè)備的網(wǎng)絡(luò)類型,可以在應(yīng)用中根據(jù)網(wǎng)絡(luò)環(huán)境做出相應(yīng)調(diào)整,如在較慢的網(wǎng)絡(luò)環(huán)境下降低圖片質(zhì)量、限制大文件下載等。
  6. 使用 CDN 加速:
    • 將靜態(tài)資源文件放在 CDN 上,加速資源文件的加載速度。(公司已購(gòu)買,由運(yùn)維管理,項(xiàng)目商品圖都已開(kāi)啟 CDN 加速)
  7. 頁(yè)面渲染優(yōu)化:
    • 使用條件渲染語(yǔ)句(如?wx:if)合理控制組件渲染:減少不必要的組件渲染。(空購(gòu)物車,訂單狀態(tài)等,v-if 可以減少 DOM 樹(shù)的大小,從而減少重繪成本,而 v-show 通過(guò) CSS 來(lái)控制顯示,適用于頻繁切換的場(chǎng)景。)
    • 避免不必要的組件重繪:減少不必要的數(shù)據(jù)變動(dòng),避免組件頻繁重繪。(v-for 的 key 值有助于 Vue 識(shí)別和復(fù)用已存在的元素,減少重繪次數(shù)。v-if、v-show 的合理使用也是減少重繪成本)
    • 骨架屏提升用戶體驗(yàn):使用戶感知到數(shù)據(jù)正在加載,降低用戶等待時(shí)的焦慮感,避免頁(yè)面白屏閃爍。(微信開(kāi)發(fā)者工具自動(dòng)生成,項(xiàng)目首頁(yè)和部分請(qǐng)求數(shù)據(jù)量較大的頁(yè)面記得添加骨架屏)
    • 避免視圖層和邏輯層頻繁進(jìn)行通訊:減少?scroll-view?組件的?scroll?事件監(jiān)聽(tīng),注意 onPageScroll 的使用。(項(xiàng)目中沒(méi)有使用 scroll 和 onPageScroll,如果一定要使用可以添加防抖?減少視圖層頻繁渲染,防抖和節(jié)流函數(shù) lodash 都有現(xiàn)成的)
    • 多使用組件自帶動(dòng)畫(huà),css 動(dòng)畫(huà),而不是通過(guò) js 的定時(shí)器操作界面做動(dòng)畫(huà)(swiper 滑動(dòng)動(dòng)畫(huà)是自帶的,訂單列表頁(yè) Tabs 的滑塊使用了 css 動(dòng)畫(huà),滾動(dòng)驅(qū)動(dòng)的動(dòng)畫(huà)是小程序自帶的并非手動(dòng)監(jiān)聽(tīng) scroll 事件)
  8. 優(yōu)化網(wǎng)絡(luò)請(qǐng)求:
    • 使用請(qǐng)求攔截和響應(yīng)攔截:對(duì)請(qǐng)求和響應(yīng)進(jìn)行攔截處理,提高請(qǐng)求效率。(http.ts 的封裝)

(總)總的來(lái)說(shuō),性能優(yōu)化是一個(gè)持續(xù)進(jìn)行的過(guò)程,通過(guò)不斷地優(yōu)化和調(diào)整,提高項(xiàng)目的性能和用戶體驗(yàn)。

加分?

理論上越多越好,按照自己的理解情況回答,回答時(shí)可提及項(xiàng)目中的業(yè)務(wù)場(chǎng)景適當(dāng)展開(kāi)。

深入?

如何在 uni-app 項(xiàng)目中使用使用防抖或節(jié)流函數(shù)。

  1. 安裝 lodash 工具庫(kù)?pnpm i lodash,在 TS 項(xiàng)目中安裝類型聲明文件?pnpm i -D @types/lodash。
  2. 導(dǎo)入?debounce?防抖函數(shù)。
  3. 用?debounce?函數(shù)包裹原事件函數(shù)并設(shè)置合理的延遲時(shí)間(結(jié)合真機(jī)調(diào)試取合適毫秒值)。

參考代碼

組合式 API 寫(xiě)法:

<script setup lang="ts">
import { throttle } from 'lodash'
import { ref } from 'vue'// 響應(yīng)式數(shù)據(jù)
const scrollTop = ref(0)// 普通的事件函數(shù)
const onScroll2 = (ev: UniHelper.ScrollViewOnScrollEvent) => {// 🔴觸發(fā)頻率非常高,視圖層頻繁渲染scrollTop.value = ev.detail.scrollTop
}// 添加節(jié)流的事件函數(shù)
const onScroll = throttle((ev: UniHelper.ScrollViewOnScrollEvent) => {// 🟢在 100 秒內(nèi)最多執(zhí)行一次函數(shù),更新視圖層scrollTop.value = ev.detail.scrollTop
}, 100)
</script><template><!-- 滾動(dòng)容器 --><scroll-view scroll-y @scroll="onScroll"><!-- 打印坐標(biāo) --><view style="position: fixed; top: 100rpx; left: 50rpx; background-color: pink">scrollTop:{{ scrollTop }}</view><view style="height: 5000rpx"> 內(nèi)容 </view></scroll-view>
</template>

選項(xiàng)式 API 寫(xiě)法:

<script lang="ts">
import { debounce } from 'lodash'
import { defineComponent } from 'vue'export default defineComponent({data() {return {scrollTop: 0,debouncedScroll: null as any,}},created() {// 防抖的處理函數(shù),🟢適當(dāng)延遲 50 毫秒后,再更新視圖層this.debouncedScroll = debounce(this.onScroll, 50)},unmounted() {// 最好是在組件卸載時(shí),清除掉防抖計(jì)時(shí)器this.debouncedScroll.cancel()},methods: {// 普通的事件處理函數(shù)onScroll(ev: UniHelper.ScrollViewOnScrollEvent) {this.scrollTop = ev.detail.scrollTop},},
})
</script><template><!-- 滾動(dòng)容器 --><scroll-view scroll-y @scroll="debouncedScroll"><!-- 打印坐標(biāo) --><view style="position: fixed; top: 100rpx; left: 50rpx; background-color: pink">scrollTop:{{ scrollTop }}</view><view style="height: 5000rpx"> 內(nèi)容 </view></scroll-view>
</template>

再深入-防抖和節(jié)流?

(總) 防抖(debounce)和節(jié)流(throttle)函數(shù)在處理高頻觸發(fā)事件時(shí)都非常實(shí)用。

debounce(防抖)函數(shù):該函數(shù)會(huì)從上一次被調(diào)用后,延遲?wait?毫秒后調(diào)用func?函數(shù)。

throttle (節(jié)流)函數(shù):在?wait?秒內(nèi)最多執(zhí)行?func?一次的函數(shù)。

根據(jù)自身理解,選其中幾點(diǎn)回答即可:

(分 1)防抖(debounce)函數(shù)在以下應(yīng)用場(chǎng)景中非常實(shí)用:

  1. 輸入框?qū)崟r(shí)搜索:當(dāng)用戶在輸入框中輸入時(shí),可以使用防抖函數(shù)來(lái)延遲觸發(fā)搜索請(qǐng)求。這樣可以減少服務(wù)器請(qǐng)求次數(shù),提高性能。
  2. 按鈕點(diǎn)擊:在一些場(chǎng)景下,如表單提交、購(gòu)物車結(jié)算等,為避免用戶頻繁點(diǎn)擊按鈕導(dǎo)致重復(fù)提交數(shù)據(jù),可以使用防抖函數(shù)控制按鈕點(diǎn)擊事件的觸發(fā)。
  3. 滾動(dòng)事件:在處理滾動(dòng)事件時(shí),可以使用防抖函數(shù)來(lái)限制事件處理函數(shù)的執(zhí)行頻率。例如,當(dāng)用戶滾動(dòng)頁(yè)面時(shí),可以使用防抖函數(shù)來(lái)延遲加載圖片或觸發(fā)其他與滾動(dòng)相關(guān)的操作。
  4. 用戶操作監(jiān)聽(tīng):在實(shí)時(shí)監(jiān)控用戶操作(如鼠標(biāo)移動(dòng)、點(diǎn)擊等)的場(chǎng)景中,可以使用防抖函數(shù)來(lái)減少事件處理函數(shù)的執(zhí)行次數(shù),降低系統(tǒng)資源消耗。

(分 2)節(jié)流(throttle)函數(shù)在以下應(yīng)用場(chǎng)景中非常實(shí)用:

  1. 滾動(dòng)加載:在無(wú)限滾動(dòng)列表或頁(yè)面滾動(dòng)加載數(shù)據(jù)的場(chǎng)景中,可以使用節(jié)流函數(shù)控制滾動(dòng)事件處理函數(shù)的執(zhí)行頻率,以減輕服務(wù)器壓力和提高性能。(組件庫(kù)一般有實(shí)現(xiàn))
  2. 頁(yè)面滾動(dòng)時(shí)的動(dòng)畫(huà)效果:當(dāng)用戶滾動(dòng)頁(yè)面時(shí),可以使用節(jié)流函數(shù)來(lái)控制動(dòng)畫(huà)效果的觸發(fā)頻率,以保持流暢的動(dòng)畫(huà)表現(xiàn),避免性能抖動(dòng)。(微信小程序的滾動(dòng)驅(qū)動(dòng)動(dòng)畫(huà)內(nèi)部實(shí)現(xiàn))
  3. 實(shí)時(shí)監(jiān)控鼠標(biāo)移動(dòng):在需要實(shí)時(shí)監(jiān)控鼠標(biāo)移動(dòng)的場(chǎng)景中,可以使用節(jié)流函數(shù)限制事件處理函數(shù)的執(zhí)行頻率,降低系統(tǒng)資源消耗。
  4. 瀏覽器窗口大小調(diào)整:當(dāng)用戶調(diào)整瀏覽器窗口大小時(shí),可以使用節(jié)流函數(shù)來(lái)限制與窗口大小相關(guān)的布局調(diào)整或重繪的執(zhí)行頻率,提高頁(yè)面性能。
  5. 實(shí)時(shí)數(shù)據(jù)采集:在需要實(shí)時(shí)采集用戶行為數(shù)據(jù)的場(chǎng)景中,可以使用節(jié)流函數(shù)來(lái)控制數(shù)據(jù)發(fā)送頻率,減輕服務(wù)器壓力。

(總)雖然防抖和節(jié)流的應(yīng)用場(chǎng)景看似有所重疊,但它們的工作原理和應(yīng)用場(chǎng)景有所不同:

  1. 工作原理:

防抖(debounce):當(dāng)事件觸發(fā)后,防抖函數(shù)會(huì)等待一定時(shí)間(設(shè)定的延遲時(shí)間),如果在這段時(shí)間內(nèi)事件沒(méi)有再次觸發(fā),則執(zhí)行事件處理函數(shù)。如果在這段時(shí)間內(nèi)事件再次觸發(fā),那么重新開(kāi)始等待延遲時(shí)間。簡(jiǎn)單來(lái)說(shuō),防抖就是讓事件處理函數(shù)在事件觸發(fā)后的一段時(shí)間內(nèi)不執(zhí)行,只有當(dāng)事件停止觸發(fā)一段時(shí)間后,才會(huì)執(zhí)行。

節(jié)流(throttle):節(jié)流函數(shù)會(huì)在一定時(shí)間間隔內(nèi)執(zhí)行事件處理函數(shù),即使在這段時(shí)間內(nèi)事件多次觸發(fā),也只會(huì)執(zhí)行一次事件處理函數(shù)。簡(jiǎn)言之,節(jié)流就是讓事件處理函數(shù)以固定的頻率執(zhí)行。

  1. 應(yīng)用場(chǎng)景:

它們?cè)诓煌膱?chǎng)景下有各自的優(yōu)勢(shì):

防抖適用于需要等待一段時(shí)間后才執(zhí)行的場(chǎng)景,如:搜索框輸入實(shí)時(shí)搜索、按鈕點(diǎn)擊避免重復(fù)提交等。這些場(chǎng)景中,只關(guān)心事件觸發(fā)的最后一次,而不關(guān)心事件在中間的過(guò)程。

節(jié)流適用于需要以一定頻率執(zhí)行的場(chǎng)景,如:滾動(dòng)加載、窗口大小調(diào)整、鼠標(biāo)移動(dòng)監(jiān)控等。這些場(chǎng)景中,關(guān)心事件在整個(gè)過(guò)程中的表現(xiàn),而不僅僅是最后一次觸發(fā)。

總結(jié):防抖關(guān)注事件觸發(fā)后的延遲執(zhí)行,節(jié)流關(guān)注事件在整個(gè)過(guò)程中以固定頻率執(zhí)行。在選擇使用防抖或節(jié)流時(shí),需要根據(jù)具體的應(yīng)用場(chǎng)景和需求來(lái)決定。

參考鏈接

  • uni-app 優(yōu)化建議-官方整理
  • 智能 WebP, PNG 和 JPEG 壓縮
  • 防抖的事件處理器 - Vue 官方文檔
  • 創(chuàng)建一個(gè)防抖 ref - Vue 官方文檔
  • lodash 防抖 debounce 函數(shù)用法
  • lodash 節(jié)流 throttle 函數(shù)用法

類似問(wèn)題

  • 請(qǐng)談?wù)勅绾卧?uni-app 中實(shí)現(xiàn)頁(yè)面的按需加載?
  • 請(qǐng)談?wù)劮蓝逗凸?jié)流的理解和應(yīng)用場(chǎng)景?

?uni-app 中,如何實(shí)現(xiàn)下拉刷新和上拉加載更多功能??

參考首頁(yè)的下拉刷新,猜你喜歡組件和熱門推薦頁(yè)的上拉加載分頁(yè)。

必答-下拉刷新?

我們是通過(guò)?scroll-view?組件 實(shí)現(xiàn)的下拉刷新,步驟如下:

  1. 啟用下拉刷新: 添加?refresher-enabled?屬性。
  2. 下拉刷新事件:綁定?@refresherrefresh?事件。
  3. 添加 下拉刷新?tīng)顟B(tài) 標(biāo)記: 添加?refresher-triggered?屬性,用于關(guān)閉動(dòng)畫(huà)的。
  4. 下拉刷新事件內(nèi)部:主要是重新獲取數(shù)據(jù),當(dāng)數(shù)據(jù)獲取成功后,主動(dòng)關(guān)閉下拉刷新動(dòng)畫(huà)。注意在多個(gè)請(qǐng)求的情況下,需要用?Promise.all()?等所有請(qǐng)求都結(jié)束了,再關(guān)閉動(dòng)畫(huà)
<script setup lang="ts">
// 當(dāng)前下拉刷新?tīng)顟B(tài)
const isTriggered = ref(false)
// 自定義下拉刷新被觸發(fā)
const onRefresherrefresh = async () => {// 開(kāi)始動(dòng)畫(huà)isTriggered.value = true// 加載數(shù)據(jù)await Promise.all([getHomeBannerData(), getHomeCategoryData(), getHomeHotData()])// 關(guān)閉動(dòng)畫(huà)isTriggered.value = false
}
</script><template><!-- 滾動(dòng)容器 --><scroll-viewrefresher-enabled@refresherrefresh="onRefresherrefresh":refresher-triggered="isTriggered"scroll-y>....</scroll-view>
</template>

?

必答-分頁(yè)加載?

上拉加載更多其實(shí)就是分頁(yè)加載,主要步驟如下。

  1. 定義?pageParams?對(duì)象,存儲(chǔ)分頁(yè)參數(shù),包括頁(yè)碼?page?和每頁(yè)數(shù)據(jù)量?pageSize。
  2. 定義?finish?響應(yīng)式引用,表示是否已加載完所有數(shù)據(jù)。
  3. 滾動(dòng)觸底事件:給?scroll-view?組件綁定?@scrolltolower?事件。
  4. 在事件內(nèi)部需要判斷是否已加載完所有數(shù)據(jù),沒(méi)有結(jié)束就繼續(xù)發(fā)送請(qǐng)求,同時(shí)頁(yè)碼要累加,獲取的數(shù)據(jù)要追加到原數(shù)組后,如果分頁(yè)已結(jié)束,就更新?finish?標(biāo)記,并提醒用戶。
<script setup lang="ts">
// 分頁(yè)參數(shù)
const pageParams: Required<PageParams> = {page: 1,pageSize: 10,
}
// 猜你喜歡的列表
const guessList = ref<GuessItem[]>([])
// 已結(jié)束標(biāo)記
const finish = ref(false)
// 獲取猜你喜歡數(shù)據(jù)
const getHomeGoodsGuessLikeData = async () => {// 退出分頁(yè)判斷if (finish.value === true) {return uni.showToast({ icon: 'none', title: '沒(méi)有更多數(shù)據(jù)~' })}const res = await getHomeGoodsGuessLikeAPI(pageParams)// 數(shù)組追加guessList.value.push(...res.result.items)// 分頁(yè)條件if (pageParams.page < res.result.pages) {// 頁(yè)碼累加pageParams.page++} else {finish.value = true}
}
// 重置數(shù)據(jù)
const resetData = () => {pageParams.page = 1guessList.value = []finish.value = false
}
// 組件掛載完畢
onMounted(() => {getHomeGoodsGuessLikeData()
})
</script><template><!-- 滾動(dòng)容器 --><scroll-view @scrolltolower="onScrolltolower" scroll-y><!-- 猜你喜歡列表 --><view class="guess"><navigatorclass="guess-item"v-for="item in guessList":key="item.id":url="`/pages/goods/goods?id=${item.id}`"><image class="image" mode="aspectFill" :src="item.picture"></image><view class="name"> {{ item.name }} </view><view class="price"><text class="small">¥</text><text>{{ item.price }}</text></view></navigator></view><view class="loading-text">{{ finish ? '沒(méi)有更多數(shù)據(jù)~' : '正在加載...' }}</view></scroll-view>
</template>

如何在 uni-app 中處理表單元素??

必答?

在我們項(xiàng)目的個(gè)人信息頁(yè),收貨地址表單頁(yè)等頁(yè)面都涉及到表單數(shù)據(jù)的收集。

(總)在 uni-app 中使用的是?<input>、<radio>?、<checkbox>?和?<picker>?等組件,能兼容不同平臺(tái)。

(分)

  1. input?支持?v-model?雙向綁定,收集數(shù)據(jù)比較便利。
  2. <radio>?、<checkbox>?和?<picker>?等不支持?v-model?指令,可以使用?:value?和?@change?代替?v-model?來(lái)實(shí)現(xiàn)類似的效果。

(總)?小程序端的表單組件具有一些特有的屬性,外觀和功能都有些差異,如?input?組件的?type?屬性支持的值與網(wǎng)頁(yè)端有所不同。例如,小程序端的?input?組件有一個(gè)?idcard?類型,而網(wǎng)頁(yè)端沒(méi)有。所以不要完全憑借網(wǎng)頁(yè)端的經(jīng)驗(yàn)處理小程序的表單,盡管部分表單組件的名稱和網(wǎng)頁(yè)端同名,也要應(yīng)該要查閱 uni-app 組件部分的文檔了解差異。

參考代碼

<script setup lang="ts">
import { ref } from 'vue'const switchValue = ref(false)const onSwitchChange = (ev: UniHelper.SwitchOnChangeEvent) => {switchValue.value = ev.detail.value
}
</script><template><view><switch :value="switchValue" @change="onSwitchChange" /></view>
</template>

(總)在這個(gè)例子中,我們使用?ref?函數(shù)創(chuàng)建了一個(gè)名為?switchValue?的響應(yīng)式引用,并使用?:value?將?switchValue?的值傳遞給?<switch>?組件。我們還定義了一個(gè)名為?onSwitchChange?的函數(shù),它在開(kāi)關(guān)狀態(tài)發(fā)生變化時(shí)被?@change?事件監(jiān)聽(tīng)器調(diào)用,從而根據(jù)事件對(duì)象中的?detail.value?更新?switchValue?的值。

加分-表單校驗(yàn)?

項(xiàng)目中我們還通過(guò)?uni-forms?實(shí)現(xiàn)了表單的校驗(yàn)。

以下是使用 uni-forms 實(shí)現(xiàn)表單校驗(yàn)的具體步驟:

  1. 創(chuàng)建表單數(shù)據(jù)和驗(yàn)證規(guī)則:使用?ref?函數(shù)創(chuàng)建表單數(shù)據(jù)對(duì)象?form?和驗(yàn)證規(guī)則對(duì)象?rules。
  2. 設(shè)置 ·uni-forms 屬性:在?<uni-forms>?組件上設(shè)置?:model?和?:rules?屬性,分別綁定到?form?和?rules。
  3. 使用 uni-form-item 組件和 input 組件構(gòu)建表單:為每個(gè)表單項(xiàng)創(chuàng)建一個(gè)?<uni-form-item>?組件,并設(shè)置?name?屬性。在表單項(xiàng)內(nèi)部使用?<input>?組件,并使用?v-model?指令進(jìn)行雙向數(shù)據(jù)綁定。
  4. 創(chuàng)建表單引用:使用?ref?函數(shù)創(chuàng)建一個(gè)名為?formRef?的引用,將其設(shè)置為?<uni-forms>?組件的?ref?屬性。
  5. 創(chuàng)建表單提交處理函數(shù):定義一個(gè)名為?onSubmit?的函數(shù),在此函數(shù)內(nèi)部使用?formRef.value.validate()?方法進(jìn)行表單驗(yàn)證。根據(jù)驗(yàn)證結(jié)果執(zhí)行相應(yīng)的邏輯(例如,提交表單或顯示錯(cuò)誤提示)。
  6. 添加提交按鈕:在模板中添加一個(gè)提交按鈕,為其設(shè)置?@tap?事件監(jiān)聽(tīng)器,綁定到?onSubmit?函數(shù)。
<script setup lang="ts">
import { ref } from 'vue'const form = ref({username: '',password: '',
})const rules: UniHelper.UniFormsRules = {username: {rules: [{ required: true, errorMessage: '用戶名不能為空' }],},password: {rules: [{ required: true, errorMessage: '密碼不能為空' }],},
}const formRef = ref<UniHelper.UniFormsInstance>()const onSubmit = async () => {try {const result = await formRef.value?.validate!()console.log('校驗(yàn)通過(guò),提交數(shù)據(jù):', result)} catch (error) {console.log('校驗(yàn)未通過(guò):', error)}
}
</script><template><view><uni-forms :model="form" :rules="rules" ref="formRef"><uni-forms-item label="用戶名:" name="username"><input v-model="form.username" placeholder="請(qǐng)輸入用戶名" /></uni-forms-item><uni-forms-item label="密碼:" name="password"><input password v-model="form.password" placeholder="請(qǐng)輸入密碼" /></uni-forms-item><view><button @tap="onSubmit">提交</button></view></uni-forms></view>
</template>

參考鏈接?

普通 form 表單

uni-forms 表單校驗(yàn)

類似問(wèn)題

  • 在 uni-app 中,如何處理不同平臺(tái)下的表單處理差異?

?

問(wèn):請(qǐng)談?wù)勀阍谑褂?uni-app 過(guò)程中遇到的問(wèn)題,以及如何解決它們。?

必答?

(總)在遇到問(wèn)題時(shí),我一般都是參考官方文檔、社區(qū)資源和其他開(kāi)發(fā)者的經(jīng)驗(yàn)。

(分)根據(jù)自身理解,選其中幾點(diǎn)回答即可:

  1. vue 語(yǔ)法支持問(wèn)題:uni-app 在發(fā)布到 H5 時(shí)支持所有 vue 的語(yǔ)法;發(fā)布到 App 和小程序時(shí),由于平臺(tái)限制,無(wú)法實(shí)現(xiàn)全部 vue 語(yǔ)法。相比 Web 平臺(tái), Vue.js 在 uni-app 中使用差異主要集中在兩個(gè)方面:
    • 新增:uni-app 除了支持 Vue 實(shí)例的組件生命周期,還擁有應(yīng)用生命周期及頁(yè)面的生命周期。
    • 受限:相比 Web 平臺(tái),在小程序和 App 端部分功能支持不完善,具體見(jiàn)兼容性列表。
    • 如:微信小程序端不支持自定義指令 directive,可通過(guò)封裝工具函數(shù)實(shí)現(xiàn),參考方案。
  2. 跨平臺(tái)兼容性問(wèn)題: 由于 uni-app 需要適配多個(gè)平臺(tái),開(kāi)發(fā)過(guò)程中可能會(huì)遇到不同平臺(tái)的兼容性問(wèn)題。在遇到此類問(wèn)題時(shí),可以參考官方文檔和社區(qū)資源,了解不同平臺(tái)的特性和限制,然后針對(duì)性地解決問(wèn)題。如果必要,可以使用條件編譯,在不同平臺(tái)下執(zhí)行不同的代碼。
    • 如 H5 端不支持 微信登錄,滾動(dòng)驅(qū)動(dòng)的動(dòng)畫(huà)等功能。
  3. 性能問(wèn)題: 在 uni-app 開(kāi)發(fā)過(guò)程中,可能會(huì)遇到頁(yè)面性能問(wèn)題,如加載速度慢等。為了解決這些問(wèn)題,可以嘗試以下方法:
    • 減少本地圖片資源,壓縮圖片,避免使用大圖;(素材中已優(yōu)化,在線壓圖工具)
    • 減少不必要的計(jì)算和渲染;
    • 使用分包加載,按需加載頁(yè)面和資源;
  4. 插件兼容性問(wèn)題: 當(dāng)使用第三方插件或庫(kù)時(shí),可能會(huì)遇到兼容性問(wèn)題。在這種情況下,可以嘗試以下方法:
    • 查找針對(duì) uni-app 的插件版本;(如 SKU 組件要篩選支持 Vue3 版的,axios 不支持小程序端則自行封裝)
    • 修改插件配置,以適應(yīng) uni-app 的環(huán)境;(如 Pinia 持久化存儲(chǔ)方案需要改默認(rèn)配置)
    • 尋找替代方案,如使用 uni-app 官方提供的 API 或組件。(如 組件庫(kù)使用官方的 uni-ui)
  5. 更新和維護(hù)問(wèn)題: 隨著項(xiàng)目的發(fā)展,可能需要更新和維護(hù)代碼。為了降低維護(hù)成本,可以:
    • 保持代碼的模塊化和組件化;(一直都有保持)
    • 遵循良好的編碼規(guī)范;(一直都有保持)
    • 編寫(xiě)文檔,記錄項(xiàng)目結(jié)構(gòu)和功能。(一直都保持,如:封裝函數(shù)寫(xiě) JSDoc 注釋)

(總)其實(shí) uni-app 官方文檔記錄了大量的跨平臺(tái)兼容性問(wèn)題和解決方案,uni-app 插件市場(chǎng)有大量插件,同時(shí) uni-app 社區(qū)也有其他開(kāi)發(fā)者分享的經(jīng)驗(yàn),也可以在 uni-app 社區(qū)提問(wèn)題,以找到合適的解決方案。最后,保持良好的編碼規(guī)范和項(xiàng)目結(jié)構(gòu),可以降低維護(hù)成本,提高開(kāi)發(fā)效率。

參考鏈接?

  • uni-app H5 正常但小程序異常的可能性
  • uni-app 區(qū)別于傳統(tǒng) web 開(kāi)發(fā)的注意
  • uni-app 跨端兼容
  • uni-app 常見(jiàn)問(wèn)題-官方整理
  • uni-app 優(yōu)化建議-官方整理
  • uni-app 路由攔截方法使用
  • 智能 WebP, PNG 和 JPEG 壓縮

問(wèn):請(qǐng)簡(jiǎn)述代碼規(guī)范在團(tuán)隊(duì)協(xié)作中的重要性??

必答?

(總)我們團(tuán)隊(duì)是使用 ESLint、Prettier 和 Husky 來(lái)確保代碼質(zhì)量和一致性:

(分)根據(jù)自身理解,選其中幾點(diǎn)回答即可:

  1. 保持代碼一致性:代碼規(guī)范可以確保團(tuán)隊(duì)成員遵循相同的編碼風(fēng)格和約定。這可以提高代碼的可讀性,使團(tuán)隊(duì)成員更容易理解和維護(hù)彼此的代碼。
  2. 提高代碼質(zhì)量:通過(guò)強(qiáng)制執(zhí)行一些最佳實(shí)踐,ESLint 可以幫助開(kāi)發(fā)者避免常見(jiàn)的錯(cuò)誤和潛在的風(fēng)險(xiǎn)。這有助于提高代碼的質(zhì)量,減少維護(hù)成本。
  3. 自動(dòng)化格式化:Prettier 可以自動(dòng)格式化代碼,保持代碼整潔,減輕開(kāi)發(fā)者在調(diào)整代碼格式時(shí)的負(fù)擔(dān)。它可以幫助開(kāi)發(fā)者專注于編寫(xiě)功能代碼,而無(wú)需擔(dān)心代碼風(fēng)格的問(wèn)題。
  4. 預(yù)提交檢查:Husky 可以在代碼提交到版本控制系統(tǒng)(如 Git)之前執(zhí)行一些預(yù)定義的任務(wù),如運(yùn)行 ESLint 和 Prettier 檢查。這有助于確保僅提交符合規(guī)范的代碼,從而減少代碼審查和后期修復(fù)的成本。
  5. 更好的協(xié)作:通過(guò)遵循相同的代碼規(guī)范和工具,團(tuán)隊(duì)成員之間的協(xié)作變得更加順暢。這有助于提高開(kāi)發(fā)效率,降低溝通成本。
  6. 提高開(kāi)發(fā)效率:使用這些工具可以自動(dòng)處理一些繁瑣的任務(wù)(如格式化、檢查錯(cuò)誤等),從而使開(kāi)發(fā)者可以專注于編寫(xiě)高質(zhì)量的功能代碼,提高開(kāi)發(fā)效率。

(總)總之,通過(guò)遵循統(tǒng)一的規(guī)范,團(tuán)隊(duì)可以更高效地開(kāi)發(fā)和維護(hù)項(xiàng)目。

深入?

可以談?wù)勗?uni-app 項(xiàng)目中是如何應(yīng)用 ESLint、Prettier 和 Husky 的,以及你遇到的一些挑戰(zhàn)和解決方法。

(總)這些配置是由團(tuán)隊(duì)負(fù)責(zé)人制定,當(dāng)然也可以由你自己配置,在小兔鮮兒的項(xiàng)目中已全部配置。

(分)具體步驟可以如下:

  1. 首先,我們需要安裝 ESLint、Prettier 和 Husky 作為項(xiàng)目的開(kāi)發(fā)依賴。
  2. 接下來(lái),配置 ESLint。在項(xiàng)目根目錄下創(chuàng)建一個(gè) .eslintrc.js 或 .eslintrc.json 配置文件,并定義相應(yīng)的規(guī)則??梢愿鶕?jù)項(xiàng)目需求,選擇使用 Vue 官方推薦的規(guī)則或者自定義規(guī)則。同時(shí),我們需要在項(xiàng)目的 package.json 文件中的 "scripts" 部分添加一個(gè)用于執(zhí)行 ESLint 檢查的腳本,例如:"lint": "eslint --ext .js,.vue,.ts --fix"。
  3. 接著,配置 Prettier。創(chuàng)建一個(gè) .prettierrc.js 或 .prettierrc.json 配置文件,在其中定義代碼格式化規(guī)則。同時(shí),可以在 .eslintrc.js 或 .eslintrc.json 文件中添加一些與 Prettier 相關(guān)的配置,以確保 ESLint 與 Prettier 能夠協(xié)同工作。
  4. 然后,配置 Husky。在項(xiàng)目中定義 Git 鉤子。例如,在 pre-commit 鉤子中執(zhí)行 ESLint 和 Prettier 檢查以確保提交的代碼符合規(guī)范。
  5. 最后,為了確保團(tuán)隊(duì)成員能夠在各種編輯器中保持一致的代碼風(fēng)格,建議在項(xiàng)目中添加一個(gè) .editorconfig 文件,定義編輯器相關(guān)的通用配置。

在應(yīng)用這些工具時(shí),其實(shí)也遇到了的一些挑戰(zhàn):

  • 在使用 uni. 全局變量的時(shí)候報(bào)錯(cuò),針對(duì) uni-app 項(xiàng)目設(shè)置全局變量,如:getCurrentPages、uni、wx、UniHelper。
  • ESLint、Prettier 和編輯器之間可能存在沖突。為了解決這個(gè)問(wèn)題,可以在 .eslintrc.js 或 .eslintrc.json 文件中添加與 Prettier 相關(guān)的配置,并確保編輯器插件正確地應(yīng)用了這些配置。
  • 部分 ESLint 規(guī)則可能與項(xiàng)目需求不符。在這種情況下,可以根據(jù)項(xiàng)目實(shí)際情況,自定義規(guī)則或禁用部分不適用的規(guī)則。
  • 當(dāng)使用第三方庫(kù)或組件時(shí),可能會(huì)遇到與 ESLint 規(guī)則沖突的問(wèn)題??梢栽?.eslintignore 文件中排除這些文件,或者在特定文件中禁用特定規(guī)則。

通過(guò)克服這些挑戰(zhàn),我們可以在 uni-app 項(xiàng)目中順利地應(yīng)用 ESLint、Prettier 和 Husky,確保代碼質(zhì)量和團(tuán)隊(duì)協(xié)作的高效性。

參考配置

?

/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')module.exports = {root: true,extends: ['plugin:vue/vue3-essential','eslint:recommended','@vue/eslint-config-typescript','@vue/eslint-config-prettier', // 遇到的挑戰(zhàn)2: ESLint、Prettier 存在沖突],// 遇到的挑戰(zhàn)1: 小程序全局變量globals: {uni: true,wx: true,WechatMiniprogram: true,getCurrentPages: true,UniApp: true,UniHelper: true,},parserOptions: {ecmaVersion: 'latest',},rules: {// 遇到的挑戰(zhàn)2: ESLint、Prettier 存在沖突'prettier/prettier': ['warn',{singleQuote: true,semi: false,printWidth: 100,trailingComma: 'all',endOfLine: 'auto',},],// 遇到的挑戰(zhàn)3: 部分 ESLint 規(guī)則與項(xiàng)目需求不符'vue/multi-word-component-names': ['off'],'vue/no-setup-props-destructure': ['off'],'vue/no-deprecated-html-element-is': ['off'],'@typescript-eslint/no-unused-vars': ['off'],},
}

問(wèn):請(qǐng)介紹 uni-app 中的條件編譯和平臺(tái)差異化處理??

必答?

(總)在 uni-app 開(kāi)發(fā)過(guò)程中,由于需要適配多個(gè)平臺(tái),可能會(huì)遇到不同平臺(tái)之間的差異和兼容性問(wèn)題。為了解決這些問(wèn)題,uni-app 提供了條件編譯和平臺(tái)差異化處理功能。

(分)

  1. 條件編譯(常見(jiàn)):,條件編譯是在編譯階段根據(jù)預(yù)設(shè)條件對(duì)代碼進(jìn)行不同分支的編譯。在 uni-app 中,可以通過(guò)條件編譯實(shí)現(xiàn)針對(duì)不同平臺(tái)編譯不同的代碼。 通過(guò)在代碼中添加特定的注釋來(lái)實(shí)現(xiàn)條件編譯。例如:
// #ifdef H5
console.log('這段代碼只編譯到H5端')
// #endif// #ifdef MP-WEIXIN
console.log('這段代碼只編譯到微信小程序端')
// #endif
  1. 平臺(tái)差異化處理:?平臺(tái)差異化處理是在運(yùn)行時(shí)根據(jù)當(dāng)前平臺(tái)執(zhí)行不同的代碼邏輯。在 uni-app 中,可以通過(guò)?const { osName } = uni.getSystemInfoSync()?來(lái)判斷當(dāng)前平臺(tái),然后編寫(xiě)針對(duì)不同平臺(tái)的代碼邏輯。例如:
// 獲取系統(tǒng)名稱
const { osName } = uni.getSystemInfoSync()
if (osName === 'ios') {console.log('ios平臺(tái)執(zhí)行的邏輯')
} else if (osName === 'android') {console.log('android平臺(tái)執(zhí)行的邏輯')
}

總結(jié): 條件編譯和平臺(tái)差異化處理是 uni-app 為解決多平臺(tái)兼容性問(wèn)題提供的兩種方法。條件編譯更加常見(jiàn),在編譯階段根據(jù)預(yù)設(shè)條件對(duì)代碼進(jìn)行不同分支的編譯,而平臺(tái)差異化處理是在運(yùn)行時(shí)根據(jù)當(dāng)前平臺(tái)執(zhí)行不同的代碼邏輯。根據(jù)項(xiàng)目需求和場(chǎng)景,可以靈活選擇使用這兩種方法。

加分?

條件編譯在 uni-app 中有很多應(yīng)用場(chǎng)景,主要用于處理不同平臺(tái)間的差異和兼容性問(wèn)題。以下是一些常見(jiàn)的應(yīng)用場(chǎng)景:

  1. 登錄功能差異:不同平臺(tái)可能有不同的登錄方式和 API。例如,微信小程序可以使用微信登錄,而 H5 平臺(tái)可能需要使用其他登錄方式,如手機(jī)號(hào)+驗(yàn)證碼。這種情況下,可以使用條件編譯為不同平臺(tái)提供適當(dāng)?shù)牡卿泴?shí)現(xiàn)。
// #ifdef MP-WEIXIN
// 微信小程序登錄
const { code } = wx.login()
// #endif// #ifdef H5
// H5平臺(tái)登錄,如手機(jī)號(hào)+驗(yàn)證碼
// ...
// #endif
  1. API 差異:不同平臺(tái)可能存在 API 差異,有的 API 在某些平臺(tái)上可能不可用。在這種情況下,可以使用條件編譯來(lái)處理平臺(tái)差異。
// #ifdef H5
navigator.geolocation.getCurrentPosition((position) => {// H5獲取地理位置
})
// #endif// #ifdef MP-WEIXIN
wx.getLocation({type: 'wgs84',success(res) {// 微信小程序獲取地理位置},
})
// #endif
  1. UI 組件差異:不同平臺(tái)的 UI 組件可能存在差異,例如 導(dǎo)航欄、底部標(biāo)簽欄,微信小程序的picker組件和 H5 平臺(tái)的select元素。可以使用條件編譯針對(duì)不同平臺(tái)提供不同的 UI 組件。
  2. <template><!-- #ifdef H5 --><select><option value="option1">Option 1</option><option value="option2">Option 2</option></select><!-- #endif --><!-- #ifdef MP-WEIXIN --><picker><view>Option 1</view><view>Option 2</view></picker><!-- #endif -->
    </template>

  3. 資源路徑差異:有時(shí),不同平臺(tái)對(duì)資源路徑的處理方式不同,可以使用條件編譯為不同平臺(tái)提供適當(dāng)?shù)馁Y源路徑。
<template><!-- #ifdef H5 --><img data-fancybox="gallery" src="/static/img/logo.png" /><!-- #endif --><!-- #ifdef MP-WEIXIN --><image src="/static/img/logo-weixin.png" /><!-- #endif -->
</template>

總之,條件編譯在 uni-app 開(kāi)發(fā)過(guò)程中具有廣泛的應(yīng)用場(chǎng)景,主要用于解決不同平臺(tái)間的差異和兼容性問(wèn)題。根據(jù)具體需求,可以靈活運(yùn)用條件編譯來(lái)實(shí)現(xiàn)適配不同平臺(tái)的功能和表現(xiàn)。

類似問(wèn)題

問(wèn):如何在 uni-app 的組件中實(shí)現(xiàn)跨平臺(tái)邏輯?

問(wèn):如果區(qū)分 ios 端和 android 端執(zhí)行不同的業(yè)務(wù)?

http://www.aloenet.com.cn/news/32150.html

相關(guān)文章:

  • 廣平網(wǎng)站建設(shè)seo顧問(wèn)服務(wù)公司站長(zhǎng)
  • wordpress模板導(dǎo)出重慶seo哪個(gè)強(qiáng)
  • 昆明網(wǎng)站建設(shè)搜q.479185700百度關(guān)鍵詞推廣公司哪家好
  • 公司網(wǎng)站建設(shè)的通知酒店網(wǎng)絡(luò)營(yíng)銷推廣方式
  • 攝影網(wǎng)站開(kāi)發(fā)背景怎么寫(xiě)云搜索
  • 洛陽(yáng)網(wǎng)站建設(shè)設(shè)計(jì)公司百度貼吧熱線客服24小時(shí)
  • jsp網(wǎng)站安全性電商運(yùn)營(yíng)培訓(xùn)大概多少學(xué)費(fèi)
  • 中企動(dòng)力科技股份有限公司是做什么的優(yōu)化手機(jī)性能的軟件
  • 做網(wǎng)站賣草坪賺錢嗎精準(zhǔn)營(yíng)銷推廣方案
  • 網(wǎng)站備案有效期免費(fèi)下載優(yōu)化大師
  • 做網(wǎng)站600網(wǎng)絡(luò)營(yíng)銷模式有哪些
  • 網(wǎng)站制作的一般步驟是什么百度百科搜索入口
  • 利用別人域名做自己的網(wǎng)站可以免費(fèi)推廣的平臺(tái)
  • 公司網(wǎng)站設(shè)計(jì)怎么做b站視頻推廣怎么買
  • 上海做網(wǎng)站比較有名的公司百度q3財(cái)報(bào)減虧170億
  • 如何在分類信息網(wǎng)站做推廣軟文推廣代寫(xiě)代發(fā)
  • 網(wǎng)站策劃過(guò)程怎樣推廣品牌
  • 湛江制作企業(yè)網(wǎng)站站長(zhǎng)工具使用
  • wordpress 影響力泰州seo外包
  • 手機(jī)開(kāi)發(fā)工具有哪些長(zhǎng)沙seo報(bào)價(jià)
  • 對(duì)網(wǎng)站備案的認(rèn)識(shí)濟(jì)南疫情最新情況
  • 網(wǎng)頁(yè)欣賞怎樣做關(guān)鍵詞排名優(yōu)化
  • 基于wed的網(wǎng)站開(kāi)發(fā)房地產(chǎn)營(yíng)銷策略有哪些
  • 單位網(wǎng)站建設(shè)存在問(wèn)題情況匯報(bào)智能網(wǎng)站排名優(yōu)化
  • 興國(guó)做網(wǎng)站網(wǎng)絡(luò)營(yíng)銷方案的制定
  • 政府網(wǎng)站建設(shè)十強(qiáng)百度seo公司興田德潤(rùn)
  • 做網(wǎng)站如何將一張圖片直接變體馮耀宗seo視頻教程
  • 邢臺(tái)網(wǎng)站建設(shè)的公司湖南網(wǎng)絡(luò)推廣排名
  • apt-get install wordpress深圳外包seo
  • 吉安網(wǎng)站建設(shè)0796abc百度小說(shuō)搜索風(fēng)云榜總榜