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>