uni-app常見問題解決辦法

easycom組件模式是怎么回事

官方文檔:https://uniapp.dcloud.io/collocation/pages?id=easycom

easycom組件就是符合components/組件名稱/組件名稱.vue目錄結(jié)構(gòu)的組件。

簡單說,只要聽從官方的約定,那么無需引入、無需注冊,可以實(shí)現(xiàn)開發(fā)時(shí)全局使用、打包時(shí)按需打包。

注意事項(xiàng):

  1. 官方文檔說的注意事項(xiàng)我就不重復(fù)了。

  2. 小程序原生組件要放到/wxcomponents/里面,并不是放到components里面,也不適用easycom。

  3. 符合components/組件名稱/組件名稱.vue目錄結(jié)構(gòu),只要存放,無需其他任何操作就會(huì)被HBuilderX認(rèn)出,但現(xiàn)實(shí)中幾乎沒人這么存,因?yàn)槲覀兛赡芤褂枚鄠€(gè)組件庫,這時(shí)候怎么辦?你可以到pages.json去明確注冊一下,這樣存放路徑就不那么受限了。例如:

// pages.json
{
    "easycom": {
        "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
    },
    
    // 以下為pages.json本身已有的內(nèi)容
    "pages": [
        // ......
    ]
}

我們就看這行,它其實(shí)類似于正則替換,以u-開頭的組件名,都會(huì)自動(dòng)去@/uview-ui/components里面找。

"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"

如果還有一個(gè)組件庫也是以u-開頭作為組件名呢?怎么解決沖突?

首先看哪個(gè)組件庫是低使用頻率的,然后pages.json注冊它的時(shí)候,不要寫^u-(.*),改成別的前綴,比如^ux-(.*),使用的時(shí)候也注意要使用這個(gè)前綴就行了,比如<ux-button></ux-button>

vue語法 this.$emit('update:xxx') 在小程序不生效?

似乎就是不生效,可以用另外的寫法:

this.$emit('update:fieldValue', e.detail.value);
// 改成:
this.$emit('update', e.detail.value);

其中fieldValue是prop名,由于父組件里要顯式聲明自定義事件,所以改成省略。

然后,父組件里需要顯式聲明自定義事件:

// 給組件加上
@update="password=$event"

頁面間傳遞數(shù)據(jù)、調(diào)用方法的幾種方式

URL傳參

就不說了。

向navigateTo的頁面?zhèn)鬟f數(shù)據(jù)、調(diào)用方法

這個(gè)是小程序的基礎(chǔ)知識(shí),在此簡單說一下。比如,我想調(diào)用后一個(gè)頁面的xxxToast方法,做法是:

A頁面:

    methods: {
      onTap() {
        uni.navigateTo({
          url: '/pages/mine/index',
          success: (res) => {
            res.eventChannel.emit('xxxToast', { title: 'TOAST的標(biāo)題' });
          }
        })
      }
    }

mine頁面:

    onLoad() {
      const eventChannel = this.getOpenerEventChannel();
      eventChannel.on('xxxToast', ({title}) => {
        uni.showToast({
          title
        })
      }),
    },

向navigateBack的前一頁傳遞信息

有這樣一個(gè)場景,從文章列表頁打開某個(gè)詳情頁,詳情頁有個(gè)刪除按鈕,點(diǎn)擊刪除,則文章被刪除,并跳回列表頁,列表頁應(yīng)重新ajax,或者從內(nèi)存中的列表數(shù)組中刪掉該文章。讓列表頁更新數(shù)據(jù)不允許無腦更新,必須是有指令才更新,沒指令則不更新。我們分析一下:

  • 似乎需要用navigateBack,但是navigateBack的success不具有res.eventChannel能力。

  • navigateBack沒有url屬性,無法URL傳參。

  • 換用navigateTo的話,被刪除的詳情頁會(huì)留存在頁面棧,手機(jī)回退會(huì)重新進(jìn)入被刪除的詳情頁,肯定不允許。

  • 換用redirectTo的話,雖然詳情頁被殺掉,因此不會(huì)重新進(jìn)入詳情頁,但是進(jìn)入列表頁之后,手機(jī)回退會(huì)又進(jìn)一次列表頁,也不允許。

所以,我們依然需要用navigateBack,然后用某種方式傳遞信息,怎么辦呢?

可以利用getCurrentPages()獲取頁面棧,然后執(zhí)行前一頁的方法即可。

A頁面:

    methods: {
      list() {
        // ...
      }
    }

mine頁面(也就是B頁面):

原理是利用頁面棧調(diào)用其他頁面的方法。但不同平臺(tái)又有區(qū)別。

  • H5和小程序必須先調(diào)用頁面棧的方法,再回退,也就導(dǎo)致,頁面棧要找倒數(shù)第二個(gè)頁面。

  • APP可以有2個(gè)選擇,那么采用上方的方法,要么是先回退,再調(diào)用頁面棧的方法。

綜合說,應(yīng)當(dāng)全平臺(tái)統(tǒng)一采用先調(diào)頁面棧、后回退的方式。

然后區(qū)分.$vm

    methods: {
      onTap() {
            let pages = getCurrentPages();
            let prevPage = pages[pages.length - 2];
            // #ifdef H5
            prevPage.list();
            // #endif
            // #ifndef H5
            prevPage.$vm.list();
            // #endif
            uni.navigateBack()
      }
    }

A頁面調(diào)用uni原生方法,B頁面顯示

現(xiàn)在,我們不跨頁調(diào)用自定義方法,只是調(diào)用uni原生方法, 這時(shí)候最簡單,直接寫到success就行了。適用于所有路由方法。不適用于H5,因?yàn)镠5一旦路由變化就終止一切后續(xù)代碼。

        uni.navigateBack({
          success: () => {
            uni.showToast({
              title: '哈哈哈'
            })
          }
        });

引用本地圖片作為背景圖

本地背景圖片的引用路徑推薦使用以~@開頭的絕對(duì)路徑。

動(dòng)態(tài)添加右上角按鈕

          // #ifdef APP-PLUS
            var wv = plus.webview.currentWebview();
            wv.setStyle({
                titleNView: {  
                    titleText: '刪除'  
                }  
            });
          // #endif

同樣的,plus.webview.currentWebview()可以做很多事,參看:

https://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject

引入Vant組件報(bào)postcss-loader錯(cuò)的解決辦法

如果引入Vant Weapp來開發(fā)小程序,不會(huì)有報(bào)錯(cuò),但是如果同時(shí)發(fā)布到H5,就會(huì)報(bào)錯(cuò)“postcss-loader”相關(guān)錯(cuò)誤,這個(gè)問題解決起來其實(shí)很簡單,關(guān)鍵是看你知不知道。

打開@vant/weapp/icon/index.wxss,前幾行是:

@import '../common/index.wxss';@font-face{font-weight:400;font-family:vant-icon;font-style:normal;font-display:auto;src:url(https://img.yzcdn.cn/vant/vant-icon-96970a.woff2) format("woff2"),url(https://img.yzcdn.cn/vant/vant-icon-96970a.woff) format("woff"),url(https://img.yzcdn.cn/vant/vant-icon-96970a.ttf) format("truetype")}

在里面找format("woff2"),urlformat("woff"),url,問題就出在這了。

給每個(gè)url前面敲一個(gè)空格,保存。重新編譯,故障解除!

但是,這種跨端發(fā)布的操作,不一定永遠(yuǎn)能成功,因?yàn)閂ant開發(fā)者沒打算讓你跨端使用。

同樣,在H5開發(fā)中引入Vant 2,也會(huì)報(bào)同樣的錯(cuò)誤,也可用這種方法解決。如果你把vant 2安裝在了node_modules里,無妨,把/lib/index.css拷出來,修改,引用這個(gè)css就行了。

解決APP環(huán)境沒有navigator變量的問題

H5組件庫往往使用navigator來判斷瀏覽器是安卓還是iOS環(huán)境,以便做出不同的兼容,但是APP平臺(tái)根本沒有這個(gè)變量,組件庫直接報(bào)錯(cuò)。怎么辦?我們創(chuàng)建一個(gè)頂級(jí)navigator就可以了。

if (!window) {
  global.navigator = {
    userAgent: plus.navigator.getUserAgent()
  }
}

其中global相當(dāng)于window,plus.navigator.getUserAgent()是H5 plus提供的API。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容