使用uView UI+UniApp开发微信小程序

在前面随笔的介绍中,我们已经为各种框架,已经准备了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 根据状态码自己去加入,如下代码所示。

 

 用户完成登录,并成功获取身份信息后,切换到指定的页面,如下界面效果所示

 

posted on 2021-09-03 10:26  伍华聪  阅读(13496)  评论(5编辑  收藏  举报

导航