easycom組件模式是怎么回事
官方文檔:https://uniapp.dcloud.io/collocation/pages?id=easycom
easycom組件就是符合components/組件名稱/組件名稱.vue目錄結(jié)構(gòu)的組件。
簡單說,只要聽從官方的約定,那么無需引入、無需注冊,可以實(shí)現(xiàn)開發(fā)時(shí)全局使用、打包時(shí)按需打包。
注意事項(xiàng):
官方文檔說的注意事項(xiàng)我就不重復(fù)了。
小程序原生組件要放到
/wxcomponents/里面,并不是放到components里面,也不適用easycom。符合
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"),url和format("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。