uni-app小程序2021再次起航

1,057 阅读5分钟

通过HBuilderXi创建项目

uniapp.dcloud.io/quickstart-…

uView组件库

uView安装

uni-app之uview-ui框架安装使用教程

uview配置的原理

1. 引入uView主JS库

// main.js
import uView from "uview-ui";
Vue.use(uView);

2. 引入uView的全局SCSS主题文件

uni-app不支持将SCSS变量相关的样式通过App.vue引入,为了统一的主题,以及日后的扩展, 目前一些跟颜色相关的scss变量定义在全局变量中,这些变量有独特的命名(u-开头),不会与您的类名冲突。

这些变量需要写入到项目根目录的uni.scss中才有效(这是uni-app的机制问题),它有一个特点是,编译成微信小程序后,不但注入到小程序工程 根目录的app.wxss(全局样式文件),而且还会同步注入到每一个页面单独的*.wxss中,所以如果您在uni.scss中的样式很多的话,有可能导致 微信小程序编译单个包超出限制的2M大小,整包超出最大的12M大小,从而导致无法真机调试和发布微信小程序。

所以,我们建议,只将一些跟scss主题,变量相关的样式写入到uni.scss,而其他一般的全局样式文件,通过App.vue引入即可,在微信小程序编译的时候, 它只会编译到小程序根目录的app.wxss中,而不会注入到其他的单个页面的样式中。

3. 引入基础样式

由于目前(2020-04-29)uni-app的V3模式不支持在main.js中引入样式文件,故需要在App.vue中引入uView的基础全局样式。

同时上面第2点也有说明,App.vue的样式为全局样式,微信小程序编译后只会注入到小程序根目录的app.wxss中。

4. 配置easycom组件模式

easycom功能可以让用户无需安装、引用、注册,三个步骤后才能使用组件,详见easycom文档

easycom的另一个最大的特点是,它是按需引入的,所以您引入了整个uView组件,即使只用到了button组件,最终打包的时候只会把button打包进去,其他的组件都会被剔除。

Hbuilder X自2.5.1版开始正式支持easycom特性,HX2.5.5版支持自动引入components/组件名称/组件名称.vue,考虑到用户的一些自定义组件 都会放在components目录中,为了不和用户的自定义组件混淆,同时也是为了能让用户一键升级uView,所以我们把uView相关的所有内容都放在了根目录的 uview-ui文件夹中。

uview配置

1.将uview-ui拷进项目

2.在pages.json文件最上面添加

"easycom": {
	"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
},

3.在APP文件中引用以下scss

<style lang="scss">
  /*每个页面公共css */
  @import 'uview-ui/index.scss'; //引用uview-ui框架样式
  @import 'styles/index.scss'; //引用自定义变量
  @import 'styles/uview.scss'; //引用修改的uview-ui自定义养殖
</style>

@import "./static/css/common/iconfont.css"; //引用字体样式库

4.在uni.scss文件中引用以下scss

@import 'uview-ui/theme.scss'; //uView UI的集成样式文件
@import 'styles/mixin.scss'; //项目自定义scss变量

5.在main.js 引入全局uView

import uView from 'uview-ui'
Vue.use(uView);

配置多端环境

www.cnblogs.com/zhangyezi/p…

vscode插件

uniapp-snippet (uniapp 代码片段提示)

从github上下载 uni-app 代码块,放到项目的.vscode目录下

callback改成promise

//callback
export function autoAppLogin(callback = null) {
  autoWxLogin((success) => {
    if (success) {
      getUserLoginStatus()
        .then((res) => {
          if (res.code == 100) {
            saveUserInfoAndToken(res.data);
            callback ? callback(true) : null;
          } else {
            callback ? callback(false) : null;
          }
        })
        .catch((rej) => {
          callback ? callback(false) : null;
        });
    } else {
      callback ? callback(false) : null;
    }
  });
}

//promise

//自动App登录
export async function autoAppLogin(){
	return await new Promise((resolve)=>{
		const { unionId, openId } = getStorage('userInfo')
    getUserLoginStatus(unionId, openId)
      .then(res=>{
        if(res.code == 100){
          saveUserInfoAndToken(res.data)
          resolve(true)
        }else{
          resolve(false)
        }
    	})
     .catch(()=>{
     	 resolve(false)
    })
	})
}

小程序体积优化策略

uni-app分包优化、页面预加载、页面跳转封装

分包加载

配置分包(普通分包)

配置独立分包

  • 当小程序从普通的分包页面启动时,需要首先下载主包;
  • 而独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度。
  • 把只被分包使用的资源收集到分包里,比如图片,js模块,组件,npm包
  • 为了确保主包体积最优,对于组件和静态资源,如果他们被多个分包所引用且未在主包中引用,可以将这些资源生成多份副本分别输出到对应分包中,而不会占用主包体积。

微信首次加载loading优化

有的小程序进去会有类型于这样的界面,这个是小程序自带的还是额外的

首次打开,网速慢可能会出现, 数据包在下载。

uni-app通过HBuilderX导入

uCharts图表的安装步骤

  1. 添加uni_modules插件

  1. 使用

GoEasy IM聊天和即时通讯

nvue视频弹幕

uni-app引用npm第三方库

npm init -y

uni-app中引入moment.js插件

uniapp小程序接入友盟

npm install umtrack-wx --save


import uma from 'umtrack-wx';
//友盟埋点统计
uma.init({
	appKey: '6114db03e623447a331bc941',
	useOpenid: true,
	autoGetOpenid: true,
	debug: false,
	uploadUserInfo: true,
});

uma.install = function (Vue) {
	Vue.prototype.$uma = uma;
}
Vue.use(uma);

原生小程序npm 支持

原生小程序开发,通过npm构建,会自动生成miniprogram_npm文件放置插件内容

利用camera组件自定义小程序相机拍照效果

参考链接:

疑问

为什么要用wx.checkSession()

uniapp使用/deep/修改uview组件样式小程序无效

使用uview的u-select组件,设计稿和原样式不一致,需要修改样式,代码如下:

<style lang="scss" scoped>
/deep/.u-select {
	.u-drawer-bottom {
		border-radius: 24px;
	}
	.u-select__header__cancel {
		background: #f3f6f6;
		border-radius: 100rpx;
		width: 132rpx;
		height: 62rpx;
		line-height: 62rpx;
		text-align: center;
	}

	.u-select__header__title {
		color: red;
	}
}
</style>

封装的组件,在该组件页面中添加修改样式,尝试了/deep/,important,外层单独写个class覆盖,都无效。

但是又不能直接就该component的源码,目前采用全局样式控制,有效。







修改滑动的高度

需要修改组件:

  • 全局修改样式
  • 多添加了两个传递参数,修改选择器高度,默认是 34px
//设置选择器中间选中框的样式 单位只支持px
indicatorStyle: {
    type: String,
    default: 'height:50px',
},
pickerColumnStyle: {
    type: Object,
    default: () => {
        'line-height:50px;'
    },
},
//设置弹出层的圆角
popupRadius: {
  type: Number | String,
  default: 0,
},
  • 修改 picker-view 样式
<picker-view
    :indicator-style="indicatorStyle"
>
    <picker-view-column
        v-for="(item, index) in columnData"
        :key="index"
        :style="pickerColumnStyle"
    >
    </picker-view-column>
</picker-view>
  • 修改圆角
<u-popup
    :border-radius="popupRadius"
>

使用全局变量

全局定义的变量 在template中直接使用,返回undefined?

原因:uni-app 目前微信小程序 template中不支持使用原型上的变量渲染

解决:

  • mixins只是全局混入,方便使用,只要在data或computed里定义一下,就可以在template中使用

小程序添加使用背景图片

只支持行内样式,要写在标签上:background和backgroundSize

<div
    class="mine-view"
    :style="[
        {
            background: `url(${PUBLIC_IMG_PATH}/diabetes-images/mine-bg-2.png)  no-repeat `,
            backgroundSize: 'cover'
        },
    ]"
>
</div>

.mine-view {
    width: 100%;
    height: 144px;
}

页面之间的传参,让下一个页面接收上一个页面的值

根据时分确定分段

const curStr = '2021-09-03 12:30'
		const curDate = this.$u.timeFormat(curStr, 'yyyy-mm-dd')
		let cutTime = new Date(curStr).getTime()
		const dayTime = 24 * 60 * 60 * 1000
		const rangeList = [
			{code: 11, id: 11, start: '04:00', end: '09:00'},
			{code: 12, id: 12, start: '09:00', end: '10:30'},
			{code: 21, id: 21, start: '10:30', end: '12:00'},
			{code: 22, id: 22, start: '12:00', end: '15:00'},
			{code: 31, id: 31, start: '15:00', end: '17:30'},
			{code: 32, id: 32, start: '17:30', end: '20:30'},
			{code: 41, id: 41, start: '20:30', end: '04:00'},
		].map(item => ({
			...item,
			start: new Date(curDate + ' ' + item.start).getTime(),
			end: new Date(curDate + ' ' + item.end).getTime() + (item.end < item.start ? dayTime : 0),
		}))

		console.log(rangeList, 'rangeList')
		if (cutTime < rangeList[0].start) {
			cutTime += dayTime
		}
		const find = rangeList.find(({start, end}) => cutTime >= start && cutTime < end)
		console.log(find, 'find')

打包预览时报错

message:Error: 系统错误,错误码:80200,main package source size 4540KB exceed max limit 2MB [20211012 20:06:30][wx90228c8fea61cf6f]
appid: wx90228c8fea61cf6f
openid: o6zAJs9zyx85gfzaictAO8nwwJns
ideVersion: 1.05.2109262
osType: darwin-x64
time: 2021-10-12 20:09:03

自定义组件建议移动到子包 packageA 内

HBuilderX编译提出的,可忽略。

uni-app编译后 vendor.js 文件过大

解决:选中运行时是否压缩代码

但是开启运行时是否压缩代码之后,console.log的数据就打印不出来了。

原因:在vue.config.js中设置了去除打印的代码

// 发行或运行时启用了压缩时会生效
config.optimization.minimizer('terser').tap(args => {
        const compress = args[0].terserOptions.compress
        // 非 App 平台移除 console 代码(包含所有 console 方法,如 log,debug,info...)
        compress.drop_console = true
        compress.drop_debugger = true // 移除debugger
        compress.pure_funcs = [
                '__f__', // App 平台 vue 移除日志代码
                'console.debug', // 可移除指定的 console 方法
                'console.log',
                'console.info',
        ]
        return args
})

结果:vendor.js大小变小

引入的uview-ui文件过大

原因:

  • 重复引入了scss,wxss过大。

uni.scss文件里的代码是给你全局的任何一个scss文件里面自动添加的,其目的是为了全局引入scss的变量,方法,之类的,至于样式scss代码不需要在uni. scss中引入。

不应该在uni.scss中引入自己定义的scss文件。

解决:

  1. 将自定义的scss文件在app.vue中引入
  • 全局的scss变量在uni.scss里引入
  • 全局的scss样式代码在app.vue里引入

  1. manifest.json–>微信小程序配置,勾选上传自动补齐,上传压缩代码

结果:

Infinity问题

设置了max: Infinity,但是通过find获取之后,max返回值成null

{
    value: '严重',
    level: 5,
    min: 19.05,
    max: Infinity,
    sendColor: ['#F78720', '#F72020'],
},

字体包引入

字体包引入问题:封装引入字体包,使用uni.loadFontFace效果是有的,但是有问题:首次进入页面时,会先展示默认字体,半秒左右切换至自定义字体,

解决:使用@font-face引入静态资源。

wx.loadFontFace({
  family: 'Bitstream Vera Serif Bold',
  source: 'url("https://sungd.github.io/Pacifico.ttf")',
  success: console.log
})
//设置
@font-face {
	font-family: D-DIN-PRO-SemiBold;
	src: url('~@/static/font/D-DIN-PRO-600-SemiBold.otf');
}

//引用
.werun-num {
	@include font-size-medium(64, 500);
	font-family: D-DIN-PRO-SemiBold;
}



@mixin font-size-num($s, $w: 600) {
	font-family: D-DIN-PRO-SemiBold;
	font-size: $s + rpx;
	font-weight: $w;
}

uniapp分页

问题:uniapp分页时,小程序自带的onReachBottom触底方法总是不灵敏,设置onReachBottomDistance(距离底部距离)也无效。后来百度发现:小程序的  触底事件不能在350ms之内频繁触发 也就是说它有350ms的频率限制。

解决:使用scroll-view,注意设置upper-threshold,距顶部/左 边多远时,触发 scrolltoupper 事件,否则不是很灵敏。

<scroll-view
  scroll-y
  :upper-threshold="200"
  scroll-anchoring
  @scrolltolower="reachBottom"
>

</scroll-view>

问题:列表滚动 滚动区域 在不同机型会出现高度不足的情况,导致列表到底不会继续加载,数据显示不完整

解决:scroll-view不支持calc 计算得出的高度的,需要在外出嵌套一个父级并设置高度,子级 设置高度 100%