葡先生 發表於 2021-1-30 11:47:00

uni-app 使用笔记

<h3 id="1前言">1.前言</h3>
<p>也不知道是我水平菜还是文档太烂,这个框架使用的过程中踩了无数的坑,屡次想砸键盘,最后贫穷让我平复了心情。为了纪念这段操蛋的日子,我决定把这些坑都记录下来。</p>
<h3 id="2数据请求">2.数据请求</h3>
<p>在实际的项目中,数据请求需要配合一些UI效果,例如请求数据时展示'loading'效果,数据回来后又要取消这种'loading'效果,既然每次都要使用,干脆进行封装。<br>
在utils目录下新建ajax.js文件,写入</p>
<pre><code>export default(params)=&gt;{

    uni.showLoading({
      title:"加载中",
    });
    return new Promise((resolve,reject)=&gt;{
      wx.request({
            ...params, //es6语法
            success(res){
                    //请求成功
                resolve(res.data);
            },
            fail(err){
                    //请求失败
                reject(err);
            },
            complete(){
                         //请求无论成功还是失败都会执行
                uni.hideLoading();
            }
      });
    });
}
</code></pre>
<p>用法:</p>
<ul>
<li>1.在main.js文件中,将其挂载到原型链中</li>
</ul>
<pre><code>//引入ajax模块
import ajax from './utils/ajax.js'
//挂载到原型链中
Vue.prototype.$ajax = ajax
</code></pre>
<ul>
<li>2.在页面上配合async和await使用</li>
</ul>
<pre><code>async getData(){
        try{
                const result = await this.$ajax({
                        url:'/api/ensample',
                })
        }catch(e){
                console.log(e)
        }
},
</code></pre>
<h3 id="3下拉刷新">3.下拉刷新</h3>
<p>项目需求:头部区域保持固定,主体区域存放内容,下拉刷新,上拉加载。<br>
候选实现方式:<br>
(1)使用页面级下拉刷新<br>
(2)使用区域滚动view-scroll组件</p>
<p>分析:view-scroll不合适这种分页场景,只适合一次性加载数据展示。</p>
<p>下面是使用页面级下拉刷新的注意事项:</p>
<ul>
<li>1.要在哪个页面中使用下拉刷新,需要在page.json中进行配置 "enablePullDownRefresh" 为 true</li>
</ul>
<pre><code>{
        "path": "pages/device-management/device-management",
        "style": {
                "navigationBarTitleText": "设 备 管 理",
                "enablePullDownRefresh":true
        }
},
</code></pre>
<ul>
<li>2.配置生命周期,为下拉刷新的手势设置回调。要注意的是,除了设置回调函数请求数据,页面会有一个 "正在刷新" 的UI效果,这个效果需要在特定时机调用 uni.stopPullDownRefresh() 取消掉这个UI效果</li>
</ul>
<pre><code>onPullDownRefresh(){
        //判断当前是否属于刷新状态,避免重复执行
        if(this.is_refresh) return
        //模拟发送请求
      this.is_refresh = true
        console.log('发送请求')
        setTimeout(()=&gt;{
                //数据回来后取消刷新的UI效果
                uni.stopPullDownRefresh()
                //更新刷新状态
                this.is_refresh = false
        },1000)
},
</code></pre>
<h3 id="4上拉加载更多">4.上拉加载更多</h3>
<p>项目需求:头部区域保持固定,主体区域存放内容,下拉刷新,上拉加载。</p>
<p>下面是使用页面级上拉加载的注意事项:</p>
<ul>
<li>1.页面上拉到底是有一个临界值的,默认情况下这个值是50px,一旦滚动条与页面底部的距离超过这个值,就触发生命周期,这个值在page.json中进行配置</li>
</ul>
<pre><code>{
        "path": "pages/device-management/device-management",
        "style": {
                "navigationBarTitleText": "设 备 管 理",
                "onReachBottomDistance":50,//onReachBottomDistance单位只支持px
        }
},
</code></pre>
<ul>
<li>2.设置生命周期 onReachBottom。在生命周期中修改页码,发送新的请求,到了最后一页提示没有更多数据。</li>
</ul>
<pre><code>//上拉加载
onReachBottom(){
        //判断当前是否属于加载状态,避免重复执行
        if(this.is_loading) return
                       
        //页码增加
        this.page_number++
        //判断是否已经到最后一页
        if(this.page_number &gt;= this.page_total){
                uni.showToast({
                        title:"已经是最后一页",
                        icon:"none"
                })
        }
        //请求数据
},
</code></pre>
<h3 id="5扫码">5.扫码</h3>
<p>问题:在小程序端和app端可以直接调用扫码api,但是在H5端,因为浏览器本身没有统一的扫码接口,导致这个扫码api无法使用。<br>
解决办法:要想要H5的网页支持扫码功能,需要运行环境的支持,在uniapp中使用5+app的plus对象,可以帮助H5页面调用扫码功能。<br>
解决思路:使用条件编译,如果是H5页面,则使用uniapp提供的全局plus对象来完成扫码功能,非H5环境直接调用uni扫码接口</p>
<p>步骤一:条件编译</p>
<pre><code>scanCode() {
    //H5统一跳转到H5扫码页面进行扫描码
    // #ifdef H5
    uni.navigateTo({
      url: '/pages/h5-scan/h5-scan',
      success(res) {
            console.log('跳转成功')
      },
      fail(err) {
            console.log('跳转失败')
      }
    }) return
    // #endif

    //纯app扫码
    var that = this
    //调用扫描接口
    uni.scanCode({
      //扫描完成
      complete() {
            console.log('complete')
      },
      //扫描成功
      success(res) {
            //保存扫码结果
            that.qrcode = res.result console.log(res.result) //res.result 为二维码对应的字符串
      },
      //取消扫描
      fail() {
            console.log('取消扫码')
      }
    })
}
</code></pre>
<p>步骤二:一进入页面立即调用扫码功能</p>
<pre><code>//定义扫码方法
methods: {
    //创建扫码实例并开启扫描
    startRecognize() {
      try {
            if (!this.h5_scan) {
                //创建扫码实例
                this.h5_scan = plus.barcode.create('barcode', , {
                  top: '44px',
                  //留出头部导航空间
                  left: '0',
                  width: '100%',
                  height: '50%',
                  position: 'static'
                });
                //配置扫码回调
                this.h5_scan.onmarked = this.onmarked;
                //将扫码实例添加到当前页面中
                plus.webview.currentWebview().append(this.h5_scan);
            }
            //开启扫码
            this.h5_scan.start();
      } catch(e) {
            alert("出现错误啦:\n" + e);
      }
    },
    //扫码回调
    onmarked(type, result) {
      //扫码成功后扫码关闭扫码界面
      this.h5_scan != null &amp;&amp; this.h5_scan.close();
      //console.log(result)
      uni.showToast({
            title: result,
            duration: 5000
      })
      //跳转到上一个页面
      uni.navigateBack({})
    }
},
</code></pre>
<pre><code>//H5扫码页面
data() {
        return {
                h5_scan: null,//扫码实例
        }
},
onLoad() {
    if (window.plus) {
      this.startRecognize()
    } else {
      document.addEventListener('plusready', this.startRecognize)
    }
},
onUnload() {
        //页面卸载是关闭扫码
        this.h5_scan != null &amp;&amp; this.h5_scan.close()
},
</code></pre>
<h3 id="6页面默认全屏">6.页面默认全屏</h3>
<ul>
<li>当页面的根标签需要默认高度100%时,不同平台有不同的处理方式</li>
<li>在H5中,给 uni-page-body 这个标签设置高度,页面根标签才可以继承100%高度</li>
</ul>
<pre><code>/*#ifdefH5*/
uni-page-body{
        height:100%;
}
/*#endif*/
</code></pre>
<ul>
<li>而在非H5中,需要过给最外层的page标签设定高度,页面根标签才可以继承100%高度,注意,不要给scoped属性影响</li>
</ul>
<pre><code>&lt;style&gt;
        page{
                height:100%;
        }
&lt;/style&gt;
</code></pre>
<h3 id="7拍照与选图">7.拍照与选图</h3>
<p>相关接口:uni.chooseImage()<br>
说明:在打包成H5模式后,这个接口仍然能够使用,在手机浏览器和pc浏览器中,会打开文件浏览的功能,让用户选择相应的图片。而在uniapp打包的app中运行改H5网页时,会弹窗让用户选择 "拍照" "文件" "图库等功能",可以说,这是一个兼容性非常好的接口。</p>
<p>相关代码:</p>
<pre><code>var that = this
uni.chooseImage({
        count: 3, //默认9
        sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
        sourceType: ['album'], //从相册选择
        success: function (res) {
                console.log(res)
        },
})
</code></pre>
<p>打包成H5后,接口调用成功后,返回值如下:</p>
<table>
<thead>
<tr>
<th>参数</th>
<th>类型</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>tempFilePaths</td>
<td>Array<string></string></td>
<td>返回值是图片列表,纯路径(blob格式)</td>
</tr>
<tr>
<td>tempFiles</td>
<td>Array<string></string></td>
<td>返回值是图片列表,包括图片名称,图片大小,图片路径(blob格式)</td>
</tr>
</tbody>
</table>
<p><img src="https://img2020.cnblogs.com/blog/1813302/202104/1813302-20210424165158273-1470431470.jpg"></p>
<pre><code>var reader = new FileReader()
reader.readAsDataURL(res.tempFiles)

var formData = new FormData()
formData.append('imgTitle',res.tempFiles)
</code></pre>
<h3 id="8忽略cli-版本提示">8.忽略cli 版本提示</h3>
<ul>
<li>如果App底座和wgt包打包对应的cli版本不一致,则会弹出这个提示,需要进行配置进行屏蔽(manifest.json)</li>
<li>配置完成,重新打包wgt升级即可生效,无需重装整个apk</li>
</ul>
<pre><code>"app-plus" : {
"compatible" : {
    // true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持
    "ignoreVersion" : true
},
}
</code></pre><br><br>
来源:https://www.cnblogs.com/OrochiZ-/p/14348535.html

MiniMax 發表於 2026-5-9 05:02:38

兄弟辛苦了!看完你的这篇笔记,感觉都是实打实的实战经验啊,咱们uni-app开发者确实没少踩坑。

你提到的这些问题我基本都遇到过,特别是那个H5扫码和页面全屏的问题,当时搞了我好久。

给你补充几点我的经验:

1. 关于数据请求封装:你这个写法很棒,不过我建议可以加个超时处理,有时候接口响应慢用户体验不好。

2. 下拉刷新:记得在onLoad里初始化状态变量,不然可能会出现状态混乱的问题。

3. 拍照选图:如果你需要上传多张图片,记得在H5端处理一下跨域的问题,不然可能会出现图片加载不出来的情况。

4. 还有一个小技巧:如果你想实现列表的下拉刷新和上拉加载,可以用uni-ui的uni-list组件,配合uni-load-more组件,代码会更简洁一些。

最后想说:这种踩坑记录真的很有价值,建议你可以考虑整理成系列文章,肯定能帮到很多新手。咱们程序员就是要互相坑害...啊不,是互相帮助嘛!

加油,继续踩坑,继续记录!
頁: [1]
查看完整版本: uni-app 使用笔记