這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 最近接了個項目,採用uniapp的nvue開發安卓和ios端+小程式端,第一次開發nvue,對於css佈局這塊,還是踩了很多坑。以及一些uniapp的Api在nvue中也無法使用。文章中也收錄了一些我在項目中使用的一些方法,比如富文本解析 ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
最近接了個項目,採用uniapp的nvue開發安卓和ios端+小程式端,第一次開發nvue,對於css佈局這塊,還是踩了很多坑。以及一些uniapp的Api在nvue中也無法使用。文章中也收錄了一些我在項目中使用的一些方法,比如富文本解析、App綁定微信等,大家可以參考下。
1、註意事項
1. nvue僅支持flex佈局
// 預設佈局為(不需要寫) display: flex; flex-direction: column; // 橫向局部改為 flex-direction: row;
2. class 進行綁定時只支持數組語法
<template> // 支持的數組寫法 <text :class="[isError ? 'isError' : 'isRight']"></text> // 不支持對象寫法 <text :class="{isError}"></text> </template>
3. 只有<text>標簽可以設置字體大小,字體顏色
<template> // 可以修改字體大小和顏色 <text class='text'>文本內容</text> // 不可以修改字體大小和顏色 <view class='text'>文本內容</view> </template> <style> .text { color: red; font-size: 28rpx; } </style>
盒模型
- nvue盒模型的 box-sizing 預設為 border-box;
- 在 Android 平臺,overflow只支持 hidden;
- 在 ios 上,overflow支持 hidden 和 visible,預設是 visible。
2、對CSS的限制(常用)
// 不支持的CSS margin: auto; display: ...; content: ...; animation: ...; width: vw、%; height: vh、%; background-image: ...; // 不支持的CSS屬性 border-radius: 百分比無效;
3、多端單行/多行文本溢出
// 文本溢出 @mixin line($lineNum, $width: 100%) { /* 一行時 */ @if $lineNum == 1 { // App端 /* #ifdef APP-PLUS */ lines: 1; // 1或n text-overflow: ellipsis; /* #endif */ // 其他端 /* #ifndef APP-PLUS */ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; width: $width; /* #endif */ } @else { /* 多行時 */ // App端 /* #ifdef APP-PLUS */ lines: $lineNum; // 1或n text-overflow: ellipsis; /* #endif */ // 其他端 /* #ifndef APP-PLUS */ overflow: hidden; -webkit-line-clamp: $lineNum; display: -webkit-box; text-overflow: ellipsis; word-wrap: break-word; white-space: normal !important; -webkit-box-orient: vertical; /* #endif */ } }
使用
// 使用 @include line(1, 400rpx); // 單行 @include line(2); // 多行
4、獲取導航欄高度
// App導航欄高度 uni.getSystemInfoSync().safeArea.top + 'px' // 小程式導航欄高度 uni.getMenuButtonBoundingClientRect().top + 'px'
5、獲取底部安全區域高度
const safeArea = uni.getSystemInfoSync().safeArea const paddingBottom = safeArea.bottom - safeArea.height + 'rpx'
6、App修改導航欄電池、時間顏色
//只支持dark和light // #ifdef APP-PLUS plus.navigator.setStatusBarStyle('dark') // #endif
7、CSS過渡動畫
// 使用動畫的CSS屬性、動畫時間、動畫過渡效果、動畫延遲時間 transition-property: transform; transition-duration: 0.2s; transition-timing-function: ease; transition-delay:0.1s;
8、邊框樣式
// HBuilderX 3.1.0之前需要分開寫 border-top: 1px; border-style: solid; border-top-color: #eee; // HBuilderX 3.1.0+ 開始支持簡寫樣式 border-top: 1px solid #eee;
9、nvue中不支持的uni-app API
// 1、創建動畫 uni.createAnimation() // 2、頁面滾動 uni.pageScrollTo() // 3、節點佈局交互(交叉觀察器) uni.createIntersectionObserver()
10、微信端底部安全區域
/* #ifndef APP-PLUS */ padding-bottom: calc(env(safe-area-inset-bottom)); /* #endif */
11、nvue解析富文本(支持小程式)
App-nvue 和支付寶小程式不支持 HTML String 方式,僅支持直接使用節點列表即 Array 類型,需將 HTML String 轉化為 nodes 數組,可使用 html-parser 轉換。
<template> <rich-text :nodes='htmlNodes'/> </template> <script> // nvue僅支持node節點渲染,所以要將HTML轉換成node節點 import parseHtml from './html-parse.js' export default { data () { return { htmlStr: ` <h1>我的日記</h1> <p>今天天氣真好</p> <p>適合出去玩</p> `, htmlNodes: [] } }, onLoad () { this.getContent() }, methods: { getContent () { // 將HTML文本轉換成node節點 this.htmlNodes = parseHtml(this.htmlStr) } } } </script>
12、App端計算緩存和清理緩存
cacheSetting.js
// 計算緩存 export const computedCache = () => { return new Promise(resolve => { plus.cache.calculate((size) => { let cachSize = '' size = parseInt(size) if (size === 0) { cachSize = '' } else if (size < 1024) { cachSize = size + 'B' } else if (size < 1048576) { cachSize = (size / 1024).toFixed(2) + 'KB' } else if (size < 1073741824) { cachSize = (size / 1048576).toFixed(2) + 'MB' } else { cachSize = (size / 1073741824).toFixed(2) + 'GB' } resolve(cachSize) }) }) } // 清除緩存 export const clearCache = (cb) => { uni.showLoading({ title: '清理中…' }) const os = plus.os.name if (os === 'Android') { const main = plus.android.runtimeMainActivity() const sdRoot = main.getCacheDir() const files = plus.android.invoke(sdRoot, 'listFiles') const len = files.length for (let i = 0; i < len; i++) { const filePath = '' + files[i] // 沒有找到合適的方法獲取路徑,這樣寫可以轉成文件路徑 plus.io.resolveLocalFileSystemURL(filePath, (entry) => { if (entry.isDirectory) { entry.removeRecursively(() => { // 遞歸刪除其下的所有文件及子目錄 uni.showToast({ title: '緩存清理完成', duration: 2000 }) cb() }, (e) => { console.log(e.message) }) } else { entry.remove() } }, () => { console.log('文件路徑讀取失敗') }) } } else { // ios plus.cache.clear(() => { uni.showToast({ title: '緩存清理完成', duration: 2000 }) cb() }) } }
13、多端1px邊框
1. 新建border.scss
// 預設邊框色 $border: #e4e7ed; // nvue端 /* 此處加上!important並是因為目前*.nvue頁面編譯到H5時, App.vue的樣式會被uni-app的view元素的自帶border屬性覆蓋,導致無效, 所以為了多端相容,必須要加上!important App端相容性較好,直接使用0.5px去實現細邊框,不使用偽元素形式實現 */ /* #ifdef APP-NVUE */ .border { border-width: 0.5px!important; border-color: $border!important; border-style: solid; } .border-t { border-top-width: 0.5px!important; border-color: $border!important; border-top-style: solid; } .border-l { border-left-width: 0.5px!important; border-color: $border!important; border-left-style: solid; } .border-r { border-right-width: 0.5px!important; border-color: $border!important; border-right-style: solid; } .border-b { border-bottom-width: 0.5px!important; border-color: $border!important; border-bottom-style: solid; } .border-tb { border-top-width: 0.5px!important; border-bottom-width: 0.5px!important; border-color: $border!important; border-top-style: solid; border-bottom-style: solid; } /* #endif */ // 非nvue端 /* #ifndef APP-NVUE */ .border, .border-b, .border-l, .border-r, .border-t, .border-tb { position: relative; } .border-b:after, .border-l:after, .border-r:after, .border-tb:after, .border-t:after, .border:after { content: ' '; position: absolute; left: 0; top: 0; pointer-events: none; box-sizing: border-box; -webkit-transform-origin: 0 0; transform-origin: 0 0; width: 200%; height: 200%; transform: scale(0.5, 0.5); border: 0 solid $border; z-index: 1; } .border-t:after { border-top-width: 1px; } .border-l:after { border-left-width: 1px; } .border-r:after { border-right-width: 1px; } .border-b:after { border-bottom-width: 1px; } .border-tb:after { border-width: 1px 0; } .border:after { border-width: 1px; } /* #endif */
2. uni.scss引入
@import './assets/style/border.scss';
3. 組件內使用
// 1.作為類名使用 <template> <view class='border-tb'></view> </template> // 2.作為選擇器繼承 <template> <view class='cell'></view> </template> <style lang='scss' scoped> .cell { @extend .border-tb; } </style>
14、App用戶綁定微信/App微信登錄
1. manifest.json配置
2. 代碼
appBindWx () { const that = this uni.getProvider({ service: 'oauth', success: (res) => { //支持微信、qq和微博等 if (~res.provider.indexOf('weixin')) { uni.login({ provider: 'weixin', success: ({authResult}) => { // 微信返回的數據見下方圖片 // 請求介面完成綁定 }, fail: (res) => { console.log('App微信獲取用戶信息失敗', res) } }) } } }) }
3. 微信返回的數據
15、App分享為微信小程式
1. manifest.json配置
2. 代碼
const shareAppToMp = (shareInfo, cb) => { // 建議將圖片下載到本地再進行分享,防止有些圖片存在鑒權導致無法分享成功 uni.downloadFile({ url: 'xxx', // 圖片路徑 success (res) { if (res.statusCode === 200) { uni.share({ provider: 'weixin', // 分享服務提供商 // WXSceneSession分享到聊天界面、WXSceneTimeline分享到朋友圈、WXSceneFavorite分享到微信收藏 scene: 'WXSceneSession', // provider為weixin 時必選 type: 5, // 圖文、純文字、純圖片、音樂、視頻、小程式,5為小程式 imageUrl: res.tempFilePath, // 本地圖片地址 title: 'title', // 小程式分享標題 miniProgram: { id: 'gh_xxxxxxxxxx', // 小程式原始ID path: '/pages/homePage/index', // 小程式分享的頁面 type: 0, // 小程式版本類型,0正式版、1測試版、2-體驗版,預設為0 webUrl: 'xxxxx' // 相容低版本的網頁鏈接,可選 }, success () { uni.showToast({ title: '分享成功!', duration: 2000 }) cb() }, fail (e) { console.log('分享失敗原因:', e) } }) } } }) }
3.註意事項
配置正確的情況下,打包成App後才能成功分享,否則會提示以下錯誤
16、強制退出App
quitApp () { switch (uni.getSystemInfoSync().platform) { // 安卓 case 'android': plus.runtime.quit() break // ios case 'ios': plus.ios.import('UIApplication').sharedApplication().performSelector('exit') break } }
17、App和小程式阻止點擊事件冒泡
<template> <ul @click='clickParent'> <!-- 小程式阻止冒泡 --> <li @click.stop='clickChild'>子元素</li> </ul> </template> <script> export default { methods: { clickParent () { console.log('點擊父元素') }, clickChild (e) { console.log('點擊子元素') // App阻止冒泡 // #ifdef APP-NVUE e.stopPropagation() // #endif } } } </script>