uni-app 關(guān)于 nvue 開發(fā)
1. 前言
在前面小節(jié)的學(xué)習(xí)中,我們都知道 uni-app 框架是基于 vue 的前端解決方案,大部分的開發(fā)需求在 vue 頁(yè)面基本都可以實(shí)現(xiàn)。
但是還有部分功能需要結(jié)合 nvue 頁(yè)面才能實(shí)現(xiàn),比如 <map>
組件在 vue 頁(yè)面中層級(jí)是最高的。用人話說,就是不能在 <map>
組件上添加任何的標(biāo)簽,那我想要將標(biāo)簽顯示在頁(yè)面地圖上怎么辦呢?
這就需要用 nvue 頁(yè)面來開發(fā) <map>
組件了,這節(jié)課主要講解如何在 uni-app 框架中使用 nvue 進(jìn)行開發(fā)。
2. nvue 介紹
2.1 nvue 是什么?
nvue 是 native vue 的縮寫,可以理解為 uni-app 的一種渲染方式。在 App 端,如果是 vue頁(yè)面,使用的是小程序方式的 webview 渲染,如果是 nvue 頁(yè)面,則使用 weex 方式的原生渲染。
使用 weex 方式的原生渲染,其實(shí)就是在 weex 的基礎(chǔ)上封裝了 uni-app 框架的 API,提供了App 端的原生渲染能力。nvue 常用于在 App 端給一些使用 vue 頁(yè)面表現(xiàn)不佳的場(chǎng)景作為強(qiáng)化補(bǔ)充。
有很多同學(xué)之前沒有接觸過 weex,我們先來了解一下。
2.2 weex 是什么?
weex 也是比較流行的一個(gè) Web 開發(fā)框架,也可以提供跨平臺(tái)開發(fā)方案,實(shí)現(xiàn)一份代碼同時(shí)在移動(dòng)端、Web端同時(shí)運(yùn)行的效果。但是 weex 有一個(gè)很大的問題就是它只是一個(gè)高性能的渲染器,沒有足夠的API能力。
nvue 就解決了 weex 的這個(gè)問題,weex 支持的東西,在 nvue 里大多都是支持的,并且 nvue 提供了豐富的插件生態(tài),讓前端工程師可以直接開發(fā)完整 App。
2.3 vue、nvue 頁(yè)面可以共存嗎?
一個(gè)項(xiàng)目中可以同時(shí)存在 vue 和 nvue 頁(yè)面。比如項(xiàng)目首頁(yè)使用的是nvue 頁(yè)面,而二級(jí)頁(yè)則使用 vue 頁(yè)面。
如果一個(gè)頁(yè)面路由下出現(xiàn)同名的 vue 和 nvue 文件,App 端會(huì)使用 nvue 頁(yè)面,非 App 端會(huì)使用 vue 頁(yè)面。
nvue 頁(yè)面的組件和 JavaScript 的寫法與 vue 頁(yè)面是一樣的,但是 css寫法有一些區(qū)別,nvue 頁(yè)面的 css 均采用 flex 布局,不支持其他布局方式。具體區(qū)別下面我們來詳細(xì)講解。
3. vue 和 nvue 的開發(fā)區(qū)別
在 HBuilderX 編輯器中進(jìn)行頁(yè)面創(chuàng)建時(shí),可以選擇創(chuàng)建為 vue 頁(yè)面還是 nvue頁(yè)面。vue 頁(yè)面與 nvue 頁(yè)面雖然可以在同一個(gè) uni-app 項(xiàng)目中共存,但是這兩種頁(yè)面的開發(fā)還是有區(qū)別的,我們進(jìn)行項(xiàng)目開發(fā)的時(shí)候需要注意一下。
3.1 nvue 的 css 寫法受限
雖然 nvue 也可以多端編譯,但是在 nvue 頁(yè)面編寫 css 沒有在 vue 頁(yè)面方便。nvue 頁(yè)面的 css 寫法是受限的。來看一下在 nvue 頁(yè)面下,正確和錯(cuò)誤的 css 寫法實(shí)例:
3.1.1 border 不支持簡(jiǎn)寫,在 nvue 中需要拆分
/* 錯(cuò)誤寫法 */
.class {
border: 1px black solid;
}
/* 正確寫法 */
.class {
border-width: 1px;
border-style: solid;
border-color: black;
}
3.1.2 選擇器只能選擇單類
比如我們給下面的 HTML 代碼添加樣式。
<div class='imooc'>
<text class=’imooc-text’>慕課網(wǎng)</text>
</div>
我們要給 <div>
的下一級(jí) <text>
添加樣式,不能直接 .imooc>text
這樣寫,需要給 <text>
單獨(dú)添加一個(gè)樣式屬性,單獨(dú)給這個(gè)屬性定義樣式。下面來演示一下在 nvue 頁(yè)面添加樣式的正確和錯(cuò)誤的寫法。
/* 錯(cuò)誤寫法 */
.imooc>text {
background-color: green;
border-width: 1px;
border-style: solid;
border-color: black;
}
/* 正確寫法 */
.imooc {
border-width: 1px;
border-style: solid;
border-color: black;
}
.imooc-text {
background-color: green;
}
3.1.3 引入樣式文件
在 nvue 頁(yè)面不能直接使用 import
引入樣式文件。并且在 App.vue 文件中中定義的全局樣式不會(huì)在 nvue 頁(yè)面生效,nvue 頁(yè)面的全局樣式需要我們手動(dòng)引入。
/* 錯(cuò)誤寫法 */
<style>
@import "@/main.css";
</style>
/* 正確寫法 */
<style src="@/main.css">
</style>
3.1.4 不支持預(yù)編譯語(yǔ)言
在 nvue 頁(yè)面不支持使用 scss、less 等預(yù)編譯語(yǔ)言。
/* 錯(cuò)誤寫法 */
<style lang="scss">
</style>
3.1.5 引入字體文件
在 nvue 中,不能在 <style>
標(biāo)簽中直接引入字體文件,需要用 weex 來加載字體。
實(shí)例:
const domModule = weex.requireModule('dom');
domModule.addRule('fontFace', {
'fontFamily': "iconfont",
'src': "url('./font.ttf')"
});
4. nvue 和 vue 相互通訊
如果使用 vue 就能實(shí)現(xiàn)項(xiàng)目需求,并且對(duì)項(xiàng)目性能沒有很高的要求,我們盡量只使用 vue 來進(jìn)行開發(fā),不建議使用 nvue 來開發(fā)項(xiàng)目。因?yàn)?nvue 除了 css 寫法受限之外,在 vue 和 nvue 頁(yè)面混用的項(xiàng)目中,通訊也是一個(gè)大問題。
下面來看看在 vue 和 nvue 頁(yè)面混用的項(xiàng)目中,nvue 和 vue 如何相互通訊。
4.1 nvue 向 vue 傳值
在 nvue中使用 uni.postMessage(data)
發(fā)送數(shù)據(jù),參數(shù) data 只能是 json 數(shù)據(jù),json 數(shù)據(jù)的值只支持字符串。在vue中使用 onUniNViewMessage
函數(shù)監(jiān)聽數(shù)據(jù)。
實(shí)例:
在 nvue 頁(yè)面定義方法,使用 uni.postMessage(data)
發(fā)送數(shù)據(jù)。
<script>
export default {
methods: {
postMessage(item){
uni.postMessage({
name:’慕課網(wǎng)’,
data:item
})
}
}
}
</script>
在 vue 頁(yè)面接收數(shù)據(jù),對(duì) nvue 頁(yè)面發(fā)送的數(shù)據(jù)進(jìn)行監(jiān)聽。
<script>
export default {
onUniNViewMessage:(e) => {
const data = e.data
uni.$emit(‘data’,data)
}
}
</script>
4.2 vue 向 nvue 傳值
方法一:使用 storage 緩存的方式進(jìn)行參數(shù)傳遞。
在 vue 頁(yè)面中打開 nvue 頁(yè)面,并且通過 setStorageSync
方法將數(shù)據(jù)保存到緩存中。
<script>
export default {
methods: {
postMessage(item){
uni.setStorageSync('storageData', 'imooc');
uni.navigateTo({
url:"/pages/nvue/nvue"
})
}
}
}
</script>
在 nvue 頁(yè)面獲得緩存中的數(shù)據(jù)。
<script>
export default {
created() {
uni.getStorage({
key:'storageData',
success: (res) => {
console.log("傳遞過來數(shù)據(jù)是:" + res.data)
}
})
}
}
</script>
方法二:使用 globalData 全局?jǐn)?shù)據(jù)的方式進(jìn)行參數(shù)傳遞。
在 vue 頁(yè)面中定義全局?jǐn)?shù)據(jù)。
<script>
export default {
//全局?jǐn)?shù)據(jù)
globalData: {
domain: 'http://idcbgp.cn'
}
}
</script>
在 nvue 頁(yè)面獲取全局?jǐn)?shù)據(jù)。
<script>
export default{
onLoad() {
//獲取全局變量
console.log(getApp().globalData.domain)
}
}
</script>
5. 小結(jié)
使用 nvue 頁(yè)面進(jìn)行開發(fā)時(shí),有個(gè)常見的錯(cuò)誤是 Uncaught Error
,這種錯(cuò)誤一般是因?yàn)闆]有創(chuàng)建 vue 頁(yè)面。uni-app 項(xiàng)目中必須要有一個(gè) vue 頁(yè)面,新建一個(gè) vue 頁(yè)面再重新編譯項(xiàng)目就不會(huì)有問題了。
本節(jié)課程我們需要掌握的重點(diǎn)如下:
- 了解 nvue、weex是什么;
- 掌握 vue 和 nvue 頁(yè)面開發(fā)區(qū)別,主要是 css 寫法受限的問題;
- 掌握 vue 和 nvue 頁(yè)面之間如何相互通訊。