1-uni-app入门
(1)开发规范:
- 页面遵循vue单文件
- 组件标签靠近小程序规范
- 接口靠近小程序规范
- 事件处理靠近vue
1 页面配置
1.1 全局配置 globalStyle
在pages.josn文件中进行配置
"globalStyle": {
"navigationBarTextStyle": "black",//导航栏标题颜色 仅支持black white
"navigationBarTitleText": "uni-app11",// 默认标题内容 会被页面及的配置覆盖
"navigationBarBackgroundColor": "#ffaaff", //导航栏背景色
"backgroundColor": "#ff52f7",
"enablePullDownRefresh":true,
"backgroundTextStyle":"dark"//下拉loading的样式 仅支持dark 和 light
}
1.2 pages的配置
在pages.josn文件中进行配置,用于规定路径和页面基本信息
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"h5": {//h5的单独样式
"pullToRefresh": {
"color": "#007AFF"
}
}y
}
}, {
"path": "pages/message/message",
"style": {
"navigationBarTitleText": "消息",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#007AFF"
}
}
],
1.3 tabbar设置
在pages.josn文件中进行配置,用于设置下方导航
最多5个最少2个
"tabBar":{
"list":[//导航栏的列表
{
"pagePath":"pages/index/index",
"text":"首页",
"iconPath":"./static/logo.png",//未选中时展示的图标
"selectedIconPath":"./static/logo.png"//选中时展示的图标
},
{
"pagePath":"pages/message/message",
"text":"我的消息",
"iconPath":"./static/logo.png",//未选中时展示的图标
"selectedIconPath":"./static/logo.png"//选中时展示的图标
},
{
"pagePath":"pages/contact/contact",
"text":"联系我们",
"iconPath":"./static/logo.png",//未选中时展示的图标
"selectedIconPath":"./static/logo.png"//选中时展示的图标
}
],
"color":"#FFFFFF",//未选中的文字颜色
"selectedColor":"#4CD964",//选中后的文字颜色
"backgroundColor":"#333333",
"borderStyle":"black"//边框颜色 仅支持black white
// "position":"top"//仅支持微信小程序
}
1.4 condition配置
仅在开发期间生效,用于模拟直达页面的场景
"condition":{//启动模式
"current":0,
"list":[
{
"name":"详情",
"path":"pages/detail/detail",
"query":"id=80"//参数
}
]
}
2 uni-app的组件
2.1 text组件
相当于html的 span
<view class="">
<text>哈哈哈哈</text>
</view>
<view class="">
<text selectable>文字可选</text>
</view>
<view class="">
<text selectable space="ensp">文字 有 空格</text>
</view>
2.2 view组件
类似于html里面的div
<view class="">我是一个盒子</view>
<!-- hover-class指定点击的样式类 -->
<view class="box" hover-class="box-click">box</view>
<!-- hover-stop-propagation 阻止冒泡 -->
<view class="box2" hover-class="box2-click">
box2
<view class="box" hover-class="box-click" hover-stop-propagation :hover-start-time="2000">box1</view>
</view>
2.3 botton组件
按钮组件
<!-- botton组件 -->
<button type="default">按钮</button>
<!-- size 设置大小 -->
<button type="default" size="mini">按钮</button>
<!-- tyoe 设置样式类型 -->
<button type="primary" size="mini">按钮</button>
<!-- plain 按钮是否镂空-->
<button type="primary" size="mini" plain>按钮</button>
<!-- disable 是否禁用 -->
<button type="primary" size="mini" disabled>按钮</button>
<!-- loading 是否带loading图标 -->
<button type="default" size="mini" loading>按钮</button>
2.4 image组件
<!-- image 组件 -->
<image src="../../static/logo.png" mode=""></image>
<!-- mode 设置裁剪和缩放模式 -->
<image src="../../static/logo.png" mode="aspectFit"></image>
<image src="../../static/logo.png" mode="aspectFill"></image>
2.5 scroll-view组件
<template>
<view class="content">
<scroll-view scroll-x="true" class="scroll">
<view class="group">
<view class="item">111</view>
<view class="item">111</view>
<view class="item">111</view>
<view class="item">111</view>
<view class="item">111</view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
}
</script>
<style scoped>
.scroll{
box-sizing: border-box;
border:1px solid black;
height: 220rpx;
background-color: blanchedalmond;
white-space: nowrap;
}
.group > view{
width: 220rpx;
height: 220rpx;
background-color: aquamarine;
display: inline-block;
margin-right: 10rpx;
}
</style>
2.6 swiper组件
<swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000" class="swiper">
<swiper-item>
<view class="swiper-item">111</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">222</view>
</swiper-item>
</swiper>
3 uni-app中的样式
3.1 说明
- page{} === body{}
- 在uni-app中不可以使用 * 选择器
- uni-app支持class,id,element等选择器
- 可以使用 @import url(“./xxx/xxx”) 来引入外部样式
- 定义在App.vue中的样式为 全局样式 ,作用于每一个页面;定义于pages目录下的vue文件中的样式为 局部样式,只作用于对应的页面,并且会覆盖App.vue中的样式。
3.2 rpx
- 是响应式的px
- 以750rpx作为100%的基准
- 当屏幕改变的时候 会响应式的等比例改变
4 uniapp中vue语法格式
4.1 uni-app的模板语法
和vue.js一样
<view class="box1">{{defualtname}}</view>
<view class="">{{1+1}}</view>
4.2 v-for v-bind的使用
<image :src="defualtPic" mode="" @click="picChick()"></image>
<view class="" v-for="(item,index) in arr" :key="index">
<view class="">{{item.name}}</view>
<view class="">{{item.age}}</view>
</view>
<script>
export default {
data() {
return {
defualtPic:'../../static/logo.png',
arr: [
{
name: 'lihua1',
age: "18",
},
{
name: 'lihua2',
age: "19"
},
{
name: 'lihua3',
age: "15",
}
]
}
},
methods: {
picChick(){
uni.showModal({
content: 'hhhhh',
showCancel: false
});
}
}
}
</script>
4.3 v-if v-show的使用
v-if和v-show的区别:
- v-if:元素隐藏时,直接通过把
标签删除
来实现了隐藏效果。- v-show:元素隐藏时,只是增加了
display:none
的样式。
<template>
<view class="content">
<view v-if="usernameShow">{{username}}</view>
<view @click="usernameShow=!usernameShow">是否展示username</view>
</view>
</template>
<script>
export default {
data() {
return{
username:'用户名',
usernameShow:true
}
}
}
</script>
4.4 style绑定
<view class="box" :style="`background-color: cornflowerblue;`"></view>
实例:点击方块修改随机背景颜色
<template>
<view class="content">
<view class="box" :style="`background-color: ${bgColor};`" @click="changeBgColor"></view>
</view>
</template>
<script>
export default {
data() {
return{
bgColor:'cornflowerblue'
}
},
methods:{
changeBgColor(){
let color ='#' + String(Math.random()).substr(3,6)
this.bgColor = color
}
}
}
</script>
<style scoped>
.box{
width: 200rpx;
height: 200rpx;
border: 2rpx solid black;
}
</style>
4.5 class绑定
方法1
绑定字符串: :class=“boxClass”
<view class="box1" :class="boxClass" @click="changeClass"></view>
方法2
绑定对象::class=“{box2:state}”
三元表达式形式::class=" state?box:’ ’ "
<template>
<view class="content">
<view class="box1" :class="{box2:state}" @click="changeClass"></view>
</view>
</template>
<script>
export default {
data() {
return{
bgColor:'cornflowerblue',
state:false
}
},
methods:{
changeClass(){
this.state = !this.state
}
}
}
</script>
<style scoped>
.box1{
width: 200rpx;
height: 200rpx;
border: 2rpx solid black;
background-color: aquamarine;
}
.box2{
width: 200rpx;
height: 200rpx;
border: 2rpx solid black;
background-color: bisque;
border-radius: 20rpx;
}
</style>
实例:点击导航栏导航高亮显示
<template>
<view class="content">
<view class="nav">
<view class="item" v-for="(item,index) in navArr" :key="index" :class="{navActive:navIndex===index}" @click="changeNav(index)">{{item.title}}</view>
</view>
</view>
</template>
<script>
export default {
data() {
return{
navArr:[
{title:'首页'},
{title:'介绍'},
{title:'教程'},
{title:'组件'},
],
navIndex:0
}
},
methods:{
changeNav(index){
console.log(index)
this.navIndex = index
}
}
}
</script>
<style scoped>
.nav{
display: flex;
justify-content: space-between;
flex-wrap: nowrap;
}
.item{
width:25%;
background-color: antiquewhite;
padding: 15rpx 0;
text-align: center;
transition: all 0.3s;
}
.navActive{
background-color: cadetblue;
color: #fff;
}
</style>
4.6 computed的用法
<template>
<view class="content">
<input type="text" v-model="value" class="nav-content">
<view >标题:{{ value }}</view>
<view >修改后的标题:{{ newValue}}</view>
</view>
</template>
<script>
export default {
data() {
return{
value:''
}
},
computed:{
newValue(){
return '哈哈哈'+ this.value
}
}
}
</script>
9 uni-app的生命周期
9.1 应用的生命周期
定义在 App.vue 中
函数名 | 说明 |
---|---|
onLaunch (一次) | uni-app初始化完成时触发(全局只触发一次) |
onShow(多次) | 当uni-app启动 或者从后台进入前台显示 |
onReady(多次) | 当uni-app 从前台进入后台 |
onError(多次) | 当uni-app报错时触发 |
9.2 页面的生命周期
- 定义在页面中
- 注意: tabbar中的页面展现过一次之后就保留在内存中,在次切换tabbar页面,不会触发onLoad事件,只触发onShow事件
函数名 | 说明 |
---|---|
onLoad (一次) | 监听页面加载,其参数为上一个页面传递的数据,参数类型为Object(用于页面传参) |
onShow (多次) | 监听页面显示,页面每次出现在屏幕上的时候都会触发 |
onReady(一次) | 监听页面渲染完成 |
onHide(多次) | 监听页面隐藏 |
onUnload(多次) | 监听页面卸载 |
onResize(多次) | 监听页面窗口尺寸变化 |
onPullDownRefresh(多次) | 监听用户下拉的动作 一般用于下拉刷新 |
onReachBottom(多次) | 监听页面滚动到底部事件,一般用于上拉刷新 |
… | …见文档 |
onLoad(options) {
console.log("页面加载了",options)
},
onShow() {
console.log("页面显示了")
},
onReady() {
console.log("页面渲染完成")
},
onHide() {
console.log("页面隐藏")
},
10 页面刷新
10.1 下拉刷新的学习
(1)开启下拉刷新的两种方式
方式一:在pages.json里面配置
"path" : "pages/uni-style/uni-style",
"style" :
{
"navigationBarTitleText": "uni-css",
"enablePullDownRefresh": true,//开启下拉刷新
"h5":{
"pullToRefresh":{
"color":"#007AFF"
}
}
}
方式二:
调用=uni.startPullDownRefresh() 方法
<button type="default" size="mini" @click="pullDown">刷新</button>
methods: {
pullDown(){
uni.startPullDownRefresh()
}
}
(2)监听下拉刷新事件
使用生命周期函数 onPullDownRefresh()
使用 uni.stopPullDownRefresh() 关闭下拉刷新
onPullDownRefresh() {
console.log("触发下拉刷新")
this.list=["ui11","前端22","测试33","java44","大数据5"]
setTimeout(()=>{
uni.stopPullDownRefresh()//关闭下拉刷新
},1000)
},
10.2 上拉刷新(页面触底刷新)学习
(0)说明 可以配置页面触底距离底部的高度
在pages.json中配置 onReachBottomDistance
单位为px 默认50
"path" : "pages/list/list",
"style" :
{
"navigationBarTitleText": "列表",
"enablePullDownRefresh": true,
"onReachBottomDistance":200
}
(1)监听上拉刷新事件(页面触底事件)
使用生命周期函数 onReachBottom
<view class="box-item" v-for="(item,index) in list" :key="index">{{item}}</view>
<script>
export default {
data() {
return {
list:["ui","前端","测试","java","大数据"]
}
},
onReachBottom() {
console.log("页面触底了")
this.list=[...this.list,...["ui11","前端22","测试33","java44","大数据5"]]
},
}
</script>
12 网络请求-发送请求
12.1 uni.request()
使用 uni.request() 发送网络请求。
uni.request({
url:'https://www.baidu.com' ,//请求地址
method:"POST",
header:{ //请求头
"content-type":"appLication/x-wwww-form-urlencoded"
},
data:{
nameId:'18452'
},
success:res=>{
console.log(res)
this.imgArr=res.data.data
}
})
12.2 请求封装
request.js文件
const BASE_URL = "http://localhoat:9090" //后台ip和端口号
export const request = (option) =>{
return new Promise((resolve,reject)=>{
uni.request({
url:BASE_URL + option.url,
method:option.method || 'GET',
header: {token:uni.getStorageSync('User')?uni.getStorageSync('user').token:''},
data:option.data||{},
success:res=>{
const data = ras.data
if(data.code) === '401'){
uni.navigateTo({
url:'/pages/login/lohin'
})
}else if(data.code !== '200'){
uni.showToast({
icon:'error',
title:'操作错误'
})
}
resolve(data)
},
fail: error=>{
uni.showToast({
icon:'error',
title:'操作错误'
})
}
})
})
}
在main.js中引用
在.vue文件中使用
methods: {
getNews(){
this.$request({url:xxx,data:xxx}).then(res=>{
})
}
}
13 本地数据缓存
名称 | 作用 |
---|---|
uni.setStorage | 存储 |
uni.getStorage | 获取 |
uni.removeStorage | 删除 |
uni.setStorageSync | 存储数据–同步 |
uni.getStorageSync | 获取数据–同步 |
uni.removeStorageSync | 移除数据–同步 |
<button type="default" size='mini' @click="setStorage">存储数据</button>
<button type="default" size='mini' @click="getStorage">获取数据</button>
<button type="default" size='mini' @click="deleteStorage">移除数据</button>
<button type="default" size='mini' @click="setStorageSync">存储数据--同步</button>
<button type="default" size='mini' @click="getStorageSync">获取数据--同步</button>
<button type="default" size='mini' @click="deleteStorageSync">移除数据--同步</button>
setStorage(){
uni.setStorage({
key:'id',
data:80,
success() {
console.log('存储成功')
}
})
},
getStorage(){
uni.getStorage({
key:'id',
success(res) {
console.log("获取成功",res.data)
}
})
},
deleteStorage(){
uni.removeStorage({
key:'id',
success() {
console.log("移除成功")
}
})
},
setStorageSync(){
uni.setStorageSync('id',100)
},
getStorageSync(){
const a=uni.getStorageSync('id')
console.log(a)
},
deleteStorageSync(){
uni.removeStorageSync('id')
}
14 上传图片
使用 uni-chooseimage() 上传图片
<button type="default" size='mini' @click="setimg()">上传图片</button>
setimg(){
uni.chooseImage({
count:5,//在浏览器中不能限制
success:res=>{
this.imgarr=res.tempFilePaths
}
})
},
15 预览图片
使用uni.previewImage进行图片预览
<image :src="item" mode="" v-for="(item,index) in imgarr" :key=index @click="previewimg(item)"></image>
previewimg(item){
uni.previewImage({
current:item,
urls:this.imgarr,//图片列表
loop:true,//是否循环
indicator:'default',//可以取default-圆点 number-数字 none不显示 要写字符串类型的数据
// loop 和 indicator只在app中可见 在浏览器和小程序中都看不到
})
}
}
16 条件注释实现跨端兼容
使用 #ifdef‘、#endif来进行条件注释
(1)结构的条件注释
<!-- 结构的条件注释 -->
<!-- #ifdef H5 -->
<view class="">我希望只在h5中看见</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="">我希望只在微信小程序中看见</view>
<!-- #endif -->
(2) 函数中的条件注释
// 函数中的条件注释
onLoad() {
// #ifdef H5
console.log("我希望h5中打印");
// #endif
// #ifdef MP-WEIXIN
console.log("我希望微信小程序中打印");
// #endif
},
(3)样式的条件注释
/* 样式的条件注释 */
/* #ifdef H5 */
.box{
color: #2C405A;
}
/* #endif */
/* #ifdef MP-WEIXIN */
.box{
color: #4CD964;
}
/* #endif */
17 uni-app中的路由跳转
17.1 声明式页面跳转
使用组件navigator进行页面跳转
<!-- 导航跳转 -->
<navigator url="../detail/detail">跳转到详情页--有返回</navigator>
<!-- open-type="switchTab" 跳转到有tabbar的页面 -->
<navigator url="../message/message" open-type="switchTab">跳转到信息页</navigator>
<!-- open-type="redirect" 先关闭当前页面 在跳转到新的页面 没有返回的箭头了 -->
<navigator url="../detail/detail" open-type="redirect">跳转到详情页--没有返回</navigator>
17.2 编程式导航
<!-- 编程式导航 -->
<button type="default" size='mini' @click="godetail()">跳转到详情页面</button>
<button type="default" size='mini' @click="gomessage()">跳转到信息页面</button>
<button type="default" size='mini' @click="godetailandclosepage()">跳转到详情页面并关闭当前页面</button>
godetail(){
// 跳转到非tabbar
uni.navigateTo({
url:'../detail/detail'
})
},
gomessage(){
//跳转到tabbar
uni.switchTab({
url:'../message/message'
})
},
godetailandclosepage(){
// 跳转到非tabbar 并关闭当前页面
uni.redirectTo({
url:'../detail/detail'
})
}
返回1个路由
uni.navigateBack({ delta: 1})
返回2个路由
uni.navigateBack({ delta: 2})
17.3 跳转页面并传参
传
uni.navigateTo({
url: 'test?id=1&name=uniapp'
})
<navigator url="../detail/detail?id=80&age=19">跳转到详情页--有返回</navigator>
取
使用onload生命周期函数来取
onLoad(options) {
console.log(options)//{id: "80",age:'19'}
},
17.4 编程式路由跳转总结
路由跳转方法 | 说明 | 实例 | 特点 |
---|---|---|---|
uni.navigateTo(OBJECT) | 保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack 可以返回到原页面。 | uni.navigateTo({url: 'testid=1&name=uniapp'}); | 不可跳tabbar |
uni.redirectTo(OBJECT) | 关闭当前页面,跳转到应用内的某个页面。 | uni.redirectTo({url: 'test?id=1'}); | 不可跳tabbar |
uni.reLaunch(OBJECT) | 关闭所有页面,打开到应用内的某个页面。 | uni.reLaunch({url: 'test?id=1'}); | 可跳tabbar |
uni.switchTab(OBJECT) | 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。 | uni.switchTab({url:'/pages/index/index'}); | 可跳tabbar,不可携带参数 |
- navigateTo, redirectTo 只能打开非 tabBar 页面。 switchTab 只能打开 tabBar 页面。
- reLaunch 可以打开任意页面。 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
- 不能在 App.vue 里面进行页面跳转。
- H5端页面刷新之后页面栈会消失,此时navigateBack不能返回,如果一定要返回可以使用history.back()导航到浏览器的其他历史记录。
18 组件components
18.1 注册组件 - vue方式(1)
<!-- 组件 -->
<test></test>
//与method同级
components:{
test
}
18.2 注册组件 - easycom方式(2)
步骤1: 在主目录下创建components目录
步骤2: 创建组件
步骤三: 在页面中使用组件
18.3 组件的生命周期函数
v-if控制组件的创建和销毁
18.4 组件之间传值
18.3.1 父传子 props
传
<test :title="title"></test>
接收
export default {
name:"test",
data() {
return {
};
},
// 接收props方式1 简答接收
props: ['name', 'sex', 'age'],
// 接收props方式2 接收并预设数据类型
props: {
name: String,
sex: String,
age: Number
},
// 接收props方式3 接收并预设类型和必要性和默认值
props: {
name: { type: String, required: true },
sex: { type: String, required: true },
age: { type: Number, default: 99 },
array: { type: Array, default:()=>[1,2,3]},
array: { type: Object, default:()=>{name:'tom'}}
}
}
18.3.2 子传父 emit
主要是通过触发自定义事件
父
<test :title="title" @myEven="getnum" @click.native="xxxx"></test>
getnum(num){
console.log("子组件传来的值为",num)
}
子
<button type="button" @click="sendNum()">给父组件传值</button>
data() {
return {
num:3
};
},
methods:{
sendNum(){
this.$emit('myEven',this.num)
}
},
18.3.2 父子互相传值 .sync update:
:title.sync="title"
: 使用.sync
修饰,titie变为一个双向绑定 (响应式) 的变量,父子组件的改变互相影响。
父组件update:title
: 子组件使用update:
来修饰,用于向主组件传递修改值
<template>
<view class="content">
<pubTitle :title.sync="title"></pubTitle>
</view>
</template>
<script>
export default {
data() {
return{
title:'默认'
}
},
}
</script>
子组件
<template>
<view class="pubTitle">
<view class="title">文章的标题:{{title}}</view>
<button @click="changeTitle">修改标题</button>
</view>
</template>
<script>
export default {
name:"pubTitle",
data() {
return {
};
},
props:['title'],
methods:{
changeTitle(){
this.$emit("update:title",'修改后的标题')
}
}
}
</script>
18.3.3 兄弟组件传值
使用
uni.on
注册全局事件
使用uni.$emit
调用全局组件
组件b
<template>
<view>
这是b组件的数据{{num}}
</view>
</template>
<script>
export default {
name:"b",
data() {
return {
num:0
};
},
created() {
// 注册全局事件
uni.$on('updataNum',(num)=>{
this.num+=num
})
}
}
</script>
组件a
<button type="button" @click="changeNum()">修改b中的数据</button>
methods:{
changeNum(){
uni.$emit('updataNum',10)
}
}
}
21 uni-app全局变量的定义
22 vue项目中导入uni扩展组件
扩展1–反馈组件
uni.showToast({
title: '该活动已结束,期待您的下次参与。',
icon: 'none',
duration: 3000,
position: 'center'
});
uni.showLoading({ title: '加载中', mask: true })
uni.hideLoading();