一. 初始uni-app

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

1. 开发环境搭建,nodejshbuilderx

2. 应用开发流程

2.1 DCloud开发者中心注册账号并创建应用,获取AppID,去注册

在这里插入图片描述

2.2 创建uniapp项目

新建项目
项目模板

2.3 按照规范编写源代码
├── api                    # 所有请求
├── assets                 # 主题 字体等静态资源
├── common                 # 全局通用工具类
├── components             # 全局公用组件
├── language               # 国际化 language
├── store                  # 全局 store管理
├── pages                  # views 所有页面
├── ├──  index             # 视图模块名
├── ├── ├──  index.vue     # 模块入口页面
├── static                 # 存放应用引用静态资源(如图片、视频等)的目录
├── wxcomponents           # 小程序组件的目录
├── App.vue                # 入口页面,应用配置,配置App全局样式以及监听
├── main.js                # 入口文件 加载组件 初始化等
├── package.json           # package.json
├── manifest.json          # 配置应用名称、appid、logo、版本等打包信息
└── pages.json             # 配置页面路由、导航条、选项卡等页面类信息
2.4 应用调试运行

在这里插入图片描述

2.5 应用发布

二. 知识点梳理

1. 应用生命周期

<script>
export default {
	// 当uniapp初始化完成时进行触发,全局只触发一次
	onLaunch: function() {
		console.log('App Launch')
	},
	// 当uniapp启动或者从后台进入前台显示
	onShow: function() {
		console.log('App Show')
	},
	// 当uniapp从前台进入后台
	onHide: function() {
		console.log('App Hide')
	}
}
</script>

2. 页面生命周期

<script>
export default {
    onLoad(option) {}, // 监听页面加载,option为上个页面传递的数据,参数类型为Object
    onReady() {}, // 监听页面初次渲染完成
    onShow() {}, // 监听页面显示。页面每次出现在屏幕上都触发
    onHide() {}, // 监听页面隐藏
    onUnload() {}, // 监听页面卸载
    onResize() {}, // 监听窗口尺寸变化
    onPullDownRefresh() {},
    onReachBottom() {},
    onTabItemTap() {}
}
</script>
注意:
(1)不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a) 或 vm.$watch('a', newValue => this.myMethod())。因为箭头函数是和父级上下文绑定在一起的,this 不会是如你做预期的 Vue 实例,且 this.a 或 this.myMethod 也会是未定义的。
(2)建议使用 uni-app 的 onReady代替 vue 的 mounted。
(3)建议使用 uni-app 的 onLoad 代替 vue 的 created。

3. 页面路由配置及跳转

需要在pages.json里配置每个路由页面的路径及页面样式,类似小程序在app.json中配置页面路由一样。

{
	"pages": [ //pages数组中第一项表示应用启动页
		{
			"path": "pages/index/index",
			"style": {
				"navigationBarTitleText": "首页", // 导航标题
				"navigationBarBackgroundColor": "#F8F8F8", // 导航背景颜色
				"navigationBarTextStyle": "black", // 导航字体颜色
				"enablePullDownRefresh": true, // 下拉刷新
				"app-plus": { // App节点配置项
					"titleNView": {},
					"animationType": "fade-in",
					"animationDuration": 300
				}
			}
		}
	],
	"globalStyle": {
		"navigationBarTextStyle": "black", // 导航字体颜色
		"navigationBarTitleText": "uni-app", // 导航标题
		"navigationBarBackgroundColor": "#F8F8F8", // 导航背景颜色
		"backgroundColor": "#F8F8F8" // 页面背景颜色
	},
	"tabBar": {
		"color": "#333333",
		"borderStyle": "black",
		"backgroundColor": "#FFFFFF",
		"selectedColor": "#333333",
		"list": [{
				"pagePath": "pages/index/index",
				"iconPath": "",
				"selectedIconPath": "",
				"text": "首页"
			},
			{
				"pagePath": "pages/my/my",
				"iconPath": "",
				"selectedIconPath": "",
				"text": "我的"
			}
		]
	}
}
1、初始化
2、打开新页面
uni.navigateTo 、 <navigator open-type="navigate"/>
3、页面重定向
uni.redirectTo 、 <navigator open-type="redirectTo"/>
4、页面返回
uni.navigateBack  、<navigator open-type="navigateBack"/> 、用户按左上角返回按钮、安卓用户点击物理back按键
5、Tab 切换
uni.switchTab  、  <navigator open-type="switchTab"/>  、用户切换 Tab
6、重加载
uni.reLaunch  、<navigator open-type="reLaunch"/>

注意:
(1)navigateTo, redirectTo 只能打开非 tabBar 页面。
(2)switchTab 只能打开 tabBar 页面。
(3)reLaunch 可以打开任意页面。
(4)页面底部的 tabBar 由页面配置决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
(5)不能在 App.vue 里面进行页面跳转。

4. 页面布局

为支持跨平台,框架建议使用Flex布局
Flex 布局教程:语法篇
Flex 布局教程:实例篇

5. 字体图标

uni-app 支持使用字体图标,使用方式与普通 web 项目相同,需要注意以下几点:

  • 支持 base64 格式字体图标。
  • 支持网络路径字体图标。
  • 网络路径必须加协议头 https。
  • 从 http://www.iconfont.cn 上拷贝的代码,默认是没加协议头的。
 @font-face {
     font-family: test1-icon;
     src: url('~@/static/iconfont.ttf');
 }

6. 基础组件

  • 视图容器:view,scroll-view,swiper
  • 基础内容:icon,text,rich-text,progress
  • 表单组件:button,check-box,form,input,textarea,picker,radio,switch
  • 导航:navigator
  • 媒体组件:audio,camera,image,video
  • 地图:map
  • 画布:canvas
  • webview:web-view
  • 广告:ad
  • 开放能力组件:
  • App nvue 专用组件:list,recycle-list
  • 扩展组件:uni-ui

7. 应用配置

manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等。

在这里插入图片描述

三. 进阶知识点

1. 条件编译

条件编译是里用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。

  • API 的条件编译
// #ifdef  %PLATFORM%
平台特有的API实现
// #endif

说明:
以 #ifdef 或 #ifndef 加** %PLATFORM%** 开头,以 #endif 结尾。
%PLATFORM%APP-PLUSAPP-PLUS-NVUEH5MP-WEIXIN...
  • 组件的条件编译
<template>
	<view class="content">
		// #ifdef MP-WEIXIN
		<page-loading></page-loading>
		// #endif
	</view>
</template>
  • 样式的条件编译
<style lang="scss">
	/*  #ifdef MP-WEIXIN  */
	.wx-bg-login {
		background-color:#11ff11;
	}
	/*  #endif  */
</style>
  • pages.json 的条件编译
// #ifdef MP-WEIXIN
{
	"path": "pages/speech/speech",
	"style": {
		"navigationBarTitleText": "语音识别"
	}
}
// #endif
  • static 目录的条件编译
┌─static                
│  ├─mp-weixin
│  │  └─a.png     
│  └─b.png
├─main.js        
├─App.vue      
├─manifest.json 
└─pages.json     

2. vuex使用

import Vue from 'vue'
import Vuex from 'vuex'
import api from '@/api'

Vue.use(Vuex)

const store = new Vuex.Store({
	state: {
		language: uni.getStorageSync('language') || 0,
		isLogin: !!uni.getStorageSync('isLogin'),
		loginInfo: {},
		userInfo: {}
	},
	mutations: {
		// 语言信息
		SET_LANGUAGE: (state, value) => {
			state.language = value
		},
		// 用户登录
		SET_LOGIN: (state, value) => {
			state.isLogin = value
		},
		// 用户登录信息
		SET_LOGININFO: (state, value) => {
			state.loginInfo = value
		},
		// 用户信息
		SET_USERINFO: (state, value) => {
			state.userInfo = value
		}
	},
	actions: {
		// 设置语言信息
		SetLanguage({
			dispatch,
			commit
		}, value) {
			uni.setStorageSync('language', value);
			commit('SET_LANGUAGE', value);
			dispatch('SetLang', value);
		},
		// 用户登录
		Login({
			dispatch,
			commit
		}, data) {
			return new Promise((resolve, reject) => {
				api.login(data).then(response => {
					if (response.status === 1) {
						uni.setStorageSync('loginInfo', response.data);
						uni.setStorageSync('isLogin', true);
						dispatch('ParseLoginInfo');
					}
					resolve(response)
				}).catch(error => {
					reject(error)
				})
			})
		},
		// 获取用户信息
		GetUserInfo({
			dispatch,
			commit
		}) {
			return new Promise((resolve, reject) => {
				api.getUserInfo(this.state.loginInfo.mobile).then(response => {
					if (response.status === 1) {
						uni.setStorageSync('userInfo', response.data);
						dispatch('ParseUserInfo');
					}
					resolve(response)
				}).catch(error => {
					reject(error)
				})
			})
		},
		// 解析登录信息
		ParseLoginInfo({
			dispatch,
			commit
		}) {
			const loginInfo = uni.getStorageSync('loginInfo') || {};
			commit('SET_LOGININFO', loginInfo);
			commit('SET_LOGIN', Object.keys(loginInfo).length > 0);
			dispatch('ParseUserInfo');
		},
		// 解析用户信息
		ParseUserInfo({
			dispatch,
			commit
		}) {
			const userInfo = uni.getStorageSync('userInfo') || {};
			commit('SET_USERINFO', userInfo);
		},
		// 退出登录
		Logout({
			dispatch,
			commit
		}) {
			uni.clearStorageSync();
		}
	}
})
export default store

3. npm支持

uni-app支持使用npm安装第三方包。

4. 小程序组件支持

uni-app 支持在 App 和 小程序 中使用小程序自定义组件,从HBuilderX2.4.7起,H5端也可以运行微信小程序组件。

平台支持情况小程序组件存放目录
H5支持微信小程序组件(2.4.7+)wxcomponents
App(不含nvue支持微信小程序组件wxcomponents
微信小程序支持微信小程序组件wxcomponents
支付宝小程序支持支付宝小程序组件mycomponents
百度小程序支持百度小程序组件swancomponents
头条小程序支持头条小程序组件ttcomponents
QQ小程序支持QQ小程序组件wxcomponents
┌─wxcomponents                  微信小程序自定义组件存放目录
│   └──custom                   微信小程序自定义组件
│        ├─index.js
│        ├─index.wxml
│        ├─index.json
│        └─index.wxss
├─mycomponents                  支付宝小程序自定义组件存放目录
│   └──custom                   支付宝小程序自定义组件
│        ├─index.js
│        ├─index.axml
│        ├─index.json
│        └─index.wxss
├─swancomponents                百度小程序自定义组件存放目录
│   └──custom                   百度小程序自定义组件
│        ├─index.js
│        ├─index.swan
│        ├─index.json
│        └─index.wxss
├─pages
│  └─index
│        └─index.vue
│
├─static
├─main.js
├─App.vue
├─manifest.json
└─pages.json

在 pages.json 对应页面的 style -> usingComponents 引入组件:

{
    "pages": [
        {
            "path": "index/index",
            "style": {
                "usingComponents": {
                    // #ifdef APP-PLUS || MP-WEIXIN || MP-QQ
                     "custom": "/wxcomponents/custom/index"
                    // #endif
                    // #ifdef MP-BAIDU
                     "custom": "/swancomponents/custom/index"
                    // #endif
                    // #ifdef MP-ALIPAY
                     "custom": "/mycomponents/custom/index"
                    // #endif
                }
            }
        }
    ]
}

5. 使用nvue

uni-app在App端,支持vue页面和nvue页面混搭、互相跳转。也支持纯nvue项目。

四. 注意事项

1. data 属性

data 必须声明为返回一个初始数据对象的函数;否则页面关闭时,数据不会自动销毁,再次打开该页面时,会显示上次数据。

//正确用法,使用函数返回对象
data() {
    return {
        title: 'Hello'
    }
}

//错误写法,会导致再次打开页面时,显示上次数据
data: {
    title: 'Hello'
}

2. 全局变量

  • 公用模块封装
  • globalData
    小程序中有个globalData概念,可以在 App 上声明全局变量。 Vue 之前是没有这类概念的,但 uni-app 引入了globalData概念,并且在包括H5、App等平台都实现了。
    在 App.vue 可以定义 globalData ,也可以使用 API 读写这个值。
    globalData支持vue和nvue共享数据。
    globalData是一种比较简单的全局变量使用方式。
<script>  
    export default {  
        globalData: {  
            text: 'text'  
        },  
        onLaunch: function() {  
            console.log('App Launch')  
        },  
        onShow: function() {  
            console.log('App Show')  
        },  
        onHide: function() {  
            console.log('App Hide')  
        }  
    }  
</script>  
<style>  
    /*每个页面公共css */  
</style>  

js中操作globalData的方式如下:

赋值:getApp().globalData.text = ‘test’
取值:console.log(getApp().globalData.text)
如果需要把globalData的数据绑定到页面上,可在页面的onshow声明周期里进行变量重赋值。HBuilderX 2.0.3起,nvue页面在uni-app编译模式下,也支持onshow。

  • Vuex

3. Class 与 Style 绑定

  • class 支持的语法:
<view :class="{ active: isActive }">111</view>
<view class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }">222</view>
<view class="static" :class="[activeClass, errorClass]">333</view>
<view class="static" v-bind:class="[isActive ? activeClass : '', errorClass]">444</view>
<view class="static" v-bind:class="[{ active: isActive }, errorClass]">555</view>
  • style 支持的语法:
<view v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">666</view>
<view v-bind:style="[{ color: activeColor, fontSize: fontSize + 'px' }]">777</view>

非H5端不支持 Vue官方文档:Class 与 Style 绑定 中的 classObject 和 styleObject 语法。

<template>
    <view :class="[activeClass]" :style="[baseStyles,overridingStyles]"></view>
</template>

<script>
    export default {
        data() {
            return {
                activeClass: {
                    'active': true,
                    'text-danger': false
                },
                baseStyles: {
                    color: 'green',
                    fontSize: '30px'
                },
                overridingStyles: {
                    'font-weight': 'bold'
                }
            }
        }
    }
</script>

注意:以:style=""这样的方式设置px像素值,其值为实际像素,不会被编译器转换。

此外还可以用 computed 方法生成 class 或者 style 字符串,插入到页面中,举例说明:

<template>
    <!-- 支持 -->
    <view class="container" :class="computedClassStr"></view>
    <view class="container" :class="{active: isActive}"></view>

    <!-- 不支持 -->
    <view class="container" :class="computedClassObject"></view>
</template>
<script>
    export default {
        data () {
            return {
                isActive: true
            }
        },
        computed: {
            computedClassStr () {
                return this.isActive ? 'active' : ''
            },
            computedClassObject () {
                return { active: this.isActive }
            }
        }
    }
</script>

用在组件上

非H5端暂不支持在自定义组件上使用 Class 与 Style 绑定

4. 列表循环

在H5平台 使用 v-for 循环整数时和其他平台存在差异,

  • 如 v-for=“(item, index) in 10” 中,在H5平台 item 从 1 开始,其他平台 item 从 0 开始,可使用第二个参数 index 来保持一致。
  • 在非H5平台 循环对象时不支持第三个参数,如 v-for=“(value, name, index) in object” 中,index 参数是不支持的。

5. 事件处理器

// 常用事件映射表,左侧为 WEB 事件,右侧为 ``uni-app`` 对应事件
{
    click: 'tap',
    touchstart: 'touchstart',
    touchmove: 'touchmove',
    touchcancel: 'touchcancel',
    touchend: 'touchend',
    tap: 'tap',
    longtap: 'longtap', //推荐使用longpress代替
    input: 'input',
    change: 'change',
    submit: 'submit',
    blur: 'blur',
    focus: 'focus',
    reset: 'reset',
    confirm: 'confirm',
    scroll: 'scroll'
}
  • 为兼容各端,事件需使用 v-on 或 @ 的方式绑定,请勿使用小程序端的bind 和 catch 进行事件绑定。
  • 若需要禁止蒙版下的页面滚动,可使用 @touchmove.stop.prevent="moveHandle",moveHandle 可以用来处理 touchmove 的事件,也可以是一个空函数。
    -<view class="mask" @touchmove.stop.prevent="moveHandle"></view>
  1. v-html指令
    App端(vue页面V3编译模式)和H5端支持v-html,其他端不支持v-html。

跨端的富文本处理方案详见:https://ask.dcloud.net.cn/article/35772

五. 消息推送-UniPush

UniPush是DCloud联合个推公司推出的集成型统一推送服务,内建了苹果、华为、小米、OPPO、VIVO、魅族等手机厂商的系统级推送和个推等第三方推送。

uniPush推送开发指南

1. 推送平台开通

2. 模块权限配置

在这里插入图片描述

3. 厂商推送设置

在这里插入图片描述

4. 主要代码

// 初始化推送
initPush() {
	// #ifdef APP-PLUS
	let _self = this;
	// 点击状态栏消息
	plus.push.addEventListener('click', function(msg) {
		// 收到消息点击逻辑处理,跳转页面
	}, false);
		
	// receive事件
	plus.push.addEventListener('receive', function(msg) {
		_self.createLocalPushMsg(msg); //创建本地消息
	}, false);
	// #endif
},

//创建本地消息
createLocalPushMsg(msg) {
	if (msg.payload === 'LocalMSG') {
			return;
	}
	let options = {
		cover: false
	};
	plus.push.createMessage(msg.content, 'LocalMSG', options);
},

4. 获取clidentid

plus.push.getClientInfo().clientid

六. 开放生态

  1. uni-app插件市场,有数千款插件,支持前端组件、js sdk、页面模板、项目模板、原生插件等多种类型
  2. 兼容微信小程序 JS SDK,丰富的小程序生态内容可直接引入uni-app,并且在App通用
  3. 兼容微信小程序自定义组件,并且App通用
  4. 支持 mpvue 项目及组件,全端通用
  5. 支持 NPM 包管理系统
  6. 图表uCharts
  7. 丰富样式库ColorUI
  8. 官方UI组件库uni-ui
Logo

前往低代码交流专区

更多推荐