好程序员 web前端培训分享之 uni-app学习笔记 uni-app详解 , uni-app (一套代码 ,多端发行 )如果你会使用 Vue那咱们继续吧 !
uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、H5、以及各种小程序等多个平台。
多端泛滥 iOS、Android、H5、以及各种小程序多套平台,多套文档,加大开发维护成本
1、跨平台
一套代码多端发行,而不失优雅(条件编译,保留不同平台 独有特色功能方法调用)
<!-- # ifdef MP - WEIXIN -->
< view > 只会编译小程序 < /view> <!-- endif --> <!-- # ifdef XX - XXX -->
< view > 只会编译XXX < /view> <!-- endif -->
2、通用技术栈,学习成本低
Vue的语法,微信小程序Api,内嵌mpvue可以直接迁移,如果你会Vue可以直接入门
3、生态丰富
支持npm下载第三方模块,支持小程序自定义组件,SDK,兼容mpvue组件,支持原生混合编码
可以下载两个进行配置 ,测试微信小程序与支付宝小程序同步实现
编译工具下载
HBuilderX
微信小程序开发
IDE
支付宝小程序
IDE
推荐使用 HBuildX 进行开发
创建目录
00001. 打开HBuilderX
00002. 左上角创建项目
00003. 选择uni-app项目
00004. 下面是提供几个Demo项目,可以创建学习
00005. 项目名称能不能大写,创建项目
运行项目
一、找到创建项目uni里面的项目目录
二、找到 manifest.js文件输入
1、里面有所有平台配置文件
需要不通平台测试,需要分别配置不同平台
2、选择微信小程序配置
配置小程序AppID
点击最上面工具栏选择运行
选择运行到小程序模拟器
选择微信小程序开发工具
第一次配置小程序开发者工具,需要打开服务
三、打开微信小程序开发左上角小
安全设置,将服务端口开启。||工具 -> 设置 -> 安全设置,将服务端口开启。
四、选择HBuild停止服务,重新运行自动打开编辑工具
.nvue 是对weex的增强。如果你不开发App,那么你不太需要nvue。
发布测试
选择HBuild最上面工具栏,点击发布进行打包,根据命令行提示在点击微信开发者工具发布
注意不要直接修改微信开发工具目录,以HBuild开发目录为主
目录介绍
与小程序配置相似
pages //存放分页目录 static //存放应用引用静态资源 main.js //入口文件 mainfest.json //跨平台所有配置项文件 pages.json //全局配置文件,类似App.json uni.scss //全局scss文件,在分页任何位置,注意 style 需要设置 scss App.vue // 应用配置,用来配置App全局样式以及监听
统一参照uni-app官方文档
添加分页
00001. 鼠标移动pages右键
00002. 右键新建页面,注意检查pages.json文件会自动写入pages项,文件路径
pages.json文件 style 为分页配置项,类似小程序 page.json
修改 pages.json
知识点: uni-app分页配置在style里面写,globalStyle写全部样式配置,在一个配置文件,这里是有区别原生小程序开发,具体参照uni-app文档进行配置 pages.json
配置项
配置项
navigationBarBackgroundColor HexColor //# 000000 导航栏背景颜色 navigationBarTextStyle String white //导航栏标题颜色,仅支持 black/white navigationBarTitleText String //导航栏标题文字内容 navigationStyle String default //导航栏样式,仅支持 default/custom。 backgroundColor HexColor //#ffffff 下拉窗口的背景色 微信小程序
全局配置
globalStyle : {
//...全局配置 }
局部配置 参照 pages.style 内容
> pages数组,决定谁排在前面
修改pages导致文件查找失败,检查无误,重启编辑工具
pages : [
{
path : "xxx/xxx/xxx" ,
style : {
//...局部配置 }
}]
系统自带底部tabBar栏配置
如果配置tabBar需要保证abBar第一个路由,配置在第一个pages的第一个
"tabBar": {
"color" : "#7A7E83" ,
"selectedColor" : "#3cc51f" ,
"borderStyle" : "black" ,
"backgroundColor" : "#ffffff" ,
"list" : [{
"pagePath" : "pages/component/index" ,
"iconPath" : "static/image/icon_component.png" ,
"selectedIconPath" : "static/image/icon_component_HL.png" ,
"text" : "组件"
}, {
"pagePath" : "pages/API/index" ,
"iconPath" : "static/image/icon_API.png" ,
"selectedIconPath" : "static/image/icon_API_HL.png" ,
"text" : "接口"
}]
}
优先尝试根据Vue使用操作,例如使用 v-for 替换wx:for
表达式
仅此而已,有Vue使用相似,不能使用流程控制语句
< view > {{name}} </ view > <!--读取变量-->
< view > {{msg+'Msea'}} </ view > <!--拼接变量--> < view > {{10-9}} </ view > <!--运算符--> < view > {{0||"NB"}} </ view > <!--逻辑运算符-->
<!--数据类型方法--> < view > {{'Msea'.indexOf('xxx')!==-1?'太原最靓仔':'no'}} </ view >< view > {{"我爱北京天安门".substr(0,2)}} </ view >
属性绑定
< image : src = "'https://www.w3school.com.cn/i/eg_tulip.jpg'" />
动态样式
< view :class= "`${'box'}`+''+`12`" > {{ `1` + 1 }} < /view> < view :class= "{className:true}" >< /view> < view :class= "['box',true?'col2':'']" >< /view> < view class= "box1212" :class= "['box',true?'col2':'']" >< /view> < view : style = "{ color: 'red', fontSize: 20 + 'px' }" > 666 < /view> < view : style = "[{ color: pink, fontSize: 20 + 'px' }]" > 777 < /view>
指令
< view class = "box" v-show = "true" > v-show </ view >
< view v-if = "text==='登陆'" > {{'欢迎'+name+'登陆'}} </ view >< view v-else-if = "text==='未登陆'" > 未登陆 </ view >< view v-else > !!!!! </ view >
< input type = "text" v-model = "val" > {{val}} <!--数据双项绑定--><!--支持v-model修饰符--> < input type = "text" v-model . number = "val" > {{val+11}}
事件
<!--事件,阻止事件冒泡--> < view @ click = "test1(true)" > <!--传入参数-->
< button @ click . stop = "test2" > test </ button ></ view >
遍历
<!--数组遍历--> < ul id = "example-1" >
< li v-for = "(item,index) in items" >
{{ item.message }}
</ li ></ ul >
<!--对象遍历--> < div v-for = "(value, name, index) in object" >
{{ index }}. {{ name }}: {{ value }} </ div >
页面栈最多十层。使用uni.navigateTo频繁切换,会导致栈溢出,跳转失败
// 非tabbar配置的页面我们使用 navigateTo跳转时保留老页面,一般用于需要返回 uni.navigateTo({
url : "../one/one?name=Msea" }) // 跳转pages.json>tabbar>配置过的页面,使用 switchTab uni.switchTab({
url : "../one/one" }) // 不保留当前页面,跳转非配置页面 uni.redirectTo({
url : "../one/one" })
响应式单位rpx
推荐使用最近公告推荐使用rpx替代upx
基于苹果6 1px =2rpx
< view class = "box1" ></ view >< view class = "box2" ></ view >< style lang = "scss" >. box1 {
width : 200 rpx;
height : 200 rpx;
background : red ;}. box2 {
width : 100 px ;
height : 100 px ;
background : pink ;}</ style >
微信小程序里面没有 window,document对象,那如果需要进行dom操作
var query = uni.createSelectorQuery(); query.select( ".titlerh" ).boundingClientRect((nodes)=>{
console.log(nodes)}).exec(); query.select( ".box1" )
.boundingClientRect()
.selectAll( ".box2" )
.boundingClientRect()
.exec((res)=>{
console.log(res);});
创建文件夹 components目录统一写法,鼠标右键创建组件
所有组件与属性名都是小写,单词之间以连字符 - 连接。
< template >
< uni-test /></ template >< script >
import uniTest from "../../components/test.vue"
export default {
data() {
return {};
},
methods : {
test(){
this .text = "登录" ;
}
},
components : {
uniTest //引入组件 }
}</ script >< style lang = "scss" >
.. . style </ style >
应用生命周期 App.vue
App({
onLaunch (options) {
console.log( "小程序初始化" );
},
onShow (options)
console.log( "小程序显示" );
},
onHide () {
console.log( "小程序隐藏" );
}})
分页生命周期 pages
Page({
onLoad : function (options) {
// 页面创建时执行 console.log( "页面加载" );
},
onShow : function () {
console.log( "页面进入" );
},
onReady : function () {
console.log( "页面首次渲染完毕时执行" );
},
onHide : function () {
console.log( "页面离开" );
},
onPullDownRefresh : function () {
// 触发下拉刷新时执行 console.log( "下拉触发" );
//enablePullDownRefresh 开启下拉 },
onReachBottom : function () {
// 页面触底时执行 console.log( "下拉到底" );
},
onShareAppMessage : function (e) {
// 页面被用户分享时执行 //通过按钮调用
//点击触发弹窗 < button open - type = "share" > 分享 < /button>
console.log( "用户分享" );
return {
title : '妹子图片' ,
path : '/pages/index/index' , //当前页面 path imageUrl : "/images/1.jpg" ,
desc : '面向百度开发' ,
success : (res) => {
console.log( "转发成功" , res);
},
fail : (res) => {
console.log( "转发失败" , res);
}
}
},
onPageScroll : function () {
console.log( "页面滚动时执行" );
},
onResize : function () {
console.log( "屏幕旋转触发" );
}})
组件生命周期
uni-app components组件支持的生命周期,与vue标准组件的生命周期相同。wx小程序支持生命周期
beforeCreate(){} // 在实例初始化之后被调用 created(){} // 在实例创建完成后被立即调用。 beforeMount(){} // 在挂载开始之前被调用。 mounted(){} // 挂载到实例上去之后调用。 beforeDestroy(){} // 实例销毁之前调用。在这一步,实例仍然完全可用。
使用方法与微信小程序一致,推荐使用uni-ui
< scroll-view :scroll-x = "true" style = "boder:1px solid red;white-space:nowrap" @ scroll = "scroll" >
< view style = " background:red; width:200px;height:100px; display:inline-block;"
></ view >
< view style = "background:yellow;width:200px;height:100px;display:inline-block;" ></ view >
< view style = "background:pink;width:200px;height:100px;display:inline-block;" ></ view >
< view style = "background:blue;width:200px;height:100px;display:inline-block;" ></ view ></ scroll-view >
引入三方UI
例如 Vant Weapp 下载
00001. 根目录下创建 wxcomponents
00002. 将下载包内部 dist包粘贴到uni-app根目录wxcomponents文件夹下
00003. 配置
{
"path" : "pages/one/one" ,
"style" : {
"usingComponents" :{
"van-button" : "/wxcomponents/dist/button/index" //参照wx组件引
}
}}
00001. 在App.vue,引入样式
< style >
/*每个页面公共css */
@ import "/wxcomponents/dist/common/index.wxss" ;</ style >
00001. 在one分页内直接使用van-button组件,不需要引入
00002. 注意如果报错,检查路径如果没有问题,可以选择重编辑器重新启动微信开发工具
获取用户授权弹窗
< button open - type = "getUserInfo" @ getuserinfo = "eventName" > 获取头像昵称 < /button> getUserInfo : function (e) {
app.globalData.userInfo = e.detail.userInfo
this .setData({
userInfo : e.detail.userInfo,
hasUserInfo : true
})}
返回所有用户授权
wx.getSetting({success : ()=>{ "返回用户所有用户授权" }})
照相机接口
因为,调用照相机获取临时图片格式,直接上传三方服务器,是不支持的,需要微信做解析,转发
wx.uploadFile 上传微信需要做转发看不到传输的参数
uni.chooseImage({
count : 1 , //图片张数 sizeType : [ 'original' , 'compressed' ], //原图,压缩图, sourceType : [ 'album' , 'camera' ], //本地相册,拍照 success : res=> {
const tempFilePaths = res.tempFilePaths //微信小程序图片临时路径 this .setData({tempFilePaths});
}}) // 预览接口 viewImgs(index) {
uni.previewImage({
current : this .data.tempFilePaths[index], // 当前显示图片的http链接 urls :this .data.tempFilePaths // 需要预览的图片http链接列表 });},
//小程序图片上传 fileUplaod() {
uni.uploadFile({
url : "http://wxs.ixinangou.net/index/index/dofiles" ,
filePath : this .data.tempFilePaths[ 0 ],
name : "file" , //上传图片key formData : {
user : "MSea" //需要额外携带参数 },
header : {
"content-type" : "multipart/form-data"
},
success : res => {
console.log( "data" );
}
});
}
请求
微信原生请求接口
注意设置,不效验合法域名,回忆怎么添加合法域名
//GET 会自动拼接参数//queryStringParams uni.request({
method : "GET" ,
url : "https://cnodejs.org/api/v1/topics" ,
data : {
uname : "Msea"
},
success : (res) => {
console.log(res)
}}) //POST 默认参数为payLoad,为json uni.request({
method : "POST" ,
url : "https://cnodejs.org/api/v1/topics" ,
data : {
uname : "Msea"
},
success : (res) => {
console.log(res)
}}) //POST form-data 数据 // 'content-type': 'multipart/form-data' 用于文件上传 uni.request({
url : 'https://cnodejs.org/api/v1/topic/5433d5e4e737cbe96dcef312' ,
data : {fileId : '123' },
method : 'POST' ,
header : {
'content-type' : 'application/x-www-form-urlencoded'
},
success :function (res){}})
地图组件
< map
id = "map"
longitude = "经度"
latitude = "纬度"
scale = "缩放级别(14)"
bindcontroltap = "点击地图触发FN"
markers = "{{添加标记}}"
bindtap = "markertap" 点解地图触发
show-location 将地图中心移置当前定位点 , 此时需设置地图组件 show-location 为true 。
style = "width: 100%; height: 300px;" ></ map >
移动地图中心点
移动端测试有效
onShow : function () {
// 地图上下文对象 this .mapCtx = uni.createMapContext( 'map' );
},
ckMap(e){
//小程序不支持 Objcet.assign var temp = {
iconPath : "/assets/img/local.png" ,
id : 0 ,
width : 25 ,
height : 25 ,
...e.detail
}
var markers =this .data.markers;
markers.push(temp);
this .setData({markers},()=>{
var data = {
...e.detail
};
this .mapCtx.moveToLocation(data)
})
}
定位
uni.getLocation({
type : 'gcj02' , //腾讯地图坐标系 success : (res)=> {
const latitude = res.latitude
const longitude = res.longitude
}})
用户授权弹窗
app.json配置文件
//app.json {
"pages" : [ "pages/index/index" ],
"permission" : {
"scope.userLocation" : {
"desc" : "熊猫创客需要获取您的位置亲" // 高速公路行驶持续后台定位
}
}}
获取当前位置并移动地图中心店
wx.getLocation({
type : 'gcj02' , //腾讯地图坐标系 success : (res) => {
const latitude = res.latitude
const longitude = res.longitude
var temp = {
iconPath : "/assets/img/local.png" ,
id : 0 ,
width : 25 ,
height : 25 ,
latitude,
longitude
}
var markers = this .data.markers;
markers.push(temp);
this .setData({
markers
}, () => {
var data = {
latitude,
longitude
};
this .mapCtx.moveToLocation(data)
})
}})
uni-app已经内置了vuex
00001. 在项目的根目录下, 创建一个名为store的文件夹 然
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({
state : {
num : 0
},
mutations : {
add(store){
store.num ++ ;
}
},
actions : {}}) export default store
00001. main.js入口文件引入
import store from './store' Vue.prototype.$store = store;
const app = new Vue({
...App,
store})app.$mount()
00001. 组件内引入
< template >
< view >
< view > {{num}} < /view>
< button @ click = "test" > test1 < /button>
< /view> < /template>
< script >
import {
mapState,
mapMutations
} from 'vuex' ;
export default {
computed : {
...mapState([ 'num' ])
},
methods : {
test() {
console.log( this .$store.commit( "add" ))
}
}
} < /script>
可以安装支付宝小程序进行测试
# ifdef % PLATFORM %
//这些代码只在该平台编译 # endif
# ifdef : if defined 仅在某个平台编译 # ifndef : if not defined 在除里该平台的其他编译 # endif : end if 结束条件编译 % PLATFORM % 需要编译的平台 , 上面的MP就是各个小程序的意思
常用 % PLATFORM % h5 h5平台MP - WEIXIN 微信小程序MP - ALIPAY 支付宝小程序MP - BAIDU 百度小城MP - TOUTIAO 头条小程序
总结: 优先使用Vue用法,只要实现微信开发,支持wx,ui,api,统一使用uni的Api,多看文档
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69913864/viewspace-2691264/ ,如需转载,请注明出处,否则将追究法律责任。