uni-app开发微信小程序系列之--框架基础

4,578 阅读6分钟

上一节: uni-app开发微信小程序系列之--初体验

本节主要涉及以下内容:

  • MVC&MVVM
  • 项目结构与文件类型
  • 全局标题与页面标题
  • 全局样式与页面样式
  • App的生命周期
  • 页面的生命周期
  • 数据绑定与事件
  • 条件渲染与列表渲染
  • 跨端兼容&条件编译

MVC & MVVM

MVC

  • M: model, 模型层, 数据的增删改查
  • V: view, 视图层, 前端页面(html/javascript/html)
  • C: controller, 控制层, 业务处理

MVVM

  • M, model, 单页面的静态数据
  • V, view, 视图即html
  • VM, ViewModel, 核心调度者, 用户或程序修改数据后, 数据双向同步至model层和view层

项目结构与文件类型

通常一个uni-app项目的目录结构如下:

├── components          # 自定义组件目录 
├── pages               # 小程序页面目录 
│  ├── index       
│  │  └── index.vue
├── static              # 静态资源
│  ├── logo.png   
├── unpackage           # 打包目录 
│  ├── dist             
│  │  └── build         # 编译后生成的代码存放目录
│  │  └── dev           # 本地测试运行时生成的代码存放目录
│  │    └── .sourcemap
│  │    └── mp-weixin   # 微信小程序上运行的文件
│  │        └── common
│  │        └── pages
│  │        └── static
│  │        └── app.js
│  │        └── app.json
│  │        └── app.wxss
│  │        └── project.config.json
│  │        └── sitemap.json
│  │    └── app-alipay  # 支付宝小程序运行的文件
│  │    └── app-plus    # 手机端运行的文件
│  │    └── h5          # h5端运行的文件
├── App.vue             # 可以称之为全局view, 其中的style样式会影响全局(即全局样式, 通用的全局样式可考虑放在App.vue的style标签内)
├── main.js             # 项目入口文件
├── manifest.json       # 项目配置文件(主要用于发布,运行和调试)
├── pages.json          # 页面相关配置(详细可查阅: https://uniapp.dcloud.io/collocation/pages)
├── uni.scss            # uni-app内置的常用样式变量(采用scss预处理)

全局标题与页面标题

pages.json内容可能如下:

{
	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
		{
			"path": "pages/index/index",
			"style": {
				"navigationBarTitleText": "uni-app"
			}
		}
    ],
	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "uni-app",
		"navigationBarBackgroundColor": "#F8F8F8",
		"backgroundColor": "#F8F8F8"
	},
	"condition" : { //模式配置,仅开发期间生效
		"current": 0, //当前激活的模式(list 的索引项)
		"list": [
			{
				"name": "", //模式名称
				"path": "", //启动页面,必选
				"query": "" //启动参数,在页面的onLoad函数里面得到
			}
		]
	}
}

其中,通过设置globalStyle.navigationBarTitleText可以设置全局标题, 通过pages列表项中某一项的style.navigationBarTitleText可以设置当前页面的标题. 此项若没有配置的话, 则使用全局标题

全局样式与页面样式

小程序的全局样式, 可以考虑在根目录下App.vue的style中添加全局样式.

页面的样式, 可以在每个页面的定义文件, 如index.vue文件的style标题中添加局部样式

需要注意的是, 页面样式是在页面样式代码加载完成之后生效的, 在此之前, 是使用全局样式.

App的生命周期

uni-app 支持如下应用生命周期函数(uni-app生命周期详细介绍):

  • onLaunch, 当uni-app 初始化完成时触发(全局只触发一次)
  • onShow, 当 uni-app 启动,或从后台进入前台显示
  • onHide, 当 uni-app 从前台进入后台
  • onError, 当 uni-app 报错时触发
  • onUniNViewMessage, 对 nvue 页面发送的数据进行监听,可参考 nvue 向 vue 通讯

hello示例工程中App.vue文件中, 有相关示例代码, 在本地运行后, 可以尝试看相关效果.

<script>
	export default {
		onLaunch: function() {
			console.log('App Launch')
		},
		onShow: function() {
			console.log('App Show')
		},
		onHide: function() {
			console.log('App Hide')
		}
	}
</script>

<style>
	/*每个页面公共css */
</style>

页面生命周期

页面生命周期函数相比于应用生命周期函数要多很多, 详细可查阅官方文档

这里我们尝试在page/index/index.vue中添加以下代码, 看下运行的效果:

<template>
	<view class="content">
		<image class="logo" src="/static/logo.png"></image>
		<view class="text-area">
			<text class="title">{{title}}</text>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: 'Hello James Zhang'
			}
		},
		onShow() {
			console.log('页面显示!')
		},
		onHide() {
			console.log('页面隐藏')
		},
		onLoad() {
			console.log('页面加载完成')
		},
		methods: {

		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.logo {
		height: 200rpx;
		width: 200rpx;
		margin-top: 200rpx;
		margin-left: auto;
		margin-right: auto;
		margin-bottom: 50rpx;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>

运行后, 可以看到打印信息如下:

其他的页面生命周期函数大家可以尝试运行下, 这些也会有后面的章节中会使用到.

数据绑定与事件

数据绑定

数据绑定部分, 有vue使用经验的同学, 应该很熟悉, 和vue的使用方式基本一致.

  • 模板表达式, {{title}}
  • 属性绑定, v-bind:propsName="value"或者简写为:propsName="value"

事件处理器

uni-app 几乎全支持 Vue官方文档:事件处理器.

这里我们添加一新的页面"events", 并添加以下代码到"events.vue"文件中.

<template>
	<view>
		hello
		<input type="text" :value="title" 
		style="background-color: #C0C0C0;height: 100upx"
		@input="change" 
		@blur="blur" 
		@focus="focus"
		@confirm="confirm"
		@tap="tap"
		@longpress="longpress"
		/>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: ''
			}
		},
		methods: {
			change(event){
				this.title = event.target.value
			},
			focus(){
				console.log("input focus")
			},
			blur(){
				console.log('input blur')
			},
			confirm(){
				console.log('confirm')
			},
			tap(){
				console.log('click')
			},
			longpress(){
				console.log('long press')
			}
		}
	}
</script>

<style>

</style>

运行下, 并操作鼠标触发相关事件, 可以看到右侧打印出相关信息出来.

其他更多事件处理, 请参考下官方文档, 在后面的章节中, 我们也会用到大部分的事件.

条件渲染与列表渲染

条件渲染

条件渲染基本上和vue中的v-if是一致的.

<view v-if="isShow">you can see me</view>
<view v-else>can not see me!</view>

<!-- 也可使用三元表达式 -->
<view v-if="sex === 1 ? 'man': 'woman"></view>

列表渲染

uni-app完整支持vue列表渲染

<template>
    <view>
        <!-- array 中 item 的某个 property -->
        <view v-for="(item,index) in objectArray" :key="item.id">
            {{index +':'+ item.name}}
        </view>
        <!-- item 本身是一个唯一的字符串或者数字时,可以使用 item 本身 -->
        <view v-for="(item,index) in stringArray" :key="item">
            {{index +':'+ item}}
        </view>
    </view>
</template>

跨端兼容&条件编译

跨端兼容

uni-app 已将常用的组件、JS API 封装到框架中,开发者按照 uni-app 规范开发即可保证多平台兼容,大部分业务均可直接满足。

但每个平台有自己的一些特性,因此会存在一些无法跨平台的情况。

  • 大量写 if else,会造成代码执行性能低下和管理混乱。
  • 编译到不同的工程后二次修改,会让后续升级变的很麻烦。

在 C 语言中,通过 #ifdef、#ifndef 的方式,为 windows、mac 等不同 os 编译不同的代码。 uni-app 参考这个思路,为 uni-app 提供了条件编译手段,在一个工程里优雅的完成了平台个性化实现。

条件编译

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

写法:以 #ifdef 或 #ifndef 加 %PLATFORM% 开头,以 #endif 结尾。

  • #ifdef:if defined 仅在某平台存在
  • #ifndef:if not defined 除了某平台均存在
  • %PLATFORM%:平台名称

支持的文件

  • .vue
  • .js
  • .css
  • pages.json
  • 各预编译语言文件,如:.scss、.less、.stylus、.ts、.pug

注意: 条件编译是利用注释实现的,在不同语法里注释写法不一样,js使用 // 注释、css 使用 /* 注释 */、vue/nvue 模板里使用 ;

API 的条件编译

例如, 以下代码只会在app中出现

在app和h5中同时出现

下一节: uni-app开发微信小程序系列之--样式与flex布局