在前面随笔的介绍中,我们已经为各种框架,已经准备了Web API、Winform端、Bootstrap-Vue的公司动态网站前端、Vue&Element的管理前端等内容,基本都是基于Web API基础的。完成这些基础准备和布局后,我们继续将技术的触角放到使用Vue语言开发小程序的场景中,本篇随笔介绍使用uView UI+UniApp开发微信小程序,介绍使用准备过程中的一些注意点和经验总结。
1、小程序的开发准备工作
我们在开发小程序之前,需要了解一些基本的知识,以及掌握一些常规的开发工具,相关知识最好能够在着手开始前有所掌握,然后在开发过程中逐步加强巩固即可。
1)Vue语言掌握
我们通过Vue官网https://cn.vuejs.org/v2/guide/index.html,了解相关的语言基础只是,这个部分我们利用Vue开发小程序的基础,必须先有所掌握相关基础知识,以及开发组件中涉及到的知识点。
Vue可以是我们后续前端开发的强力助手,如果我们掌握的好,对很多相关的处理会一目了然,否则可能不明所以,如Mixin混入、以及组件的事件属性的通讯关系、Vuex的存取处理、常用的JS模块、ES6的函数定义及Promise的处理等等。
随着我们对Vue开发的逐步熟悉,各种特性我们会一一记在脑中并能够熟练运用。
2)UniApp官网
我们需要了解UniApp的基础,包括它的相关理念,下面介绍的uViewUI本身也是基于它的进一步封装,使用UniApp和HbuliderX 工具可以开发各种不同的小程序,APP、H5等场景,不过我们这里着重考虑微信小程序。
3)uView UI官网
通过官网https://www.uviewui.com/components/intro.html,了解组件的使用,以及一些基础的知识,如easycom的约定、全局变量特别是Vuex的混入及使用过程、JS类库等处理。
我们本次开发小程序,需要利用uView UI的组件代码下载下来进行项目的整合使用,或者利用HBuilder X的工具,直接下载使用UniApp官网的uView UI插件模块。
uView UI提供了各种界面上用到的组件,几乎封装了我们常见到的各种界面元素,极大的方便了我们小程序界面的开发工作,如果有些特殊的功能界面,也可以从UniApp官网的插件列表中寻找进行整合。
4)官方小程序网站
通过官网https://developers.weixin.qq.com/miniprogram/dev/framework/了解微信小程序的基础知识,我们利用uView UI+UniApp开发微信小程序,本身还是对官方小程序接口的封装处理,我们有时候还是需要对其中的相关生命周期,底层函数等有一定的了解,才能更好的理解微信小程序的各种机制和处理方式。
5)开发工具
我们这里开发UniApp程序,推荐还是使用HBuilderX来开发,相对通用的前端开发工具VS Code来说,它的有些处理更特性化,然后熟悉配合《微信开发者工具》进行小程序的调试和部署即可。
2、uView UI的使用
以Web API为业务数据的接口基石,我们可以扩展很多业务管理端,包括Winform端、Vue&Element业务管理端、动态门户网站、微信小程序等等。
我们循例介绍一下uView UI的基础使用步骤,首先在项目中main.js引入对应的组件-引入uView主JS库。
// main.js import uView from "uview-ui"; Vue.use(uView);
检查uni.scss中已经加入了uView UI的样式,引入uView的全局SCSS主题文件
/* uni.scss */ @import 'uview-ui/theme.scss';
检查app.vue中加入了对应的样式,在App.vue
中首行的位置引入
<style lang="scss"> @import "uview-ui/index.scss"; @import "common/demo.scss"; </style>
一般来说,我们创建示例项目,都有这些基础的设置了,我这里只是循例介绍一下,让我们有所了解它的工作原理。
我这里还是主要介绍uView的this.$u的相关对象处理,它是通过Vue.prototype进行挂载进去的,也就是我们使用这些,都是uView加入的,如下main.js部分内容所示。
// 引入uView提供的对vuex的简写法文件 let vuexStore = require('@/store/$u.mixin.js') Vue.mixin(vuexStore) //引入后自动将Vuex里面的键作为Computed的属性 // 引入uView对小程序分享的mixin封装 let mpShare = require('uview-ui/libs/mixin/mpShare.js') Vue.mixin(mpShare)
在项目中,我们可以找到对应项目的store实现,以及uview对象Mixin混入的部分
它把登录信息相关的用户和令牌信息,通过storage的方式进行存储起来,并处理好相关的逻辑,这样混入后我们可以方便的通过混入的Computed属性获取到对应的值,或者快速的设置存储起来。
这里的SaveStateKeys就是设置存储到storage中的键,只要存在这两个键的内容,都可以快速的使用Vuex的处理,如下是获取内容。
<view class="u-flex-1"> <view class="u-font-16 u-p-b-20">用户名称:{{vuex_user.fullName}}</view> <view class="u-font-12 u-p-b-20">手机号:{{vuex_user.mobilePhone}}</view> <view class="u-font-12 ">邮箱:{{vuex_user.email}}</view> </view>
由于是页面对象的自动混入,我们甚至在JS代码里面都没有定义这两个对象,只需要记得这个键是我们的全局存储的对象即可。
例如我们在JS的模块里面,通过VM获得this的参数
即可直接调用对象存储处理,如下代码所示。
//缓存其他信息
vm.$u.vuex('vuex_user.name', name)
vm.$u.vuex('vuex_user.fullName', fullName)
vm.$u.vuex('vuex_user.mobilePhone', mobilePhone)
vm.$u.vuex('vuex_user.email', email)
vm.$u.vuex('vuex_user.roles', roles)
vm.$u.vuex('vuex_user.roles', roleNames)
如果是在页面组件中,我们则使用this代替vm的变量进行调用
this.$u.vuex('vuex_user.name', name)
storage的信息,可以通过小程序的调试工具进行查看到,如下截图所示。
3、小程序的登录状态判断及跳转
在业务系统中,我们需要根据登录用户的身份获取对应的数据,如果用户没有登录,这些信息是无法获到的,那么我们可以在app.vue中判断用户是否登录,然后调准到对应的页面,如下所示。
跳转判断在app.vue的程序启动逻辑中进行处理,如下代码所示。
<script> export default { globalData: { username: '' }, onLaunch() { //如果用户没有登录或令牌失效,跳转到登录界面 // console.log(this.vuex_token) if(!this.vuex_token) { this.$u.route({ url: 'pages/template/login/password' }); } else { uni.switchTab({ url: '/pages/example/myinfo' }); } }, } </script> <style lang="scss"> @import "uview-ui/index.scss"; @import "common/demo.scss"; </style>
其中 uni.switchTab 是跳转到首页的某个tab页面,如果我们的页面有tabbar页面的话。
用户登录的时候,需要输入用户名,密码,构建相关的参数后,进行登录处理
submit() { this.$refs.uForm.validate(valid => { if (valid) { this.$u.api.User.login(this.model).then(data => { // 登陆成功跳转到Tab页面 uni.switchTab({ url: '/pages/example/myinfo' }); }); } else { console.log('验证失败'); } }); },
其中 this.$u.api.User 是用户API接口的统一调用方式
我们在main.js代码里面看到安装了两个不同的JS模块,如下代码所示。
// http拦截器,将此部分放在new Vue()和app.$mount()之间,才能App.vue中正常使用 import httpInterceptor from '@/common/http.interceptor.js' Vue.use(httpInterceptor, app) // http接口API抽离,免于写url或者一些固定的参数 import httpApi from '@/common/http.api.js' Vue.use(httpApi, app)
其中第一个是统一http调用的设置,第二个这是引入一个api对象,方便调用api对应的接口,如下: this.$u.api.User
以及统一整合各个API对象
import User from '../api/user.js' // 此处第二个参数vm,就是我们在页面使用的this,你可以通过vm获取vuex等操作,更多内容详见uView对拦截器的介绍部分: // https://uviewui.com/js/http.html#%E4%BD%95%E8%B0%93%E8%AF%B7%E6%B1%82%E6%8B%A6%E6%88%AA%EF%BC%9F const install = (Vue, vm) => { // 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下 vm.$u.api = { // 将 vm 对象传递到模块中 User: User(vm) } } export default { install }
其中在http.interceptor.js里面,统一设置了api的Url的baseUrl,这样可以不用配置反向代理的转义,就可以简化API中URL的定义了。
const install = (Vue, vm) => { Vue.prototype.$u.http.setConfig({ baseUrl: 'http://localhost:27206/', //接口访问基础路径 showLoading: true, // 是否显示请求中的loading loadingText: '请求中...', // 请求loading中的文字提示 loadingTime: 800, // 在此时间内,请求还没回来的话,就显示加载中动画,单位ms // 如果将此值设置为true,拦截回调中将会返回服务端返回的所有数据response,而不是response.data // 设置为true后,就需要在this.$u.http.interceptor.response进行多一次的判断,请打印查看具体值 // originalData: true, // 设置自定义头部content-type // header: { // 'content-type': 'application/json;charset=UTF-8' // } })
另外我们返回的Response对象里面,有统一定义对象的,相关的数据可以参考随笔《利用过滤器Filter和特性Attribute实现对Web API返回结果的封装和统一异常处理》了解。
一旦程序处理过程中,有错误抛出,都会统一到这里进行处理,有异常的返回JSON如下所示。
其中结果result是用于检查是否执行成功的标识,这里用来判断是否有错误即可,有错误,则显示自定义错误信息
// 响应拦截,判断状态码是否通过 Vue.prototype.$u.http.interceptor.response = res => { // console.log(res) // 如果把originalData设置为了true,这里得到将会是服务器返回的所有的原始数据 // 判断可能变成了res.statueCode,或者res.data.code之类的,请打印查看结果 if (!vm.$u.test.isEmpty(res.success)) { // res为服务端返回值,可能有code,result等字段 // 这里对res.result进行返回,将会在this.$u.post(url).then(res => {})的then回调中的res的到 // 如果配置了originalData为true,请留意这里的返回值 return res.result } else { var msg = '' var data =res.result if (data && data.error && data.error.message) { msg = data.error.message vm.$u.toast(msg) } // 如果返回false,则会调用Promise的reject回调, // 并将进入this.$u.post(url).then().catch(res=>{})的catch回调中,res为服务端的返回值 return false } }
上面的拦截默认是基于状态码200的,如果我们自定义一些异常,指定了状态码的也需要拦截,需改uview-ui/libs/request/index.js 根据状态码自己去加入,如下代码所示。
用户完成登录,并成功获取身份信息后,切换到指定的页面,如下界面效果所示