uni-app 小程序从零开始的开发流程

前言

本文基于 HBuilderX 3.1.22 + 微信开发者工具 1.05.2106300为主要内容进行说明。

文档版本:1.0.2

更新时间:2021-09-04 16:42; 2021-10-22 13:46;

一、准备

uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/QQ/快手/钉钉/淘宝)、快应用等多个平台。

1.1 软件安装

创建uni-app有两种,一个是通过 HBuilderX 可视化界面,另一个是通过vue-cli命令行。本文档以HbuilderX为创建说明,以微信开发者工具进行运行项目和代码说明。

HbuilderX 下载地址:https://www.dcloud.io/hbuilderx.html

HbuilderX 文档地址:https://hx.dcloud.net.cn/Tutorial/startup

微信开发者工具下载地址:https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html

HbuilderX安装结束后,一般需要下载开发项目需要的插件,选择工具-->插件安装-->安装或去市场插件查找下载,然后放到目录下的uni_modules文件夹(安装时候自动生成),如scss/sass编译,App真机运行等。

微信开发者工具安装结束后,在工具栏上选择 设置-->通用设置-->安全-->打开服务端口

其次,在微信开发者平台(https://open.weixin.qq.com/)注册开发者账号,找到自己的开发ID,AppId,并记录好,为项目从HbuilderX运行到微信开发者工具做准备。

然后,在微信公众平台(https://mp.weixin.qq.com/)注册对应的账号,比如本次注册的是小程序,则微信开发者APPID如下图中找到:

 接着配置微信开发者工具的AppId,在微信开发者工具界面点击右上角详情->基本信息->AppId进行配置,如下图:

开发环境下配置:点击右上角详情->本地设置->打钩"不校验合法域名....",如下图:

1.2 vue入门

由于uni-app是以vue为基础的小程序开发,所以使用uni-app之前需要对vue有一定的了解。

vue 文档地址:https://vuejs.bootcss.com/guide/

二、基于HbuilderX 的uni-app项目搭建

2.1 创建项目

1.在点击工具栏里的文件 -> 新建 -> 项目

2.选择uni-app类型,输入工程名,选择模板,点击创建,即可成功创建。

uni-app自带的模板有 Hello uni-app ,是官方的组件和API示例。还有一个重要模板是 uni ui项目模板,日常开发可以参考该模板,毕竟这个模板已内置大量常用组件。

然后在HBuilder X内工具栏点击 运行—>运行到小程序模拟器 -->微信开发者工具,便能初步看到运行成效。

2.2 目录补充搭建

本次创建使用默认版本,创建后的目录如下:

1 根据需要给项目搭建相应的目录结构。尚未下载依赖和市场插件之前,创建需要的文件夹和文件:

2 如果要下载vue,vuex等依赖,在之前需要先安装node.js,并且安装好node的包管理器(npm,cnpm,yarn等,一个即可,本文档以npm为例)

node相关地址:http://nodejs.cn/

安装教程:https://www.runoob.com/nodejs/nodejs-install-setup.html

A. 初始化package.json文件

B.使用代码,其中注意最好加上--save

  npm install vue --save
  npm install vuex --save   
npm install uview-ui --save

下载vue和uview依赖。其中,vue是开发uni-app必要的依赖,uview则是uni-app生态的一个优秀的UI框架,本文档以uview作为前端UI开发框架为基础进行开发搭建。执行下载后,项目会自动把依赖放进node_modules文件夹内,可在node_modules文件夹进行查看。然后下载开发项目需要的市场插件,市场插件默认自行创建插件所在文件夹uni_modules,并存放插件于此。

vue相关地址:https://vuejs.bootcss.com/guide/

vuex相关地址:https://vuex.vuejs.org/zh/installation.html

uview相关地址:https://www.uviewui.com/components/intro.html

最后,创建页面和对应页面的api文件(本文档仅以登录页面、主页面和登录api文件为例),这样一个基本的结构接搭建好了,最终结构目录大体如下:

其中.hbuilderx,unpackage文件夹是自动生成,不必自主创建。node_modules,uni_modules文件夹里的文件最好不必去改动。

C.目录结构说明如下:

层级1层级2层级3描述
api     各个模块接口文件夹
  login.js   登录模块接口文件
common     公共模块,包含公共基础css等
  base.css   公共基础css
components     符合vue组件规范的uni-app组件目录
node_modules     nodejs相关依赖包文件目录
pages     业务页面文件存放的目录
  index   index文件夹
    index.vue 主页面
  login   login文件夹
    index.vue 登录主页面
static     存放应用引用的本地静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此,不要放css文件
store     vuex目录,也是存放公共属性方法的地方
  index.js   vuex的主文件
uni_modules     插件市场下载的第三方UI组件目录,存放uni_module规范的插件。
unpackage     打包目录,这里有各个平台的打包文件。
utils     全局公共方法目录
  common.js   封装的公共可复用的方法属性文件(针对当前项目)
  request.js   封装的公共请求方法文件
  utils.js   封装的公共可复用的方法属性文件(针对所有项目)
App.vue     应用配置文件,用来配置App全局样式以及监听应用生命周期
main.js     Vue初始化入口文件
manifest.json     配置应用名称、appid、logo、版本等打包信息的文件
package.json     项目配置信息文件,依赖模块的定义
package-lock.json    

1.锁定包的版本,确保再次下载时不会因为包版本不同而产生问题

2.加快下载速度,因为该文件中已经记录了项目所依赖第三方包的树状结构和包的下载地址,重新安装时只需下载即可,不需要做额外的工作

pages.json     配置页面路由、导航条、选项卡等页面类信息的文件
uni.scss     自带的公共的css修饰文件
README.md     文档说明,可包含目录文件名称对比,注意事项,框架使用,技术架构,Git或SVN地址,账号密码等

由于在pages创建了登录页面,所以需要到pages.json去配置相关路径。

pages.json

    "pages": [ 
        {
            "path": "pages/login/index",
            "style": {
                "navigationBarTitleText": "登录"
            }
        },
        {
            "path": "pages/index/index",
            "style": {
                "navigationBarTitleText": "首页"
            }
        }
    ]

<!--注意:-->

  • 编译到任意平台时,static 目录下的文件均会被完整打包进去,且不会编译。

  • 非 static 目录下的文件(vue、js、css 等)只有被引用到才会被打包编译进去。static 目录下的 js 文件不会被编译,如果里面有 es6 的代码,不经过转换直接运行,在手机设备上会报错。

  • css、less/scss 等资源不要放在 static 目录下,建议这些公用的资源放在自建的 common 目录下。

2.3 搭建目录文件代码

根据需要,我们写一个简单的登录,使用登录功能来阐述各个目录文件之间的联系。

首先,我们先把已创建的相关文件进行挂载到全局,即在main.js或者App.vue写相关代码:

main.js

App.vue

然后在被引入的文件写必要的内容信息:

base.css

  .clearfix:before{content:" ";display:table}
  .clearfix:after{content:" ";display:table;clear:both}
  .fl{float:left}
  .fr{float:right}

request.js

export default function request({
    url,
    method = "GET",
    params = {},
    header,
    loadding = false,
    loaddingText = "加载中..."
}) {
    return new Promise((resolve, reject) => {
​
        if (loadding) {
            uni.showLoading({
                title: loaddingText
            })
        }
        setTimeout(() => {
            uni.request({
                url,
                method,
                data: params,
                header,
                success: (res) => {
                    if (res) {
                        resolve(res.data)
                    } else {
                        resolve(res)
                    }
                    if (loadding) {
                        uni.hideLoading()
                    }
                },
                fail: (res) => {
                    reject(res)
                }
            })
        }, 1000)
    }).catch(err => {
        // 这里既可以捕获throw的异常也可以捕获reject的异常
        console.log("[Promise catch]:", err)
        if (loadding) {
            uni.hideLoading()
        }
     return Promise.reject(err) }) }

common.js

export default {
    BASE_URL:""
}

然后我们开始写登录页面。登录页面需要写用户名、密码、登录按钮三个组件,则需要使用uview创建。使用uview创建组件之前的几个确保:

确保1 HBuilder X 是安装了 scss/sass 编译插件

确保2 在根目录下 uni.scss 文件中引入 uview-ui/theme.scss

@import 'uview-ui/theme.scss';

确保3 在根目录下 App.vue 文件中的style代码块添加 lang="scss"属性 和 引入 uview-ui/index.scss

<style lang="scss">
    @import "uview-ui/index.scss";
</style>

确保4 在根目录下main.js文件中 引入并使用uView的JS库,注意这两行要放在import Vue之后。

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

如果是不想书写引入文件代码,即我们每当引入一个UI组件,就需要添加

import xxx from "uView-ui/components/u-xxx/u-xxx.vue";

等相关代码。则需要确保5 在根目录下pages.json文件中 ,配置easycom组件模式

// pages.json
{
    "easycom": {
        "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
    },
    
    // 此为本身已有的内容
    "pages": [
        // ......
    ]
}

接着我们在pages/login/index.vue,即登录页面中,引入uview组件和书写登录代码:

pages/login/index.vue

<template>
    <view class="content">
        <view class="inp">
            <u-input v-model="username" type="text" :border="true" placeholder="请输入用户名" />
        </view>
        <view class="inp">
            <u-input v-model="password" type="password" :border="true" placeholder="请输入密码" />
        </view>
        <view class="inp">
            <u-button type="primary" shape="circle" style="margin-top: 40rpx;" @click="onLogin">登录</u-button>
        </view>
    </view>
</template>

<script>
    import {
        login
    } from '@/api/login.js'
    export default {
        data() {
            return {
                username: '',
                password: ''
            }
        },
        onLoad() {

        },
        methods: {
            onLogin() {
                // #ifdef MP-WEIXIN
                uni.login({
                    success: res0 => {
                        login({
                            params: {
                                username: this.username,
                                password: this.password,
                                code: res0.code
                            },
                            loadding: true,
                            loaddingText: "登录中..."
                        }).then(res => {
                            this.$store.state.userinfo = res
                            if (res) {
                                uni.reLaunch({
                                    url: "../index/index"
                                })
                            } else {
                                uni.showToast({
                                    title: "登录失败",
                                    duration: 1000,
                                    icon: "none"
                                })
                            }
                        })
                    },
                    fail: err => {
                        console.log("fail:", err)
                    }
                })
                // #endif
                // #ifdef  H5
                uni.reLaunch({
                    url: "../index/index"
                })
                // #endif
            }
        }
    }
</script>

<style scoped lang="scss">
    .content {
        padding: 20px;

        .inp {
            margin: 10px;
        }
    }
</style>

以上代码为先进行获取用户登录凭证code,然后才正式登录。因为开发者需要在开发者服务器后台,使用 code 换取 openid 和 session_key 等信息。然后使用得到的code,和用户名密码一起作为参数进行真正的登录请求。其中,样式最好内聚在组件内,组件内部使用的样式,尽量在style中添加scoped,编译时会增加组件hash前缀来防止样式污染。

login页面 有请求数据,则需要写login.js请求接口:

login.js

import common from '@/utils/common.js'
import request from '@/utils/request.js'

// 登录
export async function login(payload) {
    return await request({
        url: common.BASE_URL + "http://rap2api.taobao.org/app/mock/229799/http://login",
        method: "POST",
        params: payload.params,
        loadding: payload.loadding,
        loaddingText: payload.loaddingText
    })
}

login页面 有使用 this.$store.state,则需要对store/index.js写代码:

store/index.js

import Vue from 'vue';
import Vuex from "vuex";
Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        userinfo: ""
    },
    actions: {

    },
    mutations: {

    },
    getters: {

    }
})

到此,直接点击工具栏上的运行-->运行到小程序模拟器-->微信开发者工具,结果如下图所示:

然后如果要进行调试,则需要打开调试器,点击调试器界面的source选项,找到对应的代码文件,进行断点调试,比如:

或者直接使用H5模式运行到浏览器,在移除相关会影响代码调试的微信开发者工具方法或属性后,在网页上打开控制台进行调试代码。需要注意的是,部分样式在H5和微信小程序中显示有区别,尽量以小程序显示为主。

三、打包发行

使用hbuilderx进行打包发行小程序,点击工具栏的发行 --> 小程序-微信,然后它会自主打开微信开发者工具界面,这时候我们点击右上角的上传按钮,填写版本号、描述相关信息 - 确定即可。

四、注意事项

事项1

@import "uview-ui/index.scss";

如果引入在除了App.vue之外的文件,而App.vue本身没有引入,可能会引起样式不全修饰等问题,比如登录的密码输入框,当输入密码时候显示清空按钮,此时会让密码框下移。

事项2

打包微信小程序只有包小于2MB才能上传。

posted @ 2021-09-03 17:50  烈雾风雨城  阅读(4360)  评论(0编辑  收藏  举报