uni-app框架的学习与使用


前言

uni-app是一个使用 Vue.js 开发跨平台应用的前端框架,使用hbuilder X可以快速将一套代码打包至最多7个平台。对于个人开发者,或者创业公司来说就是开发神器,省去了很多开发成本。下面就给大家介绍一下怎么快速上手uni-app。


一、uni-app简介及目录结构

uni-app简介

     uni-app是用来制作一个跨平台应用的,实现了一套代码,同时运行到多个平台,所以,在开始之前,我们一定要知道uni-app是如何打包到多个平台的。uni-app跨平台都是开发者工具来完成编译的,建议大家使用官方的开发者工具,对于一些配置项非常方便,可以省去很多麻烦。
     uni-app对百分之90的样式是完全跨平台的,对于一些特殊的,因为每个平台要求不一样,所以我们要使用条件编译来做适配,另外对于一些第三方授权登录或者支付功能每个平台也有所不同。这里我们注意要使用条件编译,重要点是一定要注意每个平台对组件或接口的兼容性。另外,需要注意的是uni-app中对vue语法的兼容性

快速上手

uni-app支持通过 可视化界面、vue-cli命令行 两种方式快速创建项目。
1、可视化界面

下载HBuilderX工具、新建项目即可

2、vue-cli

npm install -g @vue/cli

vue create -p dcloudio/uni-preset-vue my-project

uni-app目录

|——common 公共文件(如 js,css)
|——components 组件库
|——pages 业务页面文件存放的目录
|   |——index
|      | index.vue index页面
|——static 存放应用引用静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
|——main.js Vue初始化入口文件
|——App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
|——manifest.json 配置应用名称、appid, logo, 版本等打包信息
|——page.json 配置页面路由、导航条、选项卡等页面类信息

二、使用uni-app

了解生命周期

onReady:页面初次渲染完成时触发 ,然后触发vue 的 mounted
onLoad:页面加载时触发,可以用来在页面之间传参,具体的一些处理会在以后的文章详细介绍。
onShow:页面显示时触发,当应用启动或从后台进入前台时触发。感觉相当于vue的 created
onHide:页面隐藏时触发,当应用从前台进入后台时触发。
onUnload:页面卸载时触发
onBackPress:页面返回时触发
onPullDownRefresh:用户下拉时触发,在pages.json中的页面的style中添加enablePullDownRefresh,刷新完uni.stopPullDownRefresh停止
onReachBottom:页面上拉触底时触发

组件/标签的变化

  • div 改成 view

  • span、font 改成 text

  • a 改成 navigator

  • img 改成 image

  • input还在,但type属性改成了confirmtype

  • form、button、checkbox、radio、label、textarea、canvas、video 这些还在。

  • select改成 picker

  • iframe 改成 web-view

  • ul、li没有了,都用view替代

  • audio不再推荐使用,改成api方式,背景音频api文档

    其实老的HTML标签也可以在uni-app里使用,uni-app编译器会在编译时把老标签转为新标签,比如把div编译成view。但不推荐这种用法,调试H5端时容易混乱。
    除了改动外,新增了一批手机端常用的新组件

  • scroll-view 可区域滚动视图容器

  • swiper 可滑动区域视图容器

  • icon 图标

  • rich-text富文本(不可执行js,但可渲染各种文字格式和图片)

  • progress 进度条

  • slider 滑块指示器

  • switch 开关选择器

  • camera 相机

  • live-player 直播

  • map 地图

  • cover-view 可覆盖原生组件的视图容器

除了内置组件,还有很多开源的扩展组件,把常用操作都进行封装,DCloud建立了插件市场收录这些扩展组件,详见插件市场

css的变化

标准的css基本都是支持的。

1、选择器有2个变化:*选择器不支持;元素选择器里没有body,改为了page。微信小程序即是如此。

2、单位方面,px无法动态适应不同宽度的屏幕,rem无法用于nvue/weex。如果想使用根据屏幕宽度自适应的单位,推荐使用rpx,全端支持。

3、uni-app推荐使用flex布局,并默认就是flex布局,这个布局思路和传统流式布局有点区别。但flex的有趣在于,不管是什么技术都支持这种排版,web、小程序/快应用、weex/rn、原生的iOS、Android开发,全都支持flex。它是通吃所有端的新一代布局方案。相关教程请自行百度学习。

4、uni-app的vue文件里支持所有web排版方式,不管是流式还是flex。但nvue里,只支持flex,因为它在app端是使用原生排版引擎渲染的。

注意: 背景图和字体文件尽量不要大于40k。会影响性能。如果非要大于40k,需放到服务器侧远程引用或base64后引入,不能放到本地作为独立文件引用。在小程序里,其实小于40k的文件在css里也无法引用,uni-app编译器在编译时自动做了处理,把小于40k的文件编译为base64方式了。

路由跳转

uni-app 有两种页面路由跳转方式:使用navigator组件跳转、调用API跳转。

尺寸单位

rem 默认根字体大小为 屏幕宽度/20(微信小程序、字节跳动小程序、App、H5)

vh viewpoint height,视窗高度,1vh等于视窗高度的1%

vw viewpoint width,视窗宽度,1vw等于视窗宽度的1%

rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。小程序开发以 iPhone6 作为视觉稿的标准,在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。

rpx转px:

var px = rpx / 750 * wx.getSystemInfoSync().windowWidth;

px转rpx:

var rpx = px * 750 / wx.getSystemInfoSync().windowWidth;

page.json基本配置

"pages": [ //pages数组中第一项表示应用启动页
   "path" : "pages/mine/mine",
            "style" : {
					"app-plus":{
					//顶部导航栏消失
						"titleNView":false
					}
			}
        },
		{
		    "path" : "pages/class/class",
		    "style" : {
				"app-plus":{
				//导航栏设置
					"titleNView":{
						//导航栏控件的背景颜色
						"backgroundColor":"#fff",
						//原生导航栏上的搜索框样式 
						"searchInput":{
							//非输入状态下文本的对齐方式 center|right|left
							"align":"left",
							//提示文本
							"placeholder":"智能积木 越野四驱车",
							//提示文本的颜色
							"backgroundColor":"#f7f7f7",
							//是否可输入类型: Boolean 
							"disabled":true,
							//输入框的圆角半径
							"borderRadius":"5px",
							//是否自动获取焦点 类型: Boolean 
							"autoFocus":true,
						},
						//标题栏上的自定义按钮 类型: Array 
						"buttons":[
							{	
								//按钮上文字使用的字体文件路径 
								"fontSrc":"/static/fonts/iconfont.ttf",
								//按钮在标题栏上的显示位置 left | right
								"float":"right",
								//标题栏控件的标题文字超出显示区域时处理方式
								//\ue67a 字符
								"text":"\ue67a",
								//按钮上的文字颜色
								"color":"#858585",
								//按下状态按钮文字颜色 
								"colorPressed":"",
								//按钮样式。运行环境中内置按钮样式直接使用,
								//内置样式忽略fontSrc和text属性。 
								"type":"直接显示各种按钮随便选",
								//按钮上文字的粗细 
								"fontWeight":"bold",
							}
						]
					}
				}
			}
		}
	],
	"globalStyle": {
		//导航栏背景颜色 
		"backgroundColor":"#000000",
		//APP与H5为#F7F7F7,小程序平台请参考相应小程序文档
		"navigationBarBackgroundColor":"#000000",
		//导航栏标题颜色及状态栏前景颜色,仅支持 black/white
		"navigationBarTextStyle": "black",
		//导航栏标题文字内容
		"navigationBarTitleText": "内容",
		//导航栏透明设置。支持 always 一直透明 / auto 滑动自适应 / none 不透明
		"transparentTitle":"支付宝小程序、H5、APP"
		"backgroundColor": "#F8F8F8"
	},
//底部导航栏
"tabBar":{
		"color":"#aaa",//当前字体颜色
		"selectedColor":"f46d01",//点击激活的字体颜色
		"backgroundColor":"#fff",//背景颜色
		"list":[
			{
				"text":"首页",//字体
				"iconPath":"static/tab/index.png",//当前图片的颜色
				"selectedIconPath":"static/tab/index-on.png",//选中图片的颜色
				"pagePath":"pages/index/index"//路径
			},
			{
				"text":"购物车",
				"iconPath":"static/tab/shop.png",
				"selectedIconPath":"static/tab/shop-on.png",
				"pagePath":"pages/car/car"
			},
			{
				"text":"我的",
				"iconPath":"static/tab/mine.png",
				"selectedIconPath":"static/tab/mine-on.png",
				"pagePath":"pages/mine/mine"
			}
		]
	}

三、uni-app引入echarts

uni-app引入echarts页面未显示问题暂未解决,各位如有解决方法可以留言。
先记一次踩坑demo
1、安装echarts

npm install echarts mpvue-echarts --save

2、将下载下来的三个包从node_modules拷贝到根目录
在这里插入图片描述
3、在线定制echarts,以减小包体积,避免超出最大限制
替换最新版的mpvue-echart下面的echarts.vue
4、在pages/index/index.vue引用

import * as echarts from '../../echarts/echarts.min.js'
import * as chinaJson from '../../echarts/map/json/china.json'; 
import mpvueEcharts from '../../mpvue-echarts/src/echarts.vue'

5、一定要给map父容器设置宽高,否则地图不会显示,虽然我设置了也没有显示。
6、代码实现

<template>
	<view>
		<view class="wrap">
			<mpvue-echarts id="main" ref="mapChart" :echarts="echarts" @onInit="renderMap" />
		</view>
		<view>123</view>
	</view>
</template>

<script>
	import * as echarts from 'echarts'; /*echarts.min.js为在线定制*/
	import * as chinaJson from '../../echarts/map/json/china.json'; /*echart.min.js为在线定制*/
	import mpvueEcharts from 'mpvue-echarts';


	export default {
		data() {
			return {
				echarts,
				data: [{
						name: "南海诸岛",
						value: this.randomValue()
					},
					{
						name: '北京',
						value: this.randomValue()
					},
					{
						name: '天津',
						value: this.randomValue()
					},
					{
						name: '上海',
						value: this.randomValue()
					},
					{
						name: '重庆',
						value: this.randomValue()
					},
					{
						name: '河北',
						value: this.randomValue()
					},
					{
						name: '河南',
						value: this.randomValue()
					},
					{
						name: '云南',
						value: this.randomValue()
					},
					{
						name: '辽宁',
						value: this.randomValue()
					},
					{
						name: '黑龙江',
						value: this.randomValue()
					},
					{
						name: '湖南',
						value: this.randomValue()
					},
					{
						name: '安徽',
						value: this.randomValue()
					},
					{
						name: '山东',
						value: this.randomValue()
					},
					{
						name: '新疆',
						value: this.randomValue()
					},
					{
						name: '江苏',
						value: this.randomValue()
					},
					{
						name: '浙江',
						value: this.randomValue()
					},
					{
						name: '江西',
						value: this.randomValue()
					},
					{
						name: '湖北',
						value: this.randomValue()
					},
					{
						name: '广西',
						value: this.randomValue()
					},
					{
						name: '甘肃',
						value: this.randomValue()
					},
					{
						name: '山西',
						value: this.randomValue()
					},
					{
						name: '内蒙古',
						value: this.randomValue()
					},
					{
						name: '陕西',
						value: this.randomValue()
					},
					{
						name: '吉林',
						value: this.randomValue()
					},
					{
						name: '福建',
						value: this.randomValue()
					},
					{
						name: '贵州',
						value: this.randomValue()
					},
					{
						name: '广东',
						value: 20
					},
					{
						name: '青海',
						value: this.randomValue()
					},
					{
						name: '西藏',
						value: 0
					},
					{
						name: '四川',
						value: this.randomValue()
					},
					{
						name: '宁夏',
						value: this.randomValue()
					},
					{
						name: '海南',
						value: this.randomValue()
					},
					{
						name: '台湾',
						value: this.randomValue()
					},
					{
						name: '香港',
						value: this.randomValue()
					},
					{
						name: '澳门',
						value: this.randomValue()
					}
				]
			};
		},
		components: {
			mpvueEcharts
		},
		onLoad() {

		},
		methods: {
			randomValue() {
				return Math.round(Math.random() * 25);
			},
			renderMap(e) {
				const that = this;
				var mydata = that.data;
				let {
					canvas,
					width,
					height
				} = e;
				width = width - 20;
				echarts.setCanvasCreator(() => canvas);
				const chart = echarts.init(canvas, null, {
					width: width,
					height: height
				})
				echarts.registerMap('china', chinaJson);
				canvas.setChart(chart)
				var optionMap = {
					title: {
						text: '门店分布图',
						x: 'center'
					},
					tooltip: {
						trigger: 'item',
						formatter: '{b}:{c}家店'
					},
					//左侧小导航图标
					visualMap: {
						min: 0,
						max: 25,
						left: 'left',
						top: 'bottom',
						// orient:'horizontal',
						// text: ['高', '低'], //取值范围的文字
						inRange: {
							color: ['#fff8ed','#f2b95b'] //取值范围的颜色
						},
						show: true, //图注
						pieces: [ //自定义『分段式视觉映射组件(visualMapPiecewise)』的每一段的范围,以及每一段的文字,以及每一段的特别的样式
							{
								min: 0,
								max: 5,
								label: '0~5家'
							},
							{
								min: 5,
								max: 10,
								label: '5~10家'
							},
							{
								min: 10,
								max: 15,
								label: '10~15家'
							},
							{
								min: 15,
								max: 20,
								label: '15~20家'
							},
							{
								min: 20,
								max: 25,
								label: '20~25家'
							},
						],
						hoverLink: true,
						textStyle: {
							fontSize: 8
						},
					},
					geo: {
						map: 'china',
						roam: false, //不开启缩放和平移
						zoom: 1.2,//视角缩放比例
						label: {
							normal: {
								show: false,
								fontSize: 8,
								color: 'rgba(0, 0, 0, 0.5)' //文字颜色
							}
						},
						itemStyle: {
							normal: {
								borderColor: 'rgba(0, 0, 0, 0.2)' //省份边框颜色
							},
							emphasis: {
								areaColor: '#F3B329', //鼠标选择区域颜色
								shadowOffsetX: 0,
								shadowOffsetY: 0,
								shadowBlur: 20,
								borderWidth: 0,
								shadowColor: 'rgba(0, 0, 0, 0.2)' //选择后的边框阴影颜色
							}
						}
					},
					//配置属性
					series: [
						{
							type: 'map',
							geoIndex: 0,
							animation: false,
							data: mydata,
						}
					]
				};
				//初始化echarts实例
				chart.setOption(optionMap);
				this.$refs.mapChart.setChart(chart);
			}
		}
	};
</script>

<style scoped lang="scss">
	.wrap {
		width: 600rpx;
		height: 600rpx;
		border: 1rpx solid #ddd;
	}
</style>

总结

总体来说,uni-app门槛很低,基本有个开发基础的就可以实现。目前使用uni-app写小demo适配三端还是很nice的,但是接入地图还未实现,用插件市场的地图插件也还是不报错不显示,有待后续调试。。。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值