我一直认为文章的时效性是一个很重要的参数。我在看别人写的文章或者博客的时候,会特别注意文章的发布日期。当文章发布的日期超过1年的时候,我就会开始警惕文章的内容是否有效,时间越长越是如此(基础性的知识可以不受这个范围的约束)。
知识是不断更新的,旧有的已经被淘汰的知识本身的价值是很小的。在我们互联网的前端开发这个职业里面更是如此。所以这里我会给出文章发布的具体日期,供后面的人参考。
发布日期:2020/5/26
专插本刷题宝是我使用uniapp做的第一个微信小程序项目。这篇文章主要讲述我在刷题宝小程序的实践。
小程序跟平常的vue项目有着诸多的不同,我在开发的时候遇到了许多值得我去优化的地方,不知道这些问题其他人有没有遇到。已经解决的就当是在看我自己的总结,如果没有遇到过,那很好,这个问题已经有我先踩过坑啦!
希望看这篇文章之前,先看一下 泛谈一下uniapp以及我的想法这篇文章,这样有便于理解我选择解决方案的原因。
这是之前我提到过的专门针对v3版本的UI框架,我也在项目中实践过了,组件丰富,群里面很活跃。
群QQ:1042987248
uview-ui官方文档(腾讯服务器), 最近这个网站会被攻击,可能是因为作者触碰了什么人的蛋糕吧。
uview-ui官方文档(gitee),备用。
uView要求项目开启uniapp的V3版本,V3有很大的优势,详见V3版本介绍
uniapp中,能异步的api都可以使用promise!,这关乎到项目的异步流程使用上是否便利。详情看uni的api的promise封装
uni-app 对部分 API 进行了 Promise 封装,返回数据的第一个参数是错误对象,第二个参数是返回数据。
详细策略如下:
- 异步的方法,如果不传入 success、fail、complete 等 callback 参数,将以 Promise 返回数据。例如:uni.getImageInfo()
- 异步的方法且有返回对象,如果希望获取返回对象,必须至少传入一项 success、fail、complete 等 callback 参数。例如:uni.connectSocket()
- 同步的方法(即以 sync 结束),不封装 Promise。例如:uni.getSystemInfoSync()
- 以 create 开头的方法,不封装 Promise。例如:uni.createMapContext()
- 以 manager 结束的方法,不封装 Promise。例如:uni.getBackgroundAudioManager()
//default
uni.showModal({
title:'这里是弹窗',
success(res){},
fail(error){}
})
//promise (只要不传入 success、fail、complete这些回调就返回promise)
uni.showModal({
title:'这里是弹窗'
}).then([error,res]){
//error 同原本 error
//res 同原本的 res
}
//async/await
let [error,res] = await uni.showModal({
title:'这里是弹窗'
})
这里我强烈推荐async/await,我发现promise在某些情况下不能很好的解决异步流程,但是用async/await就能够使异步流程很清晰
请求的封装,我认为是项目中比较关健的部分。插件市场有很多请求的封装,我试过2到3款,之所以一直换是因为在实际开发的时候都遇到了bug或者特性无法满足需求,到后面我最终选定了luch-request。
选择的原因:
luch-request NPM,luch-request 插件市场
uview-ui自己本身也有自己做请求封装文件的,如果后续有需要我会试试
这是个很好用的方式,挂载在原型链上面,所有页面和组件都能简单的通过this来快速使用。
但唯独一个缺点
//main.js
Vue.prototype.$store = store
//微信小程序中,在模板中使用这个变量,会报错,这是只有在微信小程序才会出现的问题,其他各端都支持!
<template>
<view>{{$store}}</view>
</template>
使用Vue.mixin 来做全局的数据共享。我就是使用这个来代替prototype无法解决的问题。当然你还能混入你想要的其他特性,包括但不限于watch、methods。
import {
mapGetters
} from 'vuex';
Vue.mixin({
computed: {
...mapGetters(['baseURL'])
//......
},
})
//普通的page页面的template中
//img:/public/uploads/uploadImage/20200110/520bedb.jpg
<template>
<image :src="`${baseURL}${img}`"/>
</template>
这个可能是我最不用多介绍的一个,熟悉使用vue的开发者都知道用这个的好处。
我个人更喜欢的用法,主要是使用映射:
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
export default {
data() {
return {}
},
computed: {
...mapGetters(['userInfo']),
},
methods: {
...mapMutations(['setUserInfo']),
...mapActions(['getUserInfo']),
}
}
这时候有人会说,可以使用this.$store.commit(),的确是的,我不喜欢这样使用,主要还是因为微信小程序的模板不能直接使用挂载在prototype上的变量。(因人而异,喜欢就好)
同时顺便介绍一下,可能是大家都知道的小技巧,vuex的modules的自动引入,通过node的支持,能够在编译文件的时候对modules内的文件自动引入,这样每次新增module都不需要单独引入,如下图:
这个是微信小程序中普遍使用的,uniapp也是继承了这个特性,但是我不推荐使用,因为数据不是响应式的,大多数情况下直接使用vuex会更好。globalDate我认为的唯一的优势就是轻量。
或许这里面有我没有发现的好呢,知道的小伙伴可以指出来
tabbar页面只能放在主包, 不能写进分包中,那样会报错
分包之间资源是不能互相引用的。主包的公用资源是可以共同使用
这里面我认为没有必要这么死板参照文档那样去设置,每个人有自己的习惯,这里我也说说我自己的做法,如下图:
开启方法(微信小程序),如下图:
静态文件:分包下支持 static 等静态资源拷贝,即分包目录内放置的静态资源不会被打包到主包中,也不可在主包中使用
上面这条我认为比较重要的,因为我现在做的项目经常会有一个背景图片资源是有200k的,如果都分到主包中,肯定都是不行的,很容易超过2M的限制,所以我是做了这个优化的。当然除了图片之外,我这边还将当前分包单独使用的组件也放入到分包来,如下图:
course
--components //存放局部组件
--pages //存放页面
--static //存放静态资源
这里面除了static这个静态资源文件是硬性要求,一定得放在分包根目录下面,其余的都是可以随意安排的,这里主要讲的我的选择。
什么时候分包好? 最好创项目一开始就把分包的大致结构弄出来,需要的时候就增加。我自己是在项目完成之后才来处理分包的,结果就是各类的资源的搬运,所有路径都要逐一修改,容易出错,最后花了我不少时间去改这个,如果一开始就做这样的处理就能避免这种问题(旧的项目想做分包的,估计会有点累吧)
1.莫名的报错提示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bqvo6yb6-1594305724163)(http://insectq.199604.com/img/image-20200522144438938.png)]
关于这个请看分包优化说明
自定义组件:若某个自定义组件仅被一个分包引用时,且未放入到分包内,编译时会输出提示信息
于是你会看到, 连uni-ui的组件也会这么被提示。这是建议,并不是报错。
开放能力主要体现为:获取用户信息,分享,登录,订阅。这是一个极其重要的功能。
现状
微信将所有开放能力都赋予 button组件, 没法像以前用js调用开放能力。当使用开发能力的通常需要使用button来“包裹”一个需要被点击的元素,但其中button自带的样式是个很令人头疼的事情,同时存在其他问题。
原因
这里我并没有查证具体原因,但我猜测一下,多半是因为安全考虑的,微信官方不希望有人恶意使用开放能力,为了防止用户被误导的可能性,于是都做成了button,这样所有的开放能力都需要通过用户的主动点击的行为来触发,减少被恶意使用的可能性。
这里说一个项目中的真实案例
项目中部分功能或者入口是需要用户授权手机号才能够使用的,具体代码会如下:
前面也说到这种开放能力依赖button,而我实际上使用发现这个授权按钮,每次点击都会申请授权,这样无论是对于用户还是对于开发者来说都是很不便的。
我怎么处理这样的问题?
我借鉴了组件navigator和传统的a标签的思路,这类标签的性质就像是:赋予“被包裹”的元素单一功能,除此之外,这个组件或者标签不承担任何其他的功能和样式表现,所有的内外的其他性质都可以随意穿过“这一层”。
我照着以上思路封装了一个组件,实现思路的关健
这种做法可以在很多场景中使用,比如要求必须登录的可点击入口,这中做法值得去挖掘
富文本方案通常是使用rich-text即可,但当产品提出希望能拥有更加强大的功能的时候,则需要考虑另外的方案。
插件市场关于富文本的插件很多,但因为v3编译器,大多都失效了。这里我推荐Parser富文本插件,原因?因为我实践过,能用,好用,就是这么简单。有进入动画、图片懒加载、图片预览、长按菜单。
ps:希望作者能一直坚持下去(毕竟uniapp官方每次更新小版本都能弄出一堆bug)
我在项目中之所以使用到自定义导航栏是因为设计方面的需求出现了整个页面底下是背景图。
在面对这类需求的时候,有两个绕不开的变量:一个是 状态栏高度,一个是 导航栏高度。
下面图是uni-ui的status-bar自定义导航栏组件,能看到uni官方已经放弃了css变量–status-bar-height的使用(这个css变量在文档中是被官方推荐来解决状态栏高度问题的,现在不使用了却不在文档中修改说明,提醒开发者,这很有趣吧,这点我有点想吐槽uni官方)
可能的原因: css变量的 --status-bar-height 并不等于
uni.getSystemInfoSync().statusBarHeight
如何方便做到正式和测试环境的切换, 包含Appid的切换 (所有appid相关,比如: 支付)
微信小程序项目是否有样式重置这个概念?类似
view,text{
box-sizing: border-box;
}
其他已经测试过稳定的特性 (uview-ui作者给出)