一、什么是uni-app
官网介绍是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。
通俗地讲,uni-app是一个前端框架,开发者编写一套代码即可发布到各大主流平台,从而实现了程序跨平台使用。
二、学习uni-app
首先需要大家掌握Vue.js和小程序,因为uni-app是使用Vue.js开发的前端框架,可以说就是使用vue语法写小程序。
uni-app有丰富的生态环境,官方及第三方插件 较为丰富。
以下变简要介绍uni-app的基础知识——目录结构、页面结构、常用组件、生命周期等。
主要掌握的知识要素
①小程序文档与uni-app文档的差异化
基础知识--目录结构
┌─uniCloud 【云空间目录,阿里云为uniCloud-aliyun,腾讯云为uniCloud-tcb(详见uniCloud)】
│─components 【符合vue组件规范的uni-app组件目录】
│ └─comp-a.vue 【可复用的a组件】
├─utssdk 【存放uts文件】
├─pages 【存放项目页面】
│ ├─index
│ │ └─index.vue 【index页面】
│ └─list
│ └─list.vue 【list页面】
├─static 【存放静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此】
├─uni_modules 【存放[uni_module](/uni_modules)】
├─platforms 【存放各平台专用页面的目录,详见】
├─nativeplugins 【App原生语言插件 详见】
├─nativeResources 【App端原生资源目录】
│ ├─android 【Android原生资源目录 详见】
| └─ios 【iOS原生资源目录 详见】
├─hybrid 【App端存放本地html文件的目录,详见】
├─wxcomponents 【存放小程序组件的目录,详见】
├─unpackage 【非工程代码,一般存放运行或发行的编译结果】
├─AndroidManifest.xml 【Android原生应用清单文件 详见】
├─Info.plist 【iOS原生应用配置文件 详见】
├─main.js 【Vue初始化入口js文件】
├─App.vue 【入口组件,应用配置,用来配置App全局样式以及监听 应用生命周期】
├─manifest.json 【配置文件,一般在发布时使用,配置应用(APP)名称、appid、logo、版本、启动页面等打包信息,详见】
├─pages.json 【页面管理。配置页面路由、导航条、选项卡、页面样式等页面类信息,详见】
└─uni.scss 【这里是uni-app内置的常用样式变量】
1.uni-app运行机制
运行uni-app程序后,首先访问的页面就是pages.json文件,所有页面都在pages属性中,pages是一个对象数组,每一个对象表示一个页面,第一个对象就是运行后要显示的页面。
1.1 uni-app页面结构
uni-app的页面结构和Vue.js的页面结构一样,都是.vue页面,由template、script、style3个部分组成。
和Vue.js不同的是,HTML的一些标签不能用了,例如ul、li标签img标签、span标签、div标签等。uni-app有自己的组件。
1.2 解读pages.json文件
"globalStyle": {
"navigationBarTextStyle": "black", //设置页面导航标题的颜色(只能设置black或者white)
"navigationBarTitleText": "演示", //设置导航标题
"navigationBarBackgroundColor": "#F8F8F8", //设置导航背景
"backgroundColor": "#F8F8F8", //设置页面背景
"usingComponents":{
"collapse-tree-item":"/components/collapse-tree-item"
},
"renderingMode": "seperated", // 仅微信小程序,webrtc 无法正常时尝试强制关闭同层渲染
"pageOrientation": "portrait", //横屏配置,全局屏幕旋转设置(仅 APP/微信/QQ小程序),支持 auto / portrait / landscape
"rpxCalcMaxDeviceWidth": 960,
"rpxCalcBaseDeviceWidth": 375,
"rpxCalcIncludeWidth": 750
},
pages.json文件中的globalStyle中的属性为全局配置,所有页面都会继承,但是在实际开发中,每个页面都有自己的导航标题。
2.常用组件和响应式像素rpx
uni-app有自己的一套标签,又称作组件。
2.1view组件
view是视图容器,类似于HTML中的div标签,和div相比,view有其独特的属性,例如设置按下去的样式属性、组织冒泡的属性等。
hover-class属性:设置按下去的样式。代码如下:
<template>
<view class="main" hover-class="mainActive">
按下去的样式属性
</view>
</template>
<style>
.mainActive{
color:#fff;
}
</style>
2.2 text组件
text组件类似于HTML中的span标签,其重要属性有selectable、space。
selectable属性:表示文本是否可选,默认值是false,在手机中长安文本是不能选中的,设置为true后,代表可以选中文本。
space属性:代表可以使用连续空格,有3个值。
2.3 rich-text组件
富文本,详情看官网rich-text。渲染有两种方式:数组类型和字符串 。
<script>
export default {
data() {
return {
strings: '<div style="text-align:center;"><img src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/[email protected]"/></div>'
}
}
}
</script>
官网Tips
- nodes 不推荐使用 String 类型,性能会有所下降。
- rich-text 组件内屏蔽所有节点的事件。所以如果内容中有链接、图片需要点击,则不能使用rich-text,此时可在uni-app插件市场搜索parse插件使用。app-vue的rich-text组件支持链接图片点击。
- attrs 属性不支持 id ,支持 class 。
- name 属性大小写不敏感。
- 如果使用了不受信任的HTML节点,该节点及其所有子节点将会被移除。
- 非 App 平台 img 标签仅支持网络图片。
- 如果在自定义组件中使用 rich-text 组件,那么仅自定义组件的 css 样式对 rich-text 中的 class 生效。
- 使用
itemclick
时,如果发生节点嵌套,外层a标签
优先级高。
2.4 image组件
其作用是展示图片,可代替img标签,详解见媒体组件--image。
-
image
组件默认宽度 320px、高度 240px;app-nvue平台,暂时默认为屏幕宽度、高度 240px;添加mode="widthFix"属性,清除默认样式,图片本身多大就显示多大。
-
src
仅支持相对路径、绝对路径,支持 base64 码; -
页面结构复杂,css样式太多的情况,使用 image 可能导致样式生效较慢,出现 “闪一下” 的情况,此时设置
image{will-change: transform}
,可优化此问题。
2.5icon组件
<template>
<view>
<view class="" v-for="(value,index) in icons" :key="index">
<icon :type="value" size="26"></icon>
<text>{{value}}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
icons:['success'],
};
},
onLoad() {
// #ifdef APP-PLUS|| MP-WEIXIN
this.icons = ['success', 'success_no_circle', 'info', 'warn', 'waiting', 'cancel', 'download', 'search','clear']
// #endif
// #ifdef MP-ALIPAY
this.icons = ['info', 'warn', 'waiting', 'cancel', 'download', 'search', 'clear', 'success', 'success_no_circle', 'loading']
// #endif
// #ifdef MP-BAIDU
this.icons = ['success', 'info', 'warn', 'waiting', 'success_no_circle', 'clear', 'search', 'personal', 'setting', 'top', 'close', 'cancel', 'download', 'checkboxSelected', 'radioSelected', 'radioUnselect']
// #endif
}
}
</script>
2.6 navigate导航组件
2.6 form组件
<!-- 表单提交 -->
<form @submit="onSubmit">
<view class="row">
姓名:<input type="text" placeholder="姓名" name="uname">
</view>
<view class="row">
电话:<input type="text" placeholder="电话" name="phone">
</view>
<view class="row">
<radio-group name="gender">
<radio value="男" checked>男</radio>
<radio value="女">女</radio>
</radio-group>
</view>
<view class="row">
<picker @change="bindPickerChange" :value="index" :range="array" name="fruit">
<view class="uni-input">{{array[index]}}</view>
</picker>
</view>
<view>
<button form-type="submit">提交信息</button>
<button form-type="reset">重置表单</button>
</view>
</form>
export default {
data() {
return {
title: 'Hello',
obj:null,
message:{
uname:'',
phone:''
},
array:['橘子','橙子','苹果'],
index:1,
}
},
onLoad() {
},
methods: {
onSubmit(e){
// console.log(e.detail.value);
this.obj = e.detail.value;
// 重新覆盖选择器的值
this.obj.fruit = this.array[this.index]
console.log(this.obj);
},
bindPickerChange(e){
// 选择器选中的值用对应下标表示
this.index = e.detail.value;
console.log(this.array[this.index],e.detail.value);
}
}
}
2.7 响应式像素rpx
- 若设计稿宽度为 750px,元素 A 在设计稿上的宽度为 100px,那么元素 A 在
uni-app
里面的宽度应该设为:750 * 100 / 750
,结果为:100rpx。 - 若设计稿宽度为 640px,元素 A 在设计稿上的宽度为 100px,那么元素 A 在
uni-app
里面的宽度应该设为:750 * 100 / 640
,结果为:117rpx。 - 若设计稿宽度为 375px,元素 B 在设计稿上的宽度为 200px,那么元素 B 在
uni-app
里面的宽度应该设为:750 * 200 / 375
,结果为:400rpx。
想要宽度占满全屏,可以设width:750rpx;
了解更多,打开官方文档css语法。
3.vue语法
3.1 v-cloak指令
v-clock原理:由于快速刷新页面或者网速原因,导致Vue.js没有生效,在生效之前,只要是添加了v-cloak指令的元素,都会隐藏(样式设置),当Vue.js加载完毕,所做的第一件事就是将页面中的v-cloak指令删掉,所以数据又可以正常显示了。
<!-- 在根节点使用v-cloak -->
<view class="app" v-cloak>
{{msg}}张三
</view>
/* 属性选择器,只要使用了v-cloak属性的元素,下面的样式都生效 */
[v-cloak]{
display: none;
}
3.2 v-text指令
作用:渲染data中的属性值。
data中的属性值有三种渲染方式:插值表达式和v-text指令,v-html指令。
<!-- 第一种渲染方法 -->
<view class="">{{msg}}</view>
<!-- 第二种渲染方法 msg='富文本'-->
<view class="" v-text="msg"></view>
3.3 v-html指令
作用:渲染富文本。
<!-- 第三种渲染方法 当msg='<view>富文本</view>'-->
<view class="" v-html="msg"></view>
插值表达式、v-text、v-html的区别和相同点。
相同点:都可以渲染M层中的数据。
不同点:(1)插值表达式和v-text不能渲染富文本。
(2)v-text和v-html在视图中不能继续添加文本内容,而插值表达式可以继续添加文本。<view class="" v-html="msg">此文本不会显示出来</view>。也就是说,v-text和v-html渲染的数据会覆盖原标签中的内容。
3.4 v-once指令(h5,小程序不支持)
作用:只渲染元素和组件一次。随后的重新渲染,元素/组件及所有的子节点被视为静态内容跳过。
<view class="" v-once>只渲染一次的{{msg}}</view>
3.5 v-bind指令
作用:元素的属性绑定。v-bind可以简写成 “ : ”。当元素中的属性使用了v-bind指令时,后面的值就是变量,Vue会到M层中找到这个变量,若找到了就渲染内容,若找不到就会报错。
<imag :src="'/static/logo'+item+'.png'" mode="" v-for="item in [1,2,3]"></image>
<imag v-bind:src="'/static/logo'+item+'.png'" mode="" v-for="item in [1,2,3]"></image>
3.5 v-on指令
元素事件的绑定。v-on指令可以简写成“ @ ”。
3.6 v-model指令
双向数据绑定指令。v-model只能运用到表单元素,只有表单元素是用户可以操作的。
双向数据绑定的概念如下:
(1)数据层(M层)发生变化会影响到视图层(V层)改变。
(2)视图层(V层)发生变化会影响到数据层(M层)改变。
v-model修饰符:
"v-model.number" ,数字修饰符,表示用户只能输入数字。
"v-model.trim" ,对于输入的内容自动去掉首尾空格。
"v-model.lazy" ,表示内容发生变化,并且在失去焦点时触发。
<view class="">
<view class="">标题:{{title}}</view>
<input type="text" v-model="title">
</view>
3.7 class绑定和style绑定
</template>
<view>
<view :style="'color:#fff'">绑定style方法1</view>
<view :style="{color:'#fff',font-size:30rpx,height:height_my+'px'}">绑定style方法2</view>
<view :style="{color:colorname}" @click="clickColor">绑定style方法3</view>
</view>
</template>
<script>
export default {
data() {
return {
colorname:'#fff',
height_my:300,
}
},
methods:{
clickColor(){
//点击切换成随机色
let color = "#'+String(Math.random()).substr(3,6);
this.colorname = color;
}
}
}
</script>
<template>
<view>
<view class="static" :class="isActive?'active':''">单个类名</view>
<!-- 对象语法 -->
<view class="static" :class="{active: isActive}">方式1</view>
<view class="static" :class="{ isActive?'active':''}">方式2</view>
<!-- 数组语法 -->
<view class="static" :class="[errorClass,activeColor]">方式1</view>
<view class="static" :class="[ isActive?'active':'',errorClass]">方式2</view>
<view class="static" :class="[{active: isActive},errorClass]">方式3</view>
</view>
</template>
<script>
export default {
data() {
return {
isActive: true,
errorClass: 'static',
activeColor:"active",
}
}
}
</script>
<style>
.static{
color: #2C405A;
}
.active{
background-color: #007AFF;
}
</style>
3.8 过滤器filters(小程序不支持)
作用:用于数据输出之前的处理。例如:将后台返回的时间戳格式转为日期格式等。
- 过滤器是一个方法,其第一个参数是固定的,表示要处理的变量,且必须有return 属性。
- 过滤器使用的竖线又称为管道符,竖线后面就是过滤器的名字。
①私有过滤器
<view class="">
<!-- " | "竖线又称为管道符, toFixed 是过滤器的名字-->
{{num | toFixed}}
</view>
<view class="">
<!-- 过滤器调用时传入两个参数,即是3,'$' ,所以过滤器需要定义两个形参接收-->
{{num3 | toFixed3(3,'$')}}
</view>
<view class="">
<!-- 使用全局过滤器并传递参数-->
{{19 | globalToFixed(3)}}
</view>
</view>
</template>
<script>
export default {
data() {
return {
// 1、在data中声明数据
num:10,
num3:30
}
},
filters:{
toFixed(val){
return val.toFixed(3);
},
toFixed3(val,param1,param2){ //第一个参数是不变的,所以两个形参是从第二个参数开始的
return param2 + val.toFixed(param1);
}
},
②全局过滤器
全局过滤器是在main.js中定义的,使用Vue.filter方法创建,第一个参数是过滤器名字,其调用方法和私有过滤器的调用方法相同。
// 全局过滤器
// globalToFixed 过滤器名字
// val 过滤器控制的元素
// data 调用过滤器时传递的参数
Vue.filter('globalToFixed',function(val,data){
return val.toFixed(data);
});
3.9 侦听器 watch
作用:用于侦听data中数据的变化,只要data中数据发生改变,就会触发watch侦听属性。
- 侦听属性的方法不能随意命名,方法名就是侦听的变量名。
- 侦听属性没有返回值。
- 一个侦听属性只能侦听一个变量。
<template>
<view>
<input type="text" v-model="word">
</view>
</template>
<script>
export default {
data() {
return {
word: 'word'
}
},
watch: {
// 使用watch来响应数据的变化
word(newVal, oldVal) {
console.log('最新值是:'+newVal,"原来的值是:"+ oldVal);
}
},
}
</script>
官方解说--Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch
。然而,通常更好的做法是使用计算属性而不是命令式的 watch
回调。
3.10 计算属性computed
- 计算属性就是通过其他数据算出一个新数据,例如一组数字的求和、求平均数等都可以使用计算属性。
- 计算属性声明时是一个方法,并且必须有return返回值。
- 计算属性调用时不能是方法调用,而是普通变量的调用,所以直接使用{{方法名}}。
- 可以直接调用其他计算属性,作为值使用。
- 同一函数定义为一个方法又定义成一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。
<template>
<view>
<!-- 3、调用计算属性 -->
<view class="">
{{getSum}}
</view>
<view class="">
{{getAvg}}
</view>
</view>
</template>
<script>
export default {
data() {
return {
// 1、在data中声明数据
num1:85,
num2:95
}
},
computed:{
// 2、在computed属性中创建计算属性
getSum(){
return this.num1 + this.num2;
},
// 直接调用其他计算属性
getAvg(){
return this.getSum / 2;
}
}
}
</script>
三、uni-app中引入iconfont字体图标使用教程
1、在iconfont网站添加一个字体图标项目,然后下载本地
2、解压下载的文件,然后找到后缀名为.ttf,.woff,.off2这三个文件添加到你的应用程序静态目录static下。将iconfont.css文件放到common文件下,并修改那三个文件的路径。
3、在App.vue文件下全局引入 iconfont.css文件。
4、在模板中引用类名使用,.iconfont是必带。