Uni-App是一个使用Vue.js开发所欲前端应用的框架,开发者编写一套代码,可发布到ios、Android、H5、以及各种小程序(微信/支付宝/百度头条/QQ/钉钉)等多个平台。
即使不跨端,uni-app同时也是更好的小程序开发框架。
具有vue和微信小程序的开发经验,可快速上手uni-app
学会uni-app之后,即可开发出ios、Android、H5、以及各种小程序的应用,不需要再去学习开发其他应用的框架,减少了开发成本。
安装编辑器HBuilderX进行开发
安装微信者开发者工具
利用HbuilderX初始化项目
pages.json:uni-app全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar等
manifest.json:应用的配置文件,用于指定应用的名称、图标、权限等
App.vue:根组件,所有页面都是在App.vue下进行切换的,是页面入口文件,可以调用应用的生命周期函数
main.js:项目入口文件,主要作用是初始化vue实例并使用需要的插件
uni.scss:为了方便整体控制应用的风格。比如按钮颜色、边框风格、uni.scss文件里预置了一批SCSS变量预置。
unpackage:打包目录,在这里有各个平台的打包文件
pages:所有的页面存放目录
static:静态资源目录,例如图片
components:组件存放目录
为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app约定了如下开发规范:
通过globalStyle进行全局配置
uniapp中官网globalStyle的配置
创建页面
在项目的pages下创建文件
在pages.json配置跳转路径
官网介绍
标签栏组件
tabBar官网介绍
在项目下的page.json中配置tabBar(标签栏)
用于直达某个页面,仅开发时期有效
官网启动模式配置介绍
在pages.json中配置启动模式,重启微信开发者工具可直接打开配置的页面
如下图,在微信开发者中可直接打开详情页面
在pages.json中配置如下:
官网介绍
空格的显示space
<template>
<view>
<view class="">
<text space="emsp">Hello World(中文字符空格一半大小)text>
view>
<view class="">
<text space="ensp">Hello World(中文字符空格大小)text>
view>
<view class="">
<text space="nbsp" style="font-size: 12px;">Hello World(根据字体设置的空格大小)text>
view>
view>
template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
script>
<style>
style>
view相当于html中的div,独占一行
一个页面必须要有一个view包裹所有的组件的根元素,
官网介绍
在编写view的hover-class所属的class样式要写在自身的class样式之后,防止hover-class设置的样式不起作用
<template>
<view>
<view hover-class="red" class="box" :hover-start-time="1000" :hover-stay-time="3000">
我是一个盒子
view>
view>
template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
script>
<style>
.box{
width:100px;
height: 100px;
background: #007AFF;
}
.red{
background: red;
}
style>
否阻止本节点的祖先节点出现点击态
<template>
<view class="box2" hover-class="red" hover-stay-time="5000">
<view class="box" hover-stop-propagation hover-class="box-active" hover-stay-time="5000">我是盒子里的盒子view>
view>
template>
<script>
export default {
data() {
return {};
},
methods: {}
};
script>
<style>
.box {
width: 100px;
height: 100px;
background: green;
}
.box2 {
width: 200px;
height: 200px;
background: #007aff;
}
.red {
background: red;
}
.box-active{
background: pink;
}
style>
官网介绍
<template>
<view>
<button type="default">白色按钮button>
<button type="primary">原始按钮button>
<button type="warn">红色按钮button>
<button type="default" size="mini">小按钮button>
<button type="primary" plain="true">背景色透明的按钮button>
<button type="default" disabled="true">禁用的按钮button>
<button type="default" loading="true">加载图标的按钮button>
view>
template>
<script>
export default {
data() {
return {};
},
methods: {}
};
script>
<style>
style>
官网介绍
页面样式介绍
在文件目录下的static下创建目录css,然后创建a.css
view{
color: green;
}
在index.vue中使用@import引用a.css
<template>
<view>
<view>
样式的学习
view>
<view class="box">
测试文字
view>
view>
template>
<script>
export default {
data() {
return {};
},
methods: {}
};
script>
<style>
/* 引用外部样式文件 */
@import url("/static/css/a.css");
.box{
width: 375rpx;
height: 375rpx;
background: #0000FF;
font-size: 30rpx;
color: #FFF;
}
style>
@font-face {
font-family: test1-icon;
src: url('~@/static/iconfont.ttf');
}
字体图标
官网介绍scss
1.在页面中需要定义数据,和我们之前的vue一模一样,直接在data中定义数据即可
export default {
data () {
return {
msg: 'hello-uni'
}
}
}
2.在需要使用的地方,使用{{}}(插值表达式获取数据)
<template>
<view>
<view>数据绑定的学习view>
<view>{{hello}}view>
<view>{{1+'你好'}}view>
<view>{{1+2}}view>
<view>{{flag?'我是真的':'我是假的'}}view>
view>
template>
<script>
export default {
/* data函数 */
data() {
return {
hello:'hello uniapp',//1.定义数据
flag:true
}
},
methods: {
}
}
script>
<style>
style>
例如绑定图片的属性src
<template>
<view>
<image v-bind:src="imgUrl" mode="aspectFill">image>
view>
template>
<script>
export default {
data() {
return {
imgUrl:'http://destiny001.gitee.io/image/monkey_02.jpg'
}
},
methods: {
}
}
script>
<style>
style>
<template>
<view>
<image :src="imgUrl" mode="aspectFill">image>
view>
template>
<script>
export default {
data() {
return {
imgUrl:'http://destiny001.gitee.io/image/monkey_02.jpg'
}
},
methods: {
}
}
script>
<style>
style>
<template>
<view>
<view class="" v-for="(item, index) in arr" :key="item.id">
当前项的索引为{{index}},数组的下标是{{ item.id }},用户名:{{ item.name }},年龄:{{ item.age }}view>
view>
template>
<script>
export default {
data() {
return {
arr: [
{ id: 1, name: '刘能', age: 29 },
{ id: 2, name: '赵四', age: 39 },
{ id: 3, name: '宋小宝', age: 49 },
{ id: 4, name: '小沈阳', age: 59 },
]
};
},
methods: {}
};
script>
<style>style>
<template>
<view>
<button type="primary" v-on:click="clickHandle">按钮button>
<button type="warn" @click="clickHandle">按钮2button>
view>
template>
<script>
export default {
data() {
return {};
},
methods: {
// 1.在methods中定义事件函数
clickHandle() {
console.log("点击我了");
}
}
};
script>
<style>style>
<template>
<view>
<button type="primary" v-on:click="clickHandle">按钮button>
<button type="warn" @click="clickHandle">按钮2button>
view>
template>
<script>
export default {
data() {
return {};
},
methods: {
// 1.在methods中定义事件函数
clickHandle(e) {
console.log("点击我了",e);
}
}
};
script>
<style>style>
<template>
<view>
<button type="primary" v-on:click="clickHandle">按钮button>
<button type="warn" @click="clickHandle(20)">按钮2button>
view>
template>
<script>
export default {
data() {
return {};
},
methods: {
// 1.在methods中定义事件函数
clickHandle(e) {
console.log("点击我了",e);
}
}
};
script>
<style>style>
点击按钮,控制台输出如下:
<template>
<view>
<button type="primary" v-on:click="clickHandle">按钮button>
<button type="warn" @click="clickHandle(20,$event)">按钮2button>
view>
template>
<script>
export default {
data() {
return {};
},
methods: {
// 1.在methods中定义事件函数
/* 使用num,接收形参 */
clickHandle(num,e) {
console.log("点击我了",num,e);
}
}
};
script>
<style>style>
uniapp官网地址
生命周期的概念:一个对象从创建、运行、销毁的整个过程被成为生命周期。
生命周期函数:在生命周期中每个阶段会伴随着每一个函数的触发,这些函数被称为生命周期函数
应用生命周期:官网介绍
应用生命周期函数:onLaunch,只触发一次
页面生命周期:官网介绍
onPullDownRefresh:监听用户下拉动作,一般用于下拉刷新
官网示例
需要在 pages.json 里,找到的当前页面的pages节点,并在 style 选项中开启 enablePullDownRefresh。
通过调用uni.startPullDownRefresh方法来开启下拉刷新
<template>
<view>
<view>这是列表页view>
<view v-for="(item,index) in arr" :key="index">
{{item}}
view>
view>
template>
<script>
export default {
data() {
return {
arr: ['前端','java','ui','大数据']
}
},
onPullDownRefresh() {
console.log("触发了下拉刷新");
this.arr=['前端','java','ui','大数据'];
//刷新完成,停止刷新
uni.stopPullDownRefresh();
},
methods: {
}
}
script>
<style>
style>
<template>
<view>
<view>这是列表页view>
<view v-for="(item, index) in arr" :key="index">{{ item }}view>
view>
template>
<script>
export default {
data() {
return {
arr: ['前端', 'java', 'ui', '大数据']
};
},
onPullDownRefresh() {
console.log('触发了下拉刷新');
//延迟刷新,(两秒刷新数据)
setTimeout(() => {
this.arr = ['前端', 'java', 'ui', '大数据'];
//刷新完成,停止刷新
uni.stopPullDownRefresh();
}, 2000);
},
methods: {}
};
script>
<style>style>
点击按钮,刷新数据
<template>
<view>
<view>这是列表页view>
<view v-for="(item, index) in arr" :key="index">{{ item }}view>
<button @click="pullDown">下拉刷新button>
view>
template>
<script>
export default {
data() {
return {
arr: []
};
},
onPullDownRefresh() {
console.log('触发了下拉刷新');
//延迟刷新,(两秒刷新数据)
setTimeout(() => {
this.arr = ['前端', 'java', 'ui', '大数据'];
//刷新完成,停止刷新
uni.stopPullDownRefresh();
}, 2000);
},
methods: {
pullDown(){
uni.startPullDownRefresh({
});
}
}
};
script>
<style>style>
onReachBottom
页面滚动到底部的事件(不是scroll-view滚到底),常用于上拉加载下一页数据。如使用scroll-view导致页面级没有滚动,则触底事件不会被触发
<template>
<view>
<view>这是列表页view>
<view v-for="(item, index) in arr" :key="index" class="box">{{ item }}view>
view>
template>
<script>
export default {
data() {
return {
arr : ['前端', 'java', 'ui', '大数据','前端', 'java', 'ui', '大数据']
}
},
//上拉加载数据
onReachBottom(){
console.log("页面触底了");
},
methods: {
}
};
script>
<style>
.box{
height: 100px;
line-height: 100px;
}
style>
uni.request
将数据存储在本地
官网介绍
示例:
<template>
<view class="content">
<button type="primary" @click="setStorage">存储数据button>
<button type="primary" @click="getStorage">获取数据button>
<button type="default" @click="removeStore">移除数据button>
view>
template>
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
//数据缓存
setStorage(){
uni.setStorage({
key:'id',//缓存中的指定的 key
data:20,//缓存的数据
success() {//缓存成功的处理
console.log("存储成功!")
}
})
},
getStorage(){
uni.getStorage({
key:"id",
success(res) {
console.log("获取成功!");
console.log(res.data);
}
});
},
removeStore(){
uni.removeStorage({
key:'id',
success() {
console.log("移除数据成功!");
}
});
}
}
}
script>
<style>
style>
页面显示
点击存储数据按钮,点击浏览器控制台下的Application下的Storage下的Local Storage查看存储的数据
点击移除数据按钮,浏览器下的缓存数据被清空
<template>
<view>
<button type="primary" @click="chooseImage">上传图片button>
<image :src="item" v-for="(item,index) in imageArr" @click="previewImage(item)">image>
view>
template>
<script>
export default {
data() {
return {
imageArr:[]//存储上传图片
}
},
methods: {
chooseImage(){
//上传图片
uni.chooseImage({
count:5,//选择图片的张数
success: (res) => {
this.imageArr=res.tempFilePaths;
console.log(res);
}
});
},
//图片预览
previewImage(item){
uni.previewImage({
urls:this.imageArr,//预览的图片链接
count:5,
current:item,
loop:true,//循环预览
indicator:"default"//图片指示器样式
});
}
}
}
script>
<style>
style>
页面样式
点击上图图片按钮,页面显示图片
点击图片,实现预览,左右滑动预览图片
官网介绍
官网介绍
条件编译
在vue后缀的文件中进行条件编译
<template>
<view>
<view>我希望只在h5页面中看见view>
<view>我希望只在微信小程序页面中看见view>
view>
template>
<script>
export default {
onLoad() {
// #ifdef H5
console.log("在h5控制台打印");
//#endif
// #ifdef MP-WEIXIN
console.log("在微信小程序控制台打印");
//#endif
},
data() {
return {
}
},
methods: {
}
}
script>
1、使用navigator
2、编程式导航跳转
路由与页面的跳转
在uni-app中,可以通过创建一个后缀名为vue的文件,即创建一个组件成功,其他组件可以将该组件通过import的方式导入,再通过components进行注册即可
<template>
<view>
这是一个自定义组件
view>
template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
script>
<style>
style>
import login from '@/components/login/login'
3.注册组件
components:{login},
完整页面代码
<template>
<view class="content">
<image class="logo" src="/static/logo.png">image>
<view class="text-area">
<text class="title">{{title}}text>
view>
<login>login>
view>
template>
<script>
//1.导入login组件
import login from '@/components/login/login'
export default {
data() {
return {
title: 'Hello'
}
},
/* 2.注册组件
注册组件名为login,显示名称也为login。
所以可以简写为login
*/
components:{login},
onLoad() {
},
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>
组件的生命周期函数
beforeCreate | 在实例初始化之后被调用。详见 | |
---|---|---|
created | 在实例创建完成后被立即调用。详见 | |
beforeMount | 在挂载开始之前被调用。详见 | |
mounted | 挂载到实例上去之后调用。详见 注意:此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用$nextTick Vue官方文档 |
|
beforeUpdate | 数据更新时调用,发生在虚拟 DOM 打补丁之前。详见 | 仅H5平台支持 |
updated | 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。详见 | 仅H5平台支持 |
beforeDestroy | 实例销毁之前调用。在这一步,实例仍然完全可用。详见 | |
destroyed | Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。详见 |
<template>
<view id="myview" v-if="true">
这是一个自定义组件
view>
template>
<script>
export default {
data() {
return {
num: 3
}
},
//实例初始化之后被调用
beforeCreate() {
console.log('实例已经开始初始化了!');
console.log(this.num);
},
//实例创建完成之后调用
//一般用来初始化数据
created() {
console.log('created', this.num);
},
//挂载开始之前调用
beforeMount() {
console.log('beforeMount',document.getElementById('myview'));
},
//挂载到实例之后调用
//操作dom结构
mounted() {
console.log('mounted',document.getElementById('myview'));
},
methods: {
}
}
script>
<style>
style>
<template>
<view class="content">
<image class="logo" src="/static/logo.png">image>
<view class="text-area">
<text class="title">{{ title }}text>
view>
<login v-if="flag">login>
<button type="primary" @click="toggle">动态显示组件button>
view>
template>
<script>
//1.导入login组件
import login from '@/components/login/login';
export default {
data() {
return {
title: 'Hello',
flag:false
};
},
/* 2.注册组件
注册组件名为login,显示名称也为login。
所以可以简写为login
*/
components: { login },
onLoad() {},
methods: {
toggle(){
this.flag=!this.flag;//取反,动态显示组件
}
}
};
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>
通过props来接受外界传递到组件内部的值
<template>
<view>
<login v-bind:title="title">login>
<login :title="title">login>
view>
template>
<script>
import login from '@/components/login.vue';
export default {
components:{login},
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
}
}
script>
<style>
style>
<template>
<view>
这是一个自定义组件,父组件传递的值{{title}}
view>
template>
<script>
export default {
//通过props接收父组件传递过来的值
props:['title'],
data() {
return {
};
}
}
script>
<style>
style>
页面测试
h5页面地址
http://localhost:8080/#/pages/index/index
页面显示如下:
通过$emit触发事件进行传递参数
在子组件中,首先需要使用$emit方法,该方法接收2个参数,第一个参数是事件的名称,自己随意定义。第二个参数是需要传递的数据
在父组件中,程序会查找刚才在子组件中注册的事件名
子组件代码:
<template>
<view>
这是一个自定义组件,父组件传递的值{{title}}
<button type="primary" @click="getNum">给父组件传值button>
view>
template>
<script>
export default {
//通过props接收父组件传递过来的值
props:['title'],
data() {
return {
num:3
};
},
methods:{
getNum(){
console.log("给父组件传值");
/* this.$emit(父组件中的事件名称,传递的参数) */
this.$emit('myEven',this.num);
}
}
}
script>
<style>
style>
父组件的代码
父组件定义自定义事件并接收参数
<template>
<view>
<login :title="title" @myEven="getNum">login>
<text>这是子组件传递过来的值:{{num}}text>
view>
template>
<script>
import login from '@/components/login.vue';
export default {
components:{login},
data() {
return {
title: 'Hello',
num:0
}
},
onLoad() {
},
methods: {
getNum(num){
console.log(num);
this.num=num;
}
}
}
script>
<style>
style>
页面测试
测试地址:http://localhost:8080/#/pages/index/index
页面通讯
子组件testA,代码如下:
<template>
<view>
这是a组件:<button @click="addNum">修改b组件的数据button>
view>
template>
<script>
export default {
data() {
return {
};
},
methods:{
addNum(){
uni.$emit('updateNum',1);
}
}
}
script>
<style>
style>
子组件testB,代码如下:
<template>
<view>
这是b组件的数据:{{num}}
view>
template>
<script>
export default {
data() {
return {
num:0
};
},
//组件实例化创建时
created() {
// 监听全局的自定义事件
uni.$on('updateNum',num=>{
this.num+=num;
});
}
}
script>
<style>
style>
父组件,代码如下:
<template>
<view>
<testA>testA>
<testB>testB>
view>
template>
<script>
import testA from'@/components/a.vue';
import testB from '@/components/b.vue';
export default {
components:{testA,testB},
data() {
return {
}
},
methods: {
}
}
script>
<style>
style>
页面测试地址:
http://localhost:8080/
页面样式
点击修改b组件的数据的按钮,这是b组件的数据:1,以后每次点击,数据都发生改变
官网介绍