uni-app的爬坑记

在这里插入图片描述
1、input的placeholder样式无法直接覆盖
使用placeholder-class属性设置一个类名,再用该类名写样式去覆盖掉原有的样式

 <input type="text" v-model="searchName" placeholder="请输入名字"
    placeholder-class="search-placeholder"/>

2、页面底部键盘问题

  • 软键盘弹出有adjustResize|adjustPan
  • 两种模式,现在uni-app推荐adjustResize模式,Android和小程序没有问题,iOS只能上推页面。(注:底部输入框要flexed牢固结构)
  • 关于tabbar页面输入框一样平常不推荐,由于底部tabbar会被键盘顶起。推荐跳转页面,若是有需求可以接纳@focus和@blur方式判断,然后挪用tabbar隐藏显示api。

3、关于点击非置焦区域可收起软键盘问题

  • Android上在软键盘弹出后,点击back或点击非置焦区域可收起软键盘。

  • iOS上若是软键盘上方有带有“完成”的横条,则需要点完成才气收起键盘;若是没有软键盘上方横条,则点击非input/textarea区域即可收起软键盘。

  • uni-app提供了隐藏软键盘的api:uni.hideKeyboard()

  • App平台在iOS上软键盘弹出时,默认在软键盘上方有一个横条,显示着:上一项、下一项和完成等按钮。如不想显示这个横条有三种设置,不推荐js(js设置可能泛起第一次进入页面输入框失去焦点,无法点击按钮发送问题),推荐页面设置。

4、无法覆盖uni-app提供的组件的样式
直接重写样式会发现并不生效

编译到H5如果要重置组件样式使用
    >>> .className{
    width:xxx
    }

scss的话 要使用 
    /deep/ .uni-radio-input {
        width: 32upx;
        height: 32upx;
        background: #fff !important;
        border: 2upx solid #CCCCCC !important;
    }

5、ios真机下键盘遮挡住弹框底部部分内容
pages.json中配置

 {
    "path": "pages/normative-interpretation/normative-interpretation-info/normative-interpretation-info",
    "style": {
        "app-plus":{
            "softinputMode": "adjustResize"
            }
        }
    },

6、关于ios朋友圈,圈子类型的功效需要加内容审核或者屏障举报功效
Ios app的审核职员会以为你的朋友圈需要一些人性化的设置功效,由于有些人不喜欢看到某些内容,好比广告,以是要支持屏障功效。圈子公布的内容需要审核才气在app上显示,制止欠妥言论和图片泛起。

  1. 加审核机制,屏障功效。
  2. 朋友圈若是是tabbar页面,可以单个隐藏tabbar,但uni-app暂时不支持单个隐藏,只能所有隐藏,或者改单个tabbar名字。
    接口控制,朋友圈审核时是放一张暂无数据图片,但有瑕玷,后期再次提交审核,会对用户使用产生影响。
  3. ios的朋友圈屏障功效可以不加,由于苹果方有各个国家的差别的人审核,有些人以为可以不加,但有些人以为一定要加,以是有一定概率能过。

7、图片下载保存到本地
需求大概是下载一个类似于小说结构的文档,其实下载没啥,主要是文档是可能会有图片,再无网络情况下我们无法访问网络地址的图片,所以只能下载到本地才能进行浏览。

思路:遍历数组拿到所有网络图片地址链接,遍历图片地址调用官方api下载图片,这里下载完也只是一个临时地址,我们还需要调用保存文件接口保存到本地,才能拿到本地真实地址,再无网络下页面渲染时替换网络地址即可。
图片下载保存:

/**
 * 获取富文本内容中的图片地址   存入数组返回
 */
export const getImgList = (html) => {
    var list = [];
    if (!html || Object.keys(html).length === 0) {
        return list
    }
    html.replace(/<img [^="">]*src=['"]([^'"]+)[^>]*>/g, (match, capture) => {
        list.push(capture);
    });
    return list;
}

/**
 * 图片下载保存
 */
export const getImageDownload = (url) => {
    return new Promise((resolve, reject) => {
        uni.downloadFile({
            url,
            success: (res) => {
                if (res.statusCode === 200) {
                    uni.saveFile({
                        tempFilePath: res.tempFilePath,
                        success: function(saveRes) {
                            var savedFilePath = saveRes.savedFilePath;
                            resolve({
                                [url]: savedFilePath
                            })
                        },
                        fail(e) {
                            console.log('e', e)
                        }
                    });
                }
            },
            fail: (err) => {
                console.log('err', err)
            }
        });
    })
}

/**
 * 处理图片
 */
export const handlexfNormsChaptersDtoList = async (xfNormsChaptersDtoList, userInfo) => {
    let normImageList = {}
    let newxfNormsChaptersDtoList = [];
    xfNormsChaptersDtoList.forEach(item => {
        newxfNormsChaptersDtoList = [...newxfNormsChaptersDtoList, ...item.xfNormsClauseList]
    })
    newxfNormsChaptersDtoList = newxfNormsChaptersDtoList.filter(item => {
        return JSON.stringify(item).indexOf('img') !== -1
    })
    let promiseAll = [];
    let imgList = []
    newxfNormsChaptersDtoList.forEach(item => {
        imgList = [...imgList, ...getImgList(item.clauseContent), ...getImgList(item.clauseImage), ...getImgList(item.clauseInterpretation)]
    })

    promiseAll = imgList.map(childItem => {
        return getImageDownload(childItem)
    })
    const resAll = await Promise.all(promiseAll)
    resAll.forEach(item => {
        normImageList = Object.assign(normImageList, item)
    })
    console.log(normImageList)
    const xf_download_imageList = uni.getStorageSync('xf_download_imageList') || {}
    normImageList = Object.assign(normImageList, xf_download_imageList)
    uni.setStorageSync('xf_download_imageList', normImageList)
    console.log(uni.getStorageSync('xf_download_imageList'))
}

下载完之后的图片地址与网络地址组成的键值对存到缓存。

8、关于自定义导航栏中的刘海屏适配问题
官方提供了一个CSS变量可以直接引用:
var(–status-bar-height)
该变量自动匹配设备平台状态栏高度
此变量可以用calc() 加上其他单位数值来使用
具体参数和说明:官方使用自定义导航栏注意事项

9、swiper中高度无法自适应时,采用动态获取节点赋值给外层swiper组件
uni.createSelectorQuery()后加.in(this)可以防止app端出错

<swiper :indicator-dots="true" :style="{height:listHeight+'px'}" :autoplay="false" :interval="3000" :duration="1000"></swiper>
var _self;
    export default {
        data() {
            return {
                listHeight:215
            }
        },
        onLoad() {
            _self=this;
            _self.getEleHeight('.swiper-item');
        },
        onShow() {
            
        },
        methods: {
            getEleHeight(list){
                let info = uni.createSelectorQuery().in(_self).select(list);
              info.boundingClientRect(function(data) { //data - 各种参数
                  if(data != null){
                        _self.listHeight = data.height;
                    }else{
                        setTimeout(function(){
                            _self.getEleHeight('.swiper-item');
                        },300)
                    }
              }).exec()
            }
            
        }
    }

10、横向scroll-view随子元素宽度自适应
关键在于给scroll-view的直接下一层view设置如下css:
  width:auto;
  display: inline-block;
  white-space: nowrap;

     <scroll-view scroll-x="true" class="scroll_box">
                    <view class="list">
                        <view class="item" v-for="(item,index) of 4" :key="index">
                           
                        </view>
                    </view>
                </scroll-view>
.scroll_box{
    width: 100%;
    height: auto;
}

.list{
    width: auto;
    height: 100upx;
    display: inline-block;
    white-space: nowrap;
}

.item{
    width:320upx;
    display: inline-block;
    height: 100%;
}

11、nuve的坑

  • nvue页面不能使用背景图片
  • 布局不能使用百分比、没有媒体查询
  • 背景颜色不支持简写,准确写法:background-color: red;
  • nvue中不支持z-index控制层级,越靠后的代码层级越高
  • 不能使用阴影,可以使用模拟阴影
  • 子元素超出父元素大小是不会显示的,可以加大父元素的大小来让子元素显示
  • nvue的css,在选择器方面支持的较少,只支持简单的类名控制class=“classA”
  • 文字内容,必须、只能在text标签下,只有text标签可以设置字体大小,字体颜色,并且不支持text标签嵌套
  • nvue 页面只能使用 flex
    布局,不支持其他布局方式,布局排列方向默认为竖排(column),如需改变布局方向可以使用flex-direction:
    row;改变为横排
  • 边框不支持简写,准确写法:
border-width: 1px;
border-style: solid;
border-color: red; 
  • 在 nvue 里面不能给 image 设置 border-radius,想要将矩形图案变为圆形需要在 image 外面包一层
    div,代码如下:
<div style="width: 400px;height: 400px;border-radius: 400px;">
   	   <image style="width: 400px;height: 400px;" src="https://uni@2x.png"></image>
    </div>

在 nvue 里面不能在 style 节点下使用 @import “xxx.css” 这样的方式引入外部 css,需要使用如下方式引入 css:

<style src="@/common/test.css"></style>
  • 在 nvue 里面不能直接在css中 通过 @font-face 这样的方式引入字体文件的,需要在js中使用 dom
    模块引入字体文件,src字段的url的括号内一定要使用单引号
const domModule = weex.requireModule('dom');
   	domModule.addRule('fontFace', {
   		'fontFamily': "iconfont",
   		'src': "url('../../static/iconfont.ttf')"
   	});
  • 修饰符失效:
    uni-app 虽然是vue语法,但是并没有使用vue的修饰符,而是选择小程序的修饰符

12、区分开发环境和线上环境
通过process.env.NODE_ENV可以判断运行环境。其中包括两种(开发环境和生产环境),运行编译出来的代码是开发环境,发行编译出来的代码是生产环境。然后可以在app.vue中的onLanuch钩子函数中进行判断,如果是开发环境就替换成测试服务器的域名如果是生产环境就替换成线上服务器的域名。然后把url通过setStorage存在本地,最后在其他需要调用接口的页面通过getStorage获取。

13、自动登录
现在的app基本都会有自动登录功能,老大爷提了这样的需求,因为本人没有app开发经验,所以还是苦思冥想了一会儿,最后想到一个解决方案,在用户登录成功以后,把用户的登录信息存在app本地,然后在用户首次加载app的时候去后台判断用户的登录状态,如果用户是未登录状态,便调取用户在本地的登录信息,自动去帮助用户登录。

14、方法封装
我相信做前端的你们,对于封装应该并不陌生。肯定都会或多或少的封装过自己的方法组件,接下来我要说的就是在uni-app中封装一些基本方法。首先建一个js文件,里面用来存放封装的方法。在方法完成后通过export default把方法导出,在其他需要调用方法的页面直接import from,这样引入就行啦,接下来上代码

const formatResponse = function(response) {
        const status = response.statusCode;
        const data = response.data;
        const msg = data.msg;
        if (status === 200 && msg.code === 0) {
          return data.data;
        } else {
          if (status !== 200) {
  uni.showToast({
           title: '网络异常:' + status
         });
          } else {
            if (msg.code === 50401) {
  var user = uni.getStorageSync('user');
  var phone = user.phone;
  var pass = user.password;
  console.log(phone)
  console.log(pass)
  if(phone && pass){
  uni.request({
      url:  '......',
      method: 'POST',
      data: {
           name: phone,
           password: pass
      },
      success: function(res) {
            console.log(JSON.stringify(res))
            formatResponse(res)
      },
      fail: function(res) {
            console.log(JSON.stringify(res))
       },
    });
    }else {
       uni.showModal({
       title: '提示',
       content: '您还未登录,请先登录',
       showCancel: true,
     success: function(res) {
       if (res.confirm) {
          uni.navigateTo({
             url: '/pages/login/login' 
          });
        }
      }
    });
  }
    return;
}
     uni.showToast({
         title: msg.info
     });
    }
   }
 }
export default {
  formatResponse
}

15、uni-app 整包升级

使用 uni-app 开发,可将代码编译到iOS、Android、微信小程序等多个平台,升级时也需考虑多平台同步升级。
一般iOS Appstore的安装包,无法直接更新。App启动后检查有新版本,只能调整到Appstore,然后用户在Appstore的详情页点击更新按钮。
Android App,可以直接下载新的apk,只要包名和证书不变,就可以覆盖安装。

接口约定
//请求数据:
{  
    "appid": plus.runtime.appid,  
    "version": plus.runtime.version  
}

//响应数据:
{  
    "status":1,//升级标志,1:需要升级;0:无需升级  
    "note": "修复bug1;\n修复bug2;",//release notes  
    "url": "http://www.xxx" //更新包下载地址  
}

App启动时,向服务端上报当前版本号,服务端判断是否提示升级。

//App.vue
onLaunch: function () {  
    //#ifdef APP-PLUS  
    var server = "https://www.example.com/update"; //检查更新地址  
    var req = { //升级检测数据  
        "appid": plus.runtime.appid,  
        "version": plus.runtime.version  
    };  
    uni.request({  
        url: server,  
        data: req,  
        success: (res) => {  
            if (res.statusCode == 200 && res.data.status === 1) {  
                uni.showModal({ //提醒用户更新  
                    title: "更新提示",  
                    content: res.data.note,  
                    success: (res) => {  
                        if (res.confirm) {  
                            plus.runtime.openURL(res.data.url);  
                        }  
                    }  
                })  
            }  
        }  
    })  
    //#endif  
}

16、App打包前端代码进行加密

HBuilderX中配置NVUE文件原生混淆加密.

uni-app的js运行在独立的jscore中,而不是webview中,所以不受iOS平台WKWebview不支持原生混淆的限制。
uni-app的vue页面中的js,是整体编译到一个大js文件中的,它经过编译,已经不再是vue源码了,但还不是乱码。对这个统一的大文件进行混淆会有影响性能。

HBuilderX2.3.4版本开始,uni-app项目支持对nvue文件进行原生混淆
"app-plus": {   
        "confusion": {    
            "description": "NVUE原生混淆",    
            "resources": {    
                "pages/barcode/barcode.nvue": {     
                },     
                "pages/map/map.nvue": {     
                }     
            }     
        },    
        // ...    
    }

resource下的键名为nvue文件路径(相对于应用根目录),值为空JSON对象(大括号)。

爬坑持续更新中~~~~~~~
在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值