HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

简单的到顶下拉加载历史聊天记录的代码,希望对你有帮助

经验分享
<template>  
    <view>  
        <scroll-view class="cnt-wrap fanzhuan" scroll-y :scroll-top="scrollTop" @scrolltolower="lastPage"  
            @scrolltoupper="_resetPage">  
            <view class="" style="position: fixed;top:40%;" @tap.stop="toBottom">置底</view>  
            <view id="to-bottom" class="text-center ft16 text-gray fanzhuan">底部</view>  
            <view class="item-wrap fanzhuan" v-for="item,index in list" :key="index">  
                <view v-if="index%10!=0" class="bubble left">  
                    <view v-if="index%15==0">  
                        <image class="image" src="../../static/no_msg.png" mode="widthFix"></image>  
                    </view>  
                    {{item}}  

                </view>  
                <view class="spring"></view>  
                <view v-if="index%10==0" class="bubble right">  
                    {{item}}  
                </view>  
            </view>  
            <view id="to-top" class="text-center ft16 text-gray fanzhuan">顶部</view>  

        </scroll-view>  

        <view style="position: fixed;bottom: 0;left: 0;">  
            <input-box></input-box>  
        </view>  
    </view>  
</template>  

<script>  
    import InputBox from "../../pagesChat/components/input-box.vue"  

    import {  
        debounce  
    } from '../common/util'  

    const List = len => [...new Array(len).keys()]  

    export default {  
        components: {  
            InputBox  
        },  
        data() {  
            return {  
                scrollTop: 0,  
                history: List(201),  
                list: [],  

                pageSize: 20,  
                lastPage: null  
            }  
        },  
        onShow() {  
            this._resetPage()  
        },  
        created() {  
            this.lastPage = debounce(this._lastPage, 200, true)  
        },  
        mounted() {  

        },  
        methods: {  
            _lastPage() {  
                console.log("到顶了")  
                if (this.history.length) {  
                    let arr = JSON.parse(JSON.stringify(this.history.splice(-this.pageSize) || []))  
                    arr.reverse()  
                    this.list.push(...arr)  
                }  
            },  
            _resetPage() {  
                console.log("重置")  
                this.history = List(201)  
                let arr = JSON.parse(JSON.stringify(this.history.splice(-this.pageSize) || []))  
                arr.reverse()  
                this.list = arr  
            },  
            toBottom() {  
                let _this = this  
                this.scrollTop = -1  

                this.$nextTick(function() {  
                    _this.scrollTop = 0  
                })  

            }  
        }  
    }  
</script>  

<style lang="scss" scoped>  
    .fanzhuan {  
        transform: rotate(180deg);  
    }  

    .cnt-wrap {  
        height: 100vh;  
        max-height: 100vh;  
        width: 100vw;  
        background-image: linear-gradient(to top, #fff, rgba(229, 77, 66, .2));  
    }  

    .item-wrap {  

        display: flex;  
        justify-content: space-between;  
        align-items: flex-start;  

        margin: 0 40rpx 20rpx;  

        .spring {  
            flex: 1;  
        }  

        .bubble {  
            max-width: 66vw;  
            padding: 20rpx;  
            color: #fff;  
            font-size: 36rpx;  

            .image {  
                max-width: 100%;  
            }  

            &.left {  
                border-radius: 8rpx;  
                border-top-left-radius: 0;  
                background-color: mediumpurple;  
            }  

            &.right {  
                border-radius: 8rpx;  
                border-top-right-radius: 0;  
                background-color: seagreen;  
            }  
        }  

    }  
</style>
继续阅读 »
<template>  
    <view>  
        <scroll-view class="cnt-wrap fanzhuan" scroll-y :scroll-top="scrollTop" @scrolltolower="lastPage"  
            @scrolltoupper="_resetPage">  
            <view class="" style="position: fixed;top:40%;" @tap.stop="toBottom">置底</view>  
            <view id="to-bottom" class="text-center ft16 text-gray fanzhuan">底部</view>  
            <view class="item-wrap fanzhuan" v-for="item,index in list" :key="index">  
                <view v-if="index%10!=0" class="bubble left">  
                    <view v-if="index%15==0">  
                        <image class="image" src="../../static/no_msg.png" mode="widthFix"></image>  
                    </view>  
                    {{item}}  

                </view>  
                <view class="spring"></view>  
                <view v-if="index%10==0" class="bubble right">  
                    {{item}}  
                </view>  
            </view>  
            <view id="to-top" class="text-center ft16 text-gray fanzhuan">顶部</view>  

        </scroll-view>  

        <view style="position: fixed;bottom: 0;left: 0;">  
            <input-box></input-box>  
        </view>  
    </view>  
</template>  

<script>  
    import InputBox from "../../pagesChat/components/input-box.vue"  

    import {  
        debounce  
    } from '../common/util'  

    const List = len => [...new Array(len).keys()]  

    export default {  
        components: {  
            InputBox  
        },  
        data() {  
            return {  
                scrollTop: 0,  
                history: List(201),  
                list: [],  

                pageSize: 20,  
                lastPage: null  
            }  
        },  
        onShow() {  
            this._resetPage()  
        },  
        created() {  
            this.lastPage = debounce(this._lastPage, 200, true)  
        },  
        mounted() {  

        },  
        methods: {  
            _lastPage() {  
                console.log("到顶了")  
                if (this.history.length) {  
                    let arr = JSON.parse(JSON.stringify(this.history.splice(-this.pageSize) || []))  
                    arr.reverse()  
                    this.list.push(...arr)  
                }  
            },  
            _resetPage() {  
                console.log("重置")  
                this.history = List(201)  
                let arr = JSON.parse(JSON.stringify(this.history.splice(-this.pageSize) || []))  
                arr.reverse()  
                this.list = arr  
            },  
            toBottom() {  
                let _this = this  
                this.scrollTop = -1  

                this.$nextTick(function() {  
                    _this.scrollTop = 0  
                })  

            }  
        }  
    }  
</script>  

<style lang="scss" scoped>  
    .fanzhuan {  
        transform: rotate(180deg);  
    }  

    .cnt-wrap {  
        height: 100vh;  
        max-height: 100vh;  
        width: 100vw;  
        background-image: linear-gradient(to top, #fff, rgba(229, 77, 66, .2));  
    }  

    .item-wrap {  

        display: flex;  
        justify-content: space-between;  
        align-items: flex-start;  

        margin: 0 40rpx 20rpx;  

        .spring {  
            flex: 1;  
        }  

        .bubble {  
            max-width: 66vw;  
            padding: 20rpx;  
            color: #fff;  
            font-size: 36rpx;  

            .image {  
                max-width: 100%;  
            }  

            &.left {  
                border-radius: 8rpx;  
                border-top-left-radius: 0;  
                background-color: mediumpurple;  
            }  

            &.right {  
                border-radius: 8rpx;  
                border-top-right-radius: 0;  
                background-color: seagreen;  
            }  
        }  

    }  
</style>
收起阅读 »

查找实例中的元素引起错误Error: Not Found:Page[2][-1,10] at view.umd.min.js:1

经验分享

这是github源码中的查找元素方法

export function findElm (component, pageVm) {  
  if (!pageVm) {  
    return console.error('page is not ready')  
  }  
  if (!component) {  
    return pageVm.$el  
  }  
  if (__PLATFORM__ === 'app-plus') {  
    if (typeof component === 'string') {  
      const componentVm = findVmById(component, pageVm)  
      if (!componentVm) {  
        throw new Error(`Not Found:Page[${pageVm.$page.id}][${component}]`)  
      }  
      return componentVm.$el  
    }  
  }  
  return component.$el  
}

在我们写的组件或者页面的报错
Error: Not Found:Page[2][-1,10] at view.umd.min.js:1

分析:

  1. [2]的2是getCurrentPages()页面数组的第2个
  2. [-1,10]是页面的$id,可通过getCurrentPages()[1].$vm.$id 查询,通常为-1
  3. typeof _$id 为数字是不会报错的,报错时component为“-1,10”

来源:
当我们执行一些查询元素宽高方法时,找不到元素。
可能是元素加载顺序的问题,比如在父组件的mounted周期执行了查询子组件高度的方法,但子组件中的mounted生命周期并没有完全执行完,导致子组件实际上还未渲染完。

继续阅读 »

这是github源码中的查找元素方法

export function findElm (component, pageVm) {  
  if (!pageVm) {  
    return console.error('page is not ready')  
  }  
  if (!component) {  
    return pageVm.$el  
  }  
  if (__PLATFORM__ === 'app-plus') {  
    if (typeof component === 'string') {  
      const componentVm = findVmById(component, pageVm)  
      if (!componentVm) {  
        throw new Error(`Not Found:Page[${pageVm.$page.id}][${component}]`)  
      }  
      return componentVm.$el  
    }  
  }  
  return component.$el  
}

在我们写的组件或者页面的报错
Error: Not Found:Page[2][-1,10] at view.umd.min.js:1

分析:

  1. [2]的2是getCurrentPages()页面数组的第2个
  2. [-1,10]是页面的$id,可通过getCurrentPages()[1].$vm.$id 查询,通常为-1
  3. typeof _$id 为数字是不会报错的,报错时component为“-1,10”

来源:
当我们执行一些查询元素宽高方法时,找不到元素。
可能是元素加载顺序的问题,比如在父组件的mounted周期执行了查询子组件高度的方法,但子组件中的mounted生命周期并没有完全执行完,导致子组件实际上还未渲染完。

收起阅读 »

uniapp关于微信小程序新隐私政策的解决方案------已发布插件

隐私弹窗 隐私政策 微信小程序 uniapp

根据微信官网最新关于用户隐私做出的更改,特此推出该插件,仅限于微信小程序使用,注意做好跨平台判断<!-- #ifdef MP-WEIXIN -->组件<!-- #endif -->,

需要注意:
1、微信公众平台登录->设置->服务内容声明->用户隐私保护指引 更新并声明项目用到的隐私相关接口的用途(很关键,不然不会触发隐私弹框),
2、manifest.json是否加入"usePrivacyCheck": true
3、组件是否正确导入、注册并使用
4、小程序基础库是否大于2.32.3

具体使用流程请看组件https://ext.dcloud.net.cn/plugin?id=14409,不用自己判断是否同意的回调,组件会在用户调用隐私相关接口时自行弹框,组均封装完成,开箱即用,同时弹框有唯一性,多个弹框弹出回开启一个并自动关闭其他弹框

如使用过程中有问题或有一些好的建议,欢迎加QQ群互相学习交流:120594820

继续阅读 »

根据微信官网最新关于用户隐私做出的更改,特此推出该插件,仅限于微信小程序使用,注意做好跨平台判断<!-- #ifdef MP-WEIXIN -->组件<!-- #endif -->,

需要注意:
1、微信公众平台登录->设置->服务内容声明->用户隐私保护指引 更新并声明项目用到的隐私相关接口的用途(很关键,不然不会触发隐私弹框),
2、manifest.json是否加入"usePrivacyCheck": true
3、组件是否正确导入、注册并使用
4、小程序基础库是否大于2.32.3

具体使用流程请看组件https://ext.dcloud.net.cn/plugin?id=14409,不用自己判断是否同意的回调,组件会在用户调用隐私相关接口时自行弹框,组均封装完成,开箱即用,同时弹框有唯一性,多个弹框弹出回开启一个并自动关闭其他弹框

如使用过程中有问题或有一些好的建议,欢迎加QQ群互相学习交流:120594820

收起阅读 »

因上传用户图片,违反隐私策略 被Google play下架

GooglePlay下架


实际上检查代码不存在任何上传文件代码,本身就是蓝牙本地软件,不存在互联网交互


实际上检查代码不存在任何上传文件代码,本身就是蓝牙本地软件,不存在互联网交互

希望打印日志增加如下功能。

新需求

希望打印日志增加对
console.group 和 groupCollapsed 的支持
然后在控制台显示的时候也支持 折叠 的功能。

希望打印日志增加对
console.group 和 groupCollapsed 的支持
然后在控制台显示的时候也支持 折叠 的功能。

解决你的图标难!成功移植拥有7000+图标的可商用图标项目:Material Design Icons 图标库

iconfont icon 字体图标绘制 搜索图标 图标

插件简介

本插件为非官方插件,原作者为 Pictogrammers 。由于插件作者常年使用Vuetify.js框架进行前端开发,发现该框架使用的Material Design Icons图标库资源丰富拥有7000+图标、风格基本统一、还很易用,后来迁移到uni-app进行小程序开发时一直苦于没有找到跟Material Design Icons比拟的图标库(尽管阿里巴巴图标矢量库等图标库资源远比该库丰富,但里面有着大量样式或使用场景重复或相似的图标),故自己将其移植过来了。

插件地址

https://ext.dcloud.net.cn/plugin?id=10508

示例预览

示例预览图

继续阅读 »

插件简介

本插件为非官方插件,原作者为 Pictogrammers 。由于插件作者常年使用Vuetify.js框架进行前端开发,发现该框架使用的Material Design Icons图标库资源丰富拥有7000+图标、风格基本统一、还很易用,后来迁移到uni-app进行小程序开发时一直苦于没有找到跟Material Design Icons比拟的图标库(尽管阿里巴巴图标矢量库等图标库资源远比该库丰富,但里面有着大量样式或使用场景重复或相似的图标),故自己将其移植过来了。

插件地址

https://ext.dcloud.net.cn/plugin?id=10508

示例预览

示例预览图

收起阅读 »

uniapp关于微信小程序新隐私政策的临时解决方案------已发布插件

隐私政策 微信小程序

简单的说一下能解决 什么问题呢?

首先,uniapp目前还没有同步更新微信小程序新隐私政策的button属性和api接口。
然后,经过查阅文档和社区,再加上不断踩坑,总结出来的一个uniapp官方没有更新前的一个临时解决方案。

首先你的确保你了解过微信小程序的新隐私政策

小程序新版隐私政策

这个就要求必须要先在小程序隐私政策中添加相关隐私接口信息,通过审核并且等待其真实生效后,才能调用。这个生效时间大概在审核通过后,15分钟以上。

插件市场地址

jade-mp-privacy小程序新隐私政策插件

继续阅读 »

简单的说一下能解决 什么问题呢?

首先,uniapp目前还没有同步更新微信小程序新隐私政策的button属性和api接口。
然后,经过查阅文档和社区,再加上不断踩坑,总结出来的一个uniapp官方没有更新前的一个临时解决方案。

首先你的确保你了解过微信小程序的新隐私政策

小程序新版隐私政策

这个就要求必须要先在小程序隐私政策中添加相关隐私接口信息,通过审核并且等待其真实生效后,才能调用。这个生效时间大概在审核通过后,15分钟以上。

插件市场地址

jade-mp-privacy小程序新隐私政策插件

收起阅读 »

vue3 cli es6转es5

vue_cli 兼容性 浏览器兼容 h5

用各种方法legacyPlugin、babel、polyfill(polyfill解释不了可选链)等等、都转不了,在旧版本浏览器上报错
?. 、import.meta等等

官方又说自带es6转es5,又跑去下载老版本的hbuilderX,搞这搞那,没有任何作用,非常抓狂

最后发现uniapp自己在编译时带了legacyPlugin,并且可以配置,问题解决

vite.config.ts

        uni({  
            viteLegacyOptions: {  
                targets: ['Chrome > 70']  
            }  
        })

官方文档没有任何提及,这方法还是突发奇想,点到uni里面看抛出的ts才看到并尝试的,并且刚巧build了一版发到服务器上试、因为这个编译只在build时生效,特么开发模式下该报错还是报错,这让我怎么测试、心态都崩了。。

DEBUG全靠猜,唉~

继续阅读 »

用各种方法legacyPlugin、babel、polyfill(polyfill解释不了可选链)等等、都转不了,在旧版本浏览器上报错
?. 、import.meta等等

官方又说自带es6转es5,又跑去下载老版本的hbuilderX,搞这搞那,没有任何作用,非常抓狂

最后发现uniapp自己在编译时带了legacyPlugin,并且可以配置,问题解决

vite.config.ts

        uni({  
            viteLegacyOptions: {  
                targets: ['Chrome > 70']  
            }  
        })

官方文档没有任何提及,这方法还是突发奇想,点到uni里面看抛出的ts才看到并尝试的,并且刚巧build了一版发到服务器上试、因为这个编译只在build时生效,特么开发模式下该报错还是报错,这让我怎么测试、心态都崩了。。

DEBUG全靠猜,唉~

收起阅读 »

今天下午发生一个诡异的问题,不同分类的翻页参数不重新初始化,而是选择加 1

不知道各位有没有收到反馈,我这边至少有 4 台设备发现了这样的形状,页面中 tab 切换分类的时候,翻页的参数选择了点击+1,而不是初始化;还在查代码的时候,有恢复了正常。
难道 uniapp 公司能远控?

不知道各位有没有收到反馈,我这边至少有 4 台设备发现了这样的形状,页面中 tab 切换分类的时候,翻页的参数选择了点击+1,而不是初始化;还在查代码的时候,有恢复了正常。
难道 uniapp 公司能远控?

微信小程序隐私协议最新弹框解决方案

隐私协议 微信小程序

公众号文章:
https://mp.weixin.qq.com/s?__biz=MzIyNjE5ODA5NA==&mid=2247487487&idx=1&sn=36269ceb84a1ffb0a91f10a711b274cb&chksm=e87558dedf02d1c867f0a9fad1344d7bd7dc5542849543caf824051d56b89763b9a3e242efca#rd

代码片段:
https://developers.weixin.qq.com/s/VGANOSmb7VKl

继续阅读 »

公众号文章:
https://mp.weixin.qq.com/s?__biz=MzIyNjE5ODA5NA==&mid=2247487487&idx=1&sn=36269ceb84a1ffb0a91f10a711b274cb&chksm=e87558dedf02d1c867f0a9fad1344d7bd7dc5542849543caf824051d56b89763b9a3e242efca#rd

代码片段:
https://developers.weixin.qq.com/s/VGANOSmb7VKl

收起阅读 »

【解决】uni.scanCode苹果(ios)黑屏,真机测试扫码黑屏问题

扫码

hbuilderx版本:3.5.3

原因:打包会使用新版本的sdk来打包

解决方式1:在manifest.json源码视图里面一下地方加入Barcode和Camera

{  
    "app-plus" : {  
        "modules" : {  
            "Barcode" : {},  
            "Camera" : {}  
        }  
    }  
}

解决方式2:升级hbuilderx版本,勾选以下两个

↓↓↓ 各位大佬点点赞

继续阅读 »

hbuilderx版本:3.5.3

原因:打包会使用新版本的sdk来打包

解决方式1:在manifest.json源码视图里面一下地方加入Barcode和Camera

{  
    "app-plus" : {  
        "modules" : {  
            "Barcode" : {},  
            "Camera" : {}  
        }  
    }  
}

解决方式2:升级hbuilderx版本,勾选以下两个

↓↓↓ 各位大佬点点赞

收起阅读 »

【TabBar】根据角色展示不同的数量或内容解决方案

tabbar

官方文档:https://uniapp.dcloud.net.cn/api/ui/tabbar.html#settabbaritem

看不懂的看我的解决方案:

1、pages.json里面按照要求配置好最全数量的tabbar,一定要按照最大数量配置,切记!!!并且此时对应的tabbar页面是公共的tabbar(最大数量为5个)例如ont,two,three。

2、将不同角色的页面提前创建好,写好自己的业务内容,此页面无需在 pages.json 中配置,作为一个组件引入即可。

3、在所有进入tabbar页面的url处一定要处理好标识,比如A角色=1,B角色=2。然后使用 switchTab 跳转对应的tabbar公共页面。

4、在公共的tabbar页面根据角色标识判断展示对应的组件(此组件为第2步创建的页面)。

5、在所有公共的tabbar页面的 onShow 函数中处理tabbar,以下是我的伪代码:

<script setup name="">  
import { onShow } from '@dcloudio/uni-app';  
import storage from '@/common/utils/storage.js';  

onShow(() => {  
    console.log(storage.getStorageSync('role'));  
    uni.setTabBarItem({  
        index: 0,  
        text: 'Home',  
        // pagePath: '/pages/tabbar/tea-home',  
        iconPath: '/static/images/tabbar/home.png',  
        selectedIconPath: '/static/images/tabbar/home-active.png',  
        complete: (e) => {  
            console.log('======= Home', e);  
        }  
    });  
});  
</script>

6、关于我为什么不使用 pagePath 这个属性直接替代页面,有三点给大家解释下:第一点:H5页面完全失效,刷新会失去tabbar;第二点:APP中系统杀死APP后再次进入会丢失tabbar;第三点:如果是自定义tabbar会有闪烁的情况。

7、大家也可以尝试其他方案,这只是本人遇到的问题及解决思路。

继续阅读 »

官方文档:https://uniapp.dcloud.net.cn/api/ui/tabbar.html#settabbaritem

看不懂的看我的解决方案:

1、pages.json里面按照要求配置好最全数量的tabbar,一定要按照最大数量配置,切记!!!并且此时对应的tabbar页面是公共的tabbar(最大数量为5个)例如ont,two,three。

2、将不同角色的页面提前创建好,写好自己的业务内容,此页面无需在 pages.json 中配置,作为一个组件引入即可。

3、在所有进入tabbar页面的url处一定要处理好标识,比如A角色=1,B角色=2。然后使用 switchTab 跳转对应的tabbar公共页面。

4、在公共的tabbar页面根据角色标识判断展示对应的组件(此组件为第2步创建的页面)。

5、在所有公共的tabbar页面的 onShow 函数中处理tabbar,以下是我的伪代码:

<script setup name="">  
import { onShow } from '@dcloudio/uni-app';  
import storage from '@/common/utils/storage.js';  

onShow(() => {  
    console.log(storage.getStorageSync('role'));  
    uni.setTabBarItem({  
        index: 0,  
        text: 'Home',  
        // pagePath: '/pages/tabbar/tea-home',  
        iconPath: '/static/images/tabbar/home.png',  
        selectedIconPath: '/static/images/tabbar/home-active.png',  
        complete: (e) => {  
            console.log('======= Home', e);  
        }  
    });  
});  
</script>

6、关于我为什么不使用 pagePath 这个属性直接替代页面,有三点给大家解释下:第一点:H5页面完全失效,刷新会失去tabbar;第二点:APP中系统杀死APP后再次进入会丢失tabbar;第三点:如果是自定义tabbar会有闪烁的情况。

7、大家也可以尝试其他方案,这只是本人遇到的问题及解决思路。

收起阅读 »