Uni-app微信小程序开发

环境配置

下载好h5和微信小程序,在h5中创建一个uni-app空项目

第一次运行到微信小程序的时候,需要将小程序的安装路径放到运行下面

文件含义

Pages:存放页面文件的地方。

Static:存放静态文件(图片,音乐等文件)。

unpackage:打包文件配置。

App.vueuni-app的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写视图元素,也就是没有。这个文件的作用包括:调用应用生命周期函数、配置全局样式、配置全局的存储globalData应用生命周期仅可在App.vue中监听,在页面监听无效。

main.jsuni-app 的入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如 vuex

manifest.json:设置打包的文件属性。

pages.json:设置文件路径和全局样式。

uni.scss:全局Css样式。

export default {
		data() {
			return {
				title: 'Hello'
			}
		},
		onLoad() {

		},
		methods: {

		}
	}

文件详情

pages.json
  1. "globalStyle":全局样式。
  1. "navigationBarTextStyle": "whit"文字颜色只有黑色和白色。
  2. "navigationBarTitleText": "uni-app"文件标题。
  3. "navigationBarBackgroundColor": "#00E6FF"文件表头颜色。
  4. "backgroundColor": "#FF9900"文件加载背景色。
  5. "enablePullDownRefresh":true是否启动加载下拉页面。
  6. "backgroundTextStyle":"light"加载的样式只有light(亮色)/dark(灰色)。
  1. pages:页面配置加载数组类型,默认第一项为启动项。
  1. "path"页面路径
  2. "style"样式文件可以覆盖全局样式。
  1. "h5":可以修改页面的h5样式对象类型。
  1. tabBar:可以通过 tabBar 配置项指定一级导航栏,以及 tab 切换时显示的对应页,最多5个最少两个
  1. "color": "#99CCFF":只支持HexColor类型,文字未选中的颜色。
  2. "selectedColor": "##FFFFFF":和color一样不同的是事选中后的颜色。
  3. "backgroundColor":"#FFFFFF"背景颜色也是HEXColor类型。
  4. "borderStyle":"black":边框颜色只支持black和white两种颜色。
  5. "position": "bottom":tabBar出现的位置默认是下,只有上下两个参数(top/bottom)。
  6. list:tab的列表,数组类型。
  1. "pagePath":"pages/index/index":跳转路径。
  2. "text":"首页":标识名称。
  3. "iconPath":"static/tabs/home.png":未选中时候的icon。
  4. "selectedIconPath":"static/tabs/home-active.png":选中时候的icon。
  1. condition:启动模式配置,仅开发期间生效,用于模拟直达页面的场景,如:小程序转发后,用户点击所打开的页面。
  1. "current": 0:当前激活的模式,list节点的索引值
  2. "list":启动模式列表。
  1. "name": "详情页"页面名称。
  2. "path": "pages/detail/detail":页面路径。
  3. "query": "id=30":页面传值。

组件

text组件
<view>
		<view>
			<text>练习两年半</text><!-- 不用view包起来就会在一行显示 -->
		</view>
		<view>
			<text selectable="true">练习两年半</text><!-- selectable变的的可选 -->
		</view>
		<view>
			<text>练习  两年半</text>
		</view>
		<view>
			<text space="ensp">练习  两年半</text><!-- 一个空格等于半个中文大小 -->
		</view>
		<view>
			<text space="emsp">练习  两年半</text><!-- 一个空格等于一个中文大小 -->
		</view>
		<view>
			<text space="nbsp" style="font-size: 30px;">练习  两年半</text><!-- 根据字体大小设置空格大小 -->
		</view>
		<!-- 本来还有一个解码属性但是在写的过程中发现现在小程序和浏览器都能解码。decode bool类型默认false -->
	</view>
view组件
<template>
	<view>
		<view class="box1" hover-class="active">
			<view class="box2" hover-class="active2" hover-stop-propagation :hover-start-time="2000" :hover-stay-time="2000"></view>
		</view>
		<!-- hover-class代表着你点击后执行的样式 -->
		<!-- hover-stop-propagation 类似于冒泡你点击后不会执行他的祖辈,类型为bool -->
		<!-- :hover-start-time="2000" 一定要加:也就是v-bind,点击后多久触发效果单位为毫秒。 -->
		<!-- :hover-stay-time="2000" 触发后的效果执行多久单位也是毫秒 -->
	</view>
</template>
<style>
	.box1{
		width: 100px;
		height: 100px;
		background-color: aqua;
	}
	.box2{
		width: 50px;
		height: 50px;
		background-color: black;
	}
	.active{
		background-color: crimson;
	}
	.active2{
		background-color: aliceblue;
	}
</style>
button组件
<view>
		<button>demo</button>
		<button size="mini">demo</button> <!-- size按钮的大小控制 mini小尺寸 default 默认尺寸 -->
		<button type="primary">demo</button> <!-- type颜色有三个色(primary蓝色,default白色,warn红色) -->
		<!-- 微信小程序、360小程序为绿色,App、H5、百度小程序、支付宝小程序、飞书小程序、快应用为蓝色,字节跳动小程序为红色,QQ小程序为浅蓝色。 -->
		<button type="primary" plain>demo</button> <!-- plain是否为镂空 -->
		<button type="primary" disabled>demo</button> <!-- disabled是否为禁用 -->
		<button loading>demo</button> <!-- loading名称前是否带 loading 图标 -->
		<!-- H5、App(App-nvue 平台,在 ios 上为雪花,Android上为圆圈) -->
	</view>
image组件
<view>
		<!-- 组件默认宽度 320px、高度 240px -->
		<image src="http://destiny001.gitee.io/image/cxk.gif"></image>
		<!-- 保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。 -->
		<image src="http://destiny001.gitee.io/image/cxk.gif" mode="aspectFit"></image>
		<!-- 保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。 -->
		<image src="http://destiny001.gitee.io/image/cxk.gif" mode="aspectFill"></image>
	</view>
swiper组件
<!-- swiper轮播 indicator-dots无限轮播 circular圆点-->
		<view>
			<swiper indicator-dots circular>
				<swiper-item v-for="item in swipers" :key="item.id">
					<image :src="item.img" alt="无法显示"></image> 
				</swiper-item>
			</swiper>
		</view>
map组件
<!-- 地图 -->
		<map class="map" :longitude="longitude" :latitude="latitude" :scale="scale" :markers="markers"></map>
data() {
			return {
				longitude:112.763788,//经度
				latitude:29.610183,//纬度
				scale:13,//地图大小系数
				markers:[
					{
						longitude:112.763788,
						latitude:29.610183,
						iconPath:'../../static/牛.png',//位置图标
						heigth:20,//icon宽度
						with:20//icon高度
					}
				]
			}
		},

scroll-view组件

<template>
	<view class="pics">
		<scroll-view scroll-y="true" class="left">
			<view class="active">家居生活</view>
			<view>家居生活</view>
			<view>家居生活</view>
			<view>家居生活</view>
			<view>家居生活</view>
			<view>家居生活</view>
			<view>家居生活</view>
			<view>家居生活</view>
			<view>家居生活</view>
			<view>家居生活</view>
			<view>家居生活</view>
			<view>家居生活</view>
			<view>家居生活</view>
			<view>家居生活</view>
		</scroll-view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			}
		},
		methods: {
			
		}
	}
</script>

<style lang="scss">
page{
	height: 100%;
}
.pics{
	height: 100%;
	.left{
		width: 200rpx;
		height: 100%;
		border-right: 1px solid #eee;
		view{
			height: 60px;
			line-height: 60px;
			color: #333;
			text-align: center;
			border-top: 1px solid #eee;
		}
	}
}
.active{
	background-color: $shop-color;
	color: white;
}
</style>

uni样式的使用以及scss解释

rpx

rpx即响应式px,是一种根据屏幕宽度自适应的动态单位。uni-app规定屏幕的基准宽度为750rpx。

在实际开发中,1 rpx = 750 * ( 设计稿宽度 / 设计稿基准宽度 )
设计稿的基准宽度为 750px, 有一个红色方块宽度为100px,换算成rpx 结果为:100rpx ,也就是说 1rpx = 1px
uniapp运行微信开发者工具上没反应_微信小程序

icon

@import url("static/fonts/iconfont.css");

将 ~@/static/fonts/在iconfot里面的url都要加上

<view class="iconfont icon-tupian"></view>

scss
<!-- lang="scss" scss就是css3代码解析器 也可以使用uni.scss的属性 -->
<style lang="scss">
	/* 局部样式会覆盖全局 其中不能使用*选择器 page相当于body节点 */
	@import url("a.css");
	/* rpx是响应的px,根据屏幕适应度去调整的,比如750rpx为例375 */
	.box1{
		height: 375rpx;
		width: 375rpx;
		background-color: aqua;
		color: aliceblue;
		font-size: 30rpx;
		text{
			color:$demo; 
		}
	}
</style>
demo
<template>
	<view>
		<view>样式的学习</view>
		<view class="box1">
			盒子
		<text>里面的盒子</text>
		</view>
		<view class="iconfont icon-tupian"></view>
	</view>
</template>

<script>
</script>
<!-- lang="scss" scss就是css3代码解析器 也可以使用uni.scss的属性 -->
<style lang="scss">
	/* 局部样式会覆盖全局 其中不能使用*选择器 page相当于body节点 */
	@import url("a.css");
	/* rpx是响应的px,根据屏幕适应度去调整的,比如750rpx为例375 */
	.box1{
		height: 375rpx;
		width: 375rpx;
		background-color: aqua;
		color: aliceblue;
		font-size: 30rpx;
		text{
			color:$demo; 
		}
	}
</style>

基本事件绑定

<template>
	<view>
		<view>{{msg}}</view>
		<view>{{"你"+"好"}}</view>
		<view>{{1+1}}</view>
		<view>{{booles?"true执行":"false执行"}}</view>
		<image :src="imageurl"></image>
		<view v-for="(item,index) in namelist" :key="item.id">
			序号:{{index+1}} 名字:{{item.name}} 学校:{{item.school}}
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				msg: '你好',
				booles:true,
				imageurl:"http://destiny001.gitee.io/image/monkey_02.jpg",
				namelist:[
					{
						id:0,
						name:"张三",
						school:"岳阳大学"
					},
					{
						id:1,
						name:"李四",
						school:"岳阳大学"
					},
					{
						id:2,
						name:"王五",
						school:"岳阳大学"
					}
				]
			}
		},
		onLoad() {
		},
		methods: {
	
		}
	}
</script>
$event

事件绑定属性的参数

生命周期

uniapp
onLaunch: () => {
			console.log('初始完成')
		},
		onShow: () => {
			console.log('启动')
		},
		onHide: () => {
			console.log('从前台进入后台')
		},
		onError: (err) => {
			console.log("出现错误是触发");
			console.log("错误消息",err);
		}
页面
onLoad(option) {
		   console.log("页面初次加载",option)
		},
		onShow() {
			console.log("页面显示")
		},
		onReady() {
			console.log("页面初次渲染完成")
		},
		onHide() {
			console.log("页面隐藏了")
		}
下拉刷新
前提要设置"enablePullDownRefresh": true
<template>
	<view>
		<view>下拉刷新</view>
		<view v-for="item in list">
			{{item}}
		</view>
		<button type="primary" size="mini" @click="resh">下拉刷新</button>
	</view>
</template>

<script>
	export default{
		data(){
			return{
				list:["file","command","use","format"]
			}
		},
		onPullDownRefresh() {
			setTimeout(()=>{
				this.list=["command","file","use","format"];
				// 停止刷新
				uni.stopPullDownRefresh();
			},2000)
		},
		methods:{
			resh() {
				// 始下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
				uni.startPullDownRefresh()
			}
		}
	}
</script>
上拉刷新
<template>
	<view>
		<view>上拉刷新</view>
		<view v-for="item in listimg" class="box1">{{item}}</view>
	</view>
</template>

<script>
	export default{
		data(){
			return{
				listimg:["list","command","jack","use","list","command","jack","use","list","command","jack","use","list","command","jack","use"]
			}
		},
		onReachBottom() {
			this.listimg=[...this.listimg,...["list","command","jack","use","list","command","jack","use","list","command","jack","use","list","command","jack","use"]]
			console.log("到底了");
		},
		methods:{
		
			
		}
	}
</script>
<style>
	.box1{
		margin-top: 50px;
	}
</style>

get请求

npm install
node ./src/app.js

<template>
	<view>
		<view>get请求</view>
		<button type="primary" size="mini" @click="get">请求</button>
	</view>
</template>

<script>
	export default{
		data(){
			return{
				
			}
		},
		methods:{
			get () {
				uni.request({
					url:"http://localhost:8082/api/getlunbo",
					success: (res) => {
						console.log(res);
					}
				})
			}
		}
		
	}
</script>

<style>
	.box2{
		margin-top: 80px;
	}
</style>

数据缓存

setStorage

将数据存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个异步接口

<template>
	<view>
		<view>数据缓存</view>
		<view></view>
		<button type="primary" size="mini" @click="setStorage">setStorage缓存</button>
		<button type="primary" size="mini" @click="getStorage">getStorage获取</button>
		<button type="primary" size="mini" @click="removeStorage">removeStorage获取</button>
	</view>
</template>

<script>
	export default {
		data() {
			return {

			}
		},
		methods: {
			setStorage() {
				// uni.setStorage({
				// 	key: "name",
				// 	data: 402,
				// 	success() {
				// 		console.log("本地缓存异步成功");
				// 	}
				// })
				uni.setStorageSync("id", 10);
			},
			getStorage() {
				// uni.getStorage({
				// 	key: "name",
				// 	success(res) {
				// 		console.log("获取成功", res.data)
				// 	}
				// })
				const res = uni.getStorageSync("id");
				console.log(res);
			},
			removeStorage() {
				// uni.removeStorage({
				// 	key: "name",
				// 	success() {
				// 		console.log("移除成功");
				// 	}
				// })
				uni.removeStorageSync("id");
			}

		}

	}
</script>

相片上传

<template>
	<view>
		<view>上传图片</view>
		<button type="primary"  @click="chooseImg">上传相片</button>
		<image v-for="item in listimg" :src="item" @click="previewImage(item)"></image>
	</view>
</template>

<script>
	export default{
		data(){
			return{
				listimg:[]
			}
		},
		methods:{
			chooseImg(){
				// 最大值为9
				uni.chooseImage({
					count:5,
					success: (res) => {
						this.listimg=res.tempFilePaths;
					}
				})
			},
			previewImage(imgurl){
				console.log(imgurl);
				uni.previewImage({
					current:imgurl,//current 为当前显示图片的链接/索引值
					urls:this.listimg,//需要预览的图片链接列表
					loop:true,//是否可循环预览,默认值为 false
					indicator:'number'//图片指示器样式,可取值:"default" - 底部圆点指示器; "number" - 顶部数字指示器; "none" - 不显示指示器
				})
			}
			
		}
	}
</script>

条件编译跨平台

<template>
	<view>
		<view>条件编译跨平台</view>
		<!-- #ifdef MP-WEIXIN -->
		<view>这是小程序显示的东西</view>
		<!-- #endif -->
		<!-- #ifdef H5 -->
		<view>这是h5显示的东西</view>
		<!-- #endif -->
	</view>
</template>

<script>
	export default{
		onLoad () {
			// #ifdef H5
			console.log("我希望h5显示");
			// #endif
			// #ifdef MP-WEIXIN
			console.log("我希望小程序显示");
			// #endif
		}
	}
</script>
<style>
	/* html的样式 */
	/* #ifdef H5 */
	view{
		color: aqua;
	}
	/* #endif */
	
	/* 小程序的样式 */
	/* #ifdef MP-WEIXIN */
	view{
		color: orange;
	}
	/* #endif */
</style>

页面跳转

<template>
	<view>
		<view>跳转页面</view>
		<navigator url="/pages/detail/detail">跳转详情页面</navigator>
		<!-- open-type="switchTab"用于跳转tabbar页面不加这个属性是跳转不了的 -->
		<navigator url="/pages/message/message" open-type="switchTab">跳转信息页面</navigator>
		<!-- 关闭当前页面打开新的页面 -->
		<navigator url="/pages/detail/detail" open-type="redirect">redirect跳转详情页面</navigator>
		<!-- 通过当前的api方式跳转 -->
		<button @click="godetail">跳转详情页面</button>
		<button @click="gomessage">跳转信息页面</button>
		<button @click="gomessage">redirect跳转详情页面</button>
	</view>
</template>
<script>
	export default{
		methods:{
			godetail(){
				uni.navigateTo({
					// 用?加&拼接多个值 用Load事件接受值
					url:"/pages/detail/detail?id=30&name=nihao"
				})
			},
			gomessage(){
				uni.switchTab({
					url:"/pages/message/message"
				})
			},
			removePresentPages(){
				uni.redirectTo({
					url:"/pages/detail/detail"
				})
			}
		}
	}
</script>
<style>
	
</style>


说明

navigate

保留当前页面,跳转到应用内的某个页面

redirect

关闭当前页面,跳转到应用内的某个页面

reLaunch

关闭所有页面,打开到应用内的某个页面

switchTab

跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面

组件创建与组件生命周期

组件创建:
<template>
	<view>
		<view>跳转页面</view>
		<teat></teat>
		<!-- 通过当前的api方式跳转 -->
		<button @click="godetail">跳转详情页面</button>
		<button @click="gomessage">跳转信息页面</button>
		<button @click="gomessage">redirect跳转详情页面</button>
	</view>
</template>
<script>
	import teat from '../teat/teat.vue'//创建路径
	export default{
		methods:{
			godetail(){
				uni.navigateTo({
					// 用?加&拼接多个值
					url:"/pages/detail/detail?id=30&name=nihao"
				})
			},
			gomessage(){
				uni.switchTab({
					url:"/pages/message/message"
				})
			},
			removePresentPages(){
				uni.redirectTo({
					url:"/pages/detail/detail"
				})
			}
		},
		components:{
			teat
		}
	}
</script>
<style>
	
</style>
组件生命周期:
<template>
	<view id="names">
		这是teat组件{{num}}
	</view>
</template>

<script>
	export default{
		data(){
			return{
				num:3,
				times:""
			}
		},
		beforeCreate() {
			console.log('开始初始化');
			console.log(this.num);//会发现num数据未打印
		},
		created() {
			console.log("初始化完成");
			console.log(this.num);//num数据打印出来
			this.times=setInterval(()=>{
				console.log("12");
			},1000);
		},
		beforeMount() {
			console.log("挂在之前");
			console.log(document.getElementById("names"));
		},
		mounted() {
			console.log("挂载完成之后");
			console.log(document.getElementById("names"));
		},
		destroyed() {
			console.log("摧毁完成");
			clearInterval(this.times)
		}
	}
</script>

<style>
</style>

传值

父子之间
<template>
	<view>
		<view>跳转页面</view>
		<teat v-if="booles" :tiles="tiles" @accept="accepts"></teat>
		从子组件转过来的值:{{nums}}
		<teat-a></teat-a>
		<teat-b></teat-b>
	</view>
</template>
<script>
	import teat from '../teat/teat.vue'
	import teata from '../teat/a.vue'
	import teatb from '../teat/b.vue'
	export default{
		data(){
			return{
				booles:true,
				tiles:"我是从父页面传过来的",
				nums:0
			}
		},
		methods:{
			accepts(num){
				this.nums=num;
			}
		},
		components:{
			teat,
			"teat-a":teata,
			"teat-b":teatb
		}
	}
</script>
<style>
	
</style>
<template>
	<view>
		<view id="names">
			这是teat组件{{num}}<br>	
			{{tiles}}
		</view>
		<button @click="TransferValue">给父组件传值</button>
	</view>
</template>

<script>
	export default{
		data(){
			return{
				num:3,
				times:""
			}
		},
		props:["tiles"],
		methods:{
			TransferValue(){
				console.log("给父组件传值");
				this.$emit("accept",this.num)
			}
		}
	}
</script>

<style>
</style>
兄弟之间
<template>
	<view>
		这是a组件:<button @click="senddata">修改b组件上面的数据</button>
	</view>
</template>

<script>
	export default{
		data(){
			return{
				
			}
		},
		methods:{
			senddata(){
				uni.$emit("acceptnums",10)
			}
		}
	}
</script>

<style>
</style>
<template>
	<view>
		这是b组件的数据{{num}}
	</view>
</template>

<script>
	export default{
		data(){
			return{
				num:0
			}
		},
		created() {
			uni.$on("acceptnums",(nums)=>{
				this.num+=nums;
			})
		}
	}
</script>

<style>
</style>

uni-ui组件

<template>
	<view>
		<view>跳转页面</view>
		<teat v-if="booles" :tiles="tiles" @accept="accepts"></teat>
		从子组件转过来的值:{{nums}}
		<teat-a></teat-a>
		<teat-b></teat-b>
		<uni-calendar
			:insert="true"
			:lunar="true" 
			:start-date="'2019-3-2'"
			:end-date="'2019-5-20'"
			@change="change"
			 >
		</uni-calendar>
	</view>
</template>
<script>
	import teat from '../teat/teat.vue'
	import teata from '../teat/a.vue'
	import teatb from '../teat/b.vue'
	import uniCalendar from '../../components/uni-calendar/uni-calendar.vue'
	export default{
		data(){
			return{
				booles:true,
				tiles:"我是从父页面传过来的",
				nums:0
			}
		},
		methods:{
			accepts(num){
				this.nums=num;
			},
			change(e){
				console.log("值为:",e)
			}
		},
		components:{
			teat,
			"teat-a":teata,
			"teat-b":teatb,
			uniCalendar
		}
	}
</script>
<style>
	
</style>

拨打电话

uni.makePhoneCall({
					phoneNumber:'15677777777'//电话号码
				})

特殊js的解释

export 某方法 就是可以让这个方法导出配置相应的import{某方法名称}from '路径'
	在vue中还要写Vue.prototype.$名称=某方法名称;
	调用this.$名称。

    return new Promise():使用
    function demo(){return new Promise(res=>{res("你好")})};console.log(demo());
	Promise语法糖:async 其实就是promise的语法糖。函数前面必须加一个async,异步操作的方法前加一个await 关键字。顾名思义,就是让你等一下,执行完了再继续往下走。注意:await 只能在async函数中执行,否则会报错。
    [...this.数组名,...[]]中的...是展开的意思。

calendar>

### 拨打电话

```vue
uni.makePhoneCall({
					phoneNumber:'15677777777'//电话号码
				})

特殊js的解释

export 某方法 就是可以让这个方法导出配置相应的import{某方法名称}from '路径'
	在vue中还要写Vue.prototype.$名称=某方法名称;
	调用this.$名称。

    return new Promise():使用
    function demo(){return new Promise(res=>{res("你好")})};console.log(demo());
	Promise语法糖:async 其实就是promise的语法糖。函数前面必须加一个async,异步操作的方法前加一个await 关键字。顾名思义,就是让你等一下,执行完了再继续往下走。注意:await 只能在async函数中执行,否则会报错。
    [...this.数组名,...[]]中的...是展开的意思。