- A+
所属分类:Web前端
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
最近接了个项目,采用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>