uniApp
学习路线:>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
文中下方出现的http链接均为官网纤详细教程地址,官网讲的很全没必要再重新记录一编
组件
响应式宽度单位
rpx 整个屏幕占满的宽是750rpx,它会根据你的屏幕大小进行自适应
.box{
width:750rpx; // 全屏
height:300rpx;
background: green;
}
icon
https://uniapp.dcloud.net.cn/component/icon.html# icon官网
<icon type="success" size="26"/>
text
文本组件:https://uniapp.dcloud.net.cn/component/text.html
scroll-view
可滚动视图区域:https://uniapp.dcloud.net.cn/component/scroll-view.html
swiper
滑块视图容器(轮播图):https://uniapp.dcloud.net.cn/component/swiper.html
<swiper class="swiper" circular="true" autoplay="true" duration="400" interval="3000" indicator-dots>
<swiper-item class="item">
<image src="https://img.alicdn.com/imgextra/i2/6000000008101/O1CN01pgKEuY29iJJRNkCfJ_!!6000000008101-2-octopus.png" mode=""></image>
</swiper-item>
<swiper-item class="item">
<image src="https://img.alicdn.com/imgextra/i3/6000000004754/O1CN01G2onsB1kzNg9NfdBH_!!6000000004754-2-octopus.png" mode=""></image>
</swiper-item>
<swiper-item class="item">
<image src="https://img.alicdn.com/imgextra/i4/6000000004885/O1CN0101FvmP1lxNZ8vWgR6_!!6000000004885-0-octopus.jpg" mode=""></image>
</swiper-item>
</swiper>
image
图片组件:https://uniapp.dcloud.net.cn/component/image.htmlf
表单
按钮
https://uniapp.dcloud.net.cn/component/button.html
输入框
https://uniapp.dcloud.net.cn/component/input.html
navigator
跳转组件:https://uniapp.dcloud.net.cn/component/navigator.html#
类似于h5
的a
标签 ,只能跳转到非tabBar
页面,如果你就要跳到tabBar的页面,那就可以用第二种用法设置open-type
<navigator url="/page/list/list">新闻列表</navigator>
<navigator rul="/page/list/list" open-type='reLaunch'>新闻列表</navigator>
tabBer
https://uniapp.dcloud.net.cn/collocation/pages.html#tabbar
tabBar
里面有 color
:默认颜色;selectedColor
选中颜色;list
下方按钮(列表中也有名字,颜色,图标,选中图标)
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页"
}
},
{
"path" : "pages/list/list",
"style" :
{
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/about/about",
"style" :
{
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "测试app",
"navigationBarBackgroundColor": "#F7F7F7",
"backgroundColor": "#F8F8F8"
},
"tabBar": {
"color": "#333",
"selectedColor": "#00AEEC",
"list": [
{
"text": "首页",
"pagePath": "pages/index/index",
"iconPath": "static/tabbar/index.png",
"selectedIconPath": "static/tabbar/index-h.png"
},
{
"text": "列表",
"pagePath": "pages/list/list",
"iconPath": "static/tabbar/list.png",
"selectedIconPath": "static/tabbar/list-h.png"
},
{
"text": "我的",
"pagePath": "pages/about/about",
"iconPath": "static/tabbar/about.png",
"selectedIconPath": "static/tabbar/about-h.png"
}
]
},
"uniIdRouter": {}
}
和vue比较
计算属性和监听器
每一个计算属性都包含一个 getter
和一个 setter
,默认是利用 getter
来读取。所有 getter
和 setter
的 this
上下文自动地绑定为 Vue 实例。
https://uniapp.dcloud.net.cn/tutorial/vue-basics.html#%E8%AE%A1%E7%AE%97%E5%B1%9E%E6%80%A7computed
组件
不用导入,按照约定创建直接用即可
https://uniapp.dcloud.net.cn/tutorial/vue-components.html
父组件给子组件传参props
使用的时候需要在子组件中定义props
去接收定义的属性
https://uniapp.dcloud.net.cn/tutorial/vue-components.html#props
简单使用
父组件
<template>
<view>
<testComponent title="新闻列表" subTitle="小标题"></testComponent>
</view>
</template>
子组件
<template>
<view>
<view>2022-10-19</view>
<view>{{title}}</view>
<view>{{subTitle}}</view>
</view>
</template>
<script>
export default {
name:"testComponent",
props:["title","subTitle"],
data() {
return {
};
}
}
</script>
也可以这样写设置默认值
props:{
title:{
type: String,
default: "默认标题"
},
time:{
type:Number,
default: Date.now()
},
list:{
type: Array,
default(){
return [1,2,3]
}
},
user:{
type: Object,
default(){
return {name:"匿名",gender:"保密"}
}
}
子组件给父组件传值emit
https://uniapp.dcloud.net.cn/tutorial/vue-components.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BA%8B%E4%BB%B6下滑找到自定义事件
子组件
,传的值不只是字符串,还可以时对象,数组
<template>
<view>
{{title}} 请输入传递的内容:
<input style="border: 1px solid red;" @input="oninput"/>
<button type="primary">发送</button>
</view>
</template>
<script>
export default {
name:"myEvent",
props:{
title:{
type: String,
default: "标题"
}
},
data() {
return {
};
},
methods:{
oninput(e){
// 自定义了一个事件名 myValue,在父组件中就可以跟写系定义的事件一样直接用
this.$emit("myValue",e.detail.value)
}
}
}
</script>
<style lang="scss">
</style>
父组件
<template>
<view>
<myEvent :title="title" @myValue="changeValue"></myEvent>
</view>
</template>
<script>
export default {
data() {
return {
title:"个人中心"
}
},
methods: {
changeValue(e){
this.title+=e;
}
}
}
</script>
<style>
</style>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c3x1jtpH-1667539006951)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221020114541858.png)]
事件修饰符
native
比如在自定义组件上,执行比如@click
事件,如果不加事件修饰符的话,就会以为这个事件是在组件中定义的,这里如果还想让他出发@click
的话,那几就 加上事件修饰符@click.native
sync
当一个子组件改变了一个 prop
的值时,这个变化也会同步到父组件中所绑定。 .sync
它会被扩展为一个自动更新父组件属性的 v-on
监听器。
<myComponen :state.sync="myState"></myComponen>
子组件中
methods:{
onClose(){
this.$emit("update:stte",false)
}
}
表示组组件的这个state属性是个响应式的,子组件是可以控制这个属性的
生命周期函数·
created(){}
实例创建完成后立即调用 一般做网络请求
mounted(){}
挂载到实例上去之后调用 一般做数据渲染 f
路由和页面跳转
https://uniapp.dcloud.net.cn/api/router.html#navigatetof
<navigator url="/pages/demo4/demo4">跳转到demo4页面</navigator>
或者
<view @click="goDemo4">跳转</view>
methods:{
goDemo4(){
uni.navigateTo({
url:"/pages/demo4/demo4",
success: res=>{
}
})
}
}
onload页面传参和vue route路由的差异
路由取
# 传递一个参数,传递多个用 & 拼接
# 页面 传参
<navigator url="/pages/demo4/demo4?wd=uniapp">跳转到demo4</navigator>
# 在H5中 取参
mounted(){
console.log( this.$route.query.wd )
}
# 在小程序中 取参
onLoad(e){
console.log(e)
console.log( getCurrentPages() )
}
常用小功能
消息提示框
https://uniapp.dcloud.net.cn/api/ui/prompt.html
uni.showToast()
·
... @click="clickImg"
methods: {
clickImg(){
uni.showToast({
title:"发布失败",
// icon:"error",
image:"/static/logo.png",
mask:true,
duration:1500,
success(){
setTimeout(()={
uni.navigateTo({
url:"/pages/demo/demo"
})
},1500)
}
})
}
}
showLoding和showModal模态弹窗
showLoding
onLoad(){
uni.showLoading({ // 开启加载窗
title:"数据加载中...",
mask:true
})
setTimeout(()={ // 模拟请求,关闭加载框
uni.hideLoading()
},2000)
}
showModal
methods: {
clickBox(){
uni.showModal({
title:"提示",
content:"是否继续进入下一个页面?",
editable:true, // 展示输入框
success:res=>{
console.log(res)
if(res.confirm){
uni.navigateTo({
url:"page/demo/demo"
})
}else{
uni.showToast({
title:"您已取消",
icon:"none"
})
}
}
})
}
}
showActionSheet从底部向上弹出操作菜单
data(){
return {
arr: ["三国演义","红楼梦","水浒传"]
}
}
uni.showActionSheet({
itemList: this.arr,
success: (res) => {
console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
console.log(this.arr[res.tapIndex])
},
fail: function (res) {
console.log(res.errMsg);
}
});
设置导航条
可以在page.json中进行设置,配合官方文档https://uniapp.dcloud.net.cn/collocation/pages.html#style
也可以在页面中进行设置,不过要在页面初始化的时候设置https://uniapp.dcloud.net.cn/api/ui/navigationbar.html
- 如果需要在页面进入时设置标题,可以在
onReady
内执行,以避免被框架内的修改所覆盖。如果必须在onShow
内执行需要延迟一小段时间
onLoad(){
uni.setNavigationBarTitle({
title:"js操作的导航标签,优先级大于page.json"
})
}
tabbar配置iconfont字体图标
https://uniapp.dcloud.net.cn/api/ui/tabbar.html 这个在小程序不支持
先去官网,https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=3729232&keyword=&project_type=&page=把自己想用的图标给都添加到一个项目中去,然后直接下载到本地,把下载的文件解压后,里面有一个 iconfont.ttf
文件,把这个文件复制到static
下面去,之后去page.json用即可,在list里面配置iconfont
"tabBar": {
"iconfontSrc": "static/font/iconfont.ttf", //导入
"color": "#333",
"selectedColor": "#00AEEC",
"list": [
{
"text": "首页",
"pagePath": "pages/index/index",
"iconPath": "static/tabbar/index.png",
"selectedIconPath": "static/tabbar/index-h.png",
"iconfont": {
"text": "\ue751", //直接去icon官网复制代码  然后把前三个字符使用 \u 进行转译
"selectedText": "\ue751",
"color": "#333",
"selectedColor": "#007AFF",
}
},
{
"text": "列表",
"pagePath": "pages/list/list",
"iconPath": "static/tabbar/list.png",
"selectedIconPath": "static/tabbar/list-h.png"
},
{
"text": "我的",
"pagePath": "pages/about/about",
"iconPath": "static/tabbar/about.png",
"selectedIconPath": "static/tabbar/about-h.png"
}
]
},
uni.request网络请求API接口
https://uniapp.dcloud.net.cn/api/request/request.html
一个简单案例 不带参数
<template>
<view>
<image :src="picUrl" mode="aspectFill" @click="getPicUrl"></image>
</view>
</template>
<script>
export default {
data() {
return {
picUrl:""
}
},
methods: {
getPicUrl(){
uni.showLoading({
title:"数据疯狂请求中..."
})
uni.request({
url:"https://dog.ceo/api/breeds/image/random",
success: (res) => {
this.picUrl = res.data.message;
uni.hideLoading()
}
})
}
},
onLoad() {
this.getPicUrl()
}
}
</script>
<style>
</style>
带有参数,可以写在data里面,也可以?拼接
<template>
<view>
<view v-for="item in picUrl" :key="item.id">
<image :src="item.url" mode="aspectFill" @click="getPicUrl"></image>
</view>
</view>
</template>
<script>
export default {
data() {
return {
picUrl:[]
}
},
methods: {
getPicUrl(){
uni.showLoading({
title:"数据疯狂请求中..."
})
uni.request({
url:"https://api.thecatapi.com/v1/images/search",
method:"post",
data:{
limit:3
},
timeout:3000,
success: (res) => {
console.log(res)
this.picUrl = res.data;
},
fail: (res) => {
console.log(res)
},
complete: () => { // 无论失败还是成功都会走
uni.hideLoading()
}
})
}
},
onLoad() {
this.getPicUrl()
}
}
</script>
小案例
list.vue是一个新闻列表,点击查看详情,和这个详情下面的评论内容
list.vue
<template>
<view class="out">
<view class="row" v-for="item in listArr" :key="item.id" @click="clickItem(item.id)">
<view class="title">{{item.title}}</view>
<view class="content">{{item.body}}</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
listArr:[]
}
},
onLoad() {
this.getData();
},
methods: {
// 获取新闻列表
getData(){
uni.request({
url:"http://jsonplaceholder.typicode.com/posts",
success: (res) => {
this.listArr = res.data
}
})
},
// 点击跳转详情
clickItem(id){
uni.navigateTo({
url:"/pages/list/detail/detail?id="+id
})
}
}
}
</script>
<style lang="scss">
.out{
padding: 50rpx 30rpx;
.row{
padding: 20rpx 0;
border-bottom: 1px dotted #e4e4e4;
.title{
font-size: 36rpx;
padding-bottom: 15rpx;
color: #333;
}
.content{
font-size: 28rpx;
color: #888;
}
}
}
</style>
detail.vue
<template>
<view>
<view class="detail">
<view class="title">{{info.title}}</view>
<view class="content">{{info.body}}</view>
</view>
<view class="comments">
<view class="text">评论</view>
<view class="row" v-for="item in comments" :key="item.id">
<view class="top">
<view class="name">{{item.name}}</view>
<view class="mail">{{item.email}}</view>
</view>
<view class="body">{{item.body}}</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
id:1,
info:{},
comments:[]
};
},
onLoad(e) {
// e是个对象,用来接受navigateTo中?传递过来的值,值的名字为对象中的属性名
this.id = e.id
this.getDetail()
this.getComments()
},
methods:{
// 获取详细信息
getDetail(){
uni.showLoading({
title:"数据请求中...",
mask:true
})
uni.request({
url:"http://jsonplaceholder.typicode.com/posts/"+this.id,
success: (res) => {
this.info = res.data;
},
complete: () => {
uni.hideLoading()
}
})
},
// 获取评论内容
getComments(){
uni.request({
url:`http://jsonplaceholder.typicode.com/posts/${this.id}/comments`, // 这里用反引号,方便拼接
success: (res) => {
this.comments = res.data
}
})
}
}
}
</script>
<style lang="scss">
.detail{
padding: 30rpx;
.title{
font-size: 46rpx;
color: #000;
padding-bottom:20rpx ;
}
.content{
font-size: 30rpx;
color: #666;
padding-bottom: 60rpx;
}
}
.comments{
padding: 30rpx;
background: #f8f8f8;
.text{
font-size: 46rpx;
margin-bottom: 30rpx;
}
.row{
border-bottom: 1px solid #e8e8e8;
padding: 20rpx 0;
.top{
display: flex;
justify-content: space-between;
font-size: 22rpx;
color: #999;
padding-bottom: 15rpx;
}
.body{
font-size: 29rpx;
color: #555;
}
}
}
</style>
数据缓存Storage的用法
https://uniapp.dcloud.net.cn/api/storage/storage.html#setstorage
每个方法都有一个同步和异步,一般用异步即可
设置缓存
onLoad() {
uni.setStorageSync("mykey",{name:"wangmenghu",age:20})
// 或者用
uni.setStorage({
key: "demo",
data: "123"
})
},
读取缓存
let value = uni.getStorageSync('mykey');
if (value) {
console.log(value);
}
// 或者
uni.getStorage({
key: 'storage_key',
success: function (res) {
console.log(res.data);
}
});
清空缓存
try {
uni.removeStorageSync('mykey');
} catch (e) {
// error
}
//或者
uni.removeStorage({
key: 'mykey',
success: function (res) {
console.log('success');
}
});
// 清除所有
try {
uni.clearStorageSync();
} catch (e) {
// error
}
打包不同平台
H5
打开manifest.json
,左侧菜单找到Web配置
,在这里可以设置 标题,路由模式…等等,配置完过后,去上方菜单找到发行,点击网站Pc-Web或手机H5...
然后点击发行,就会进行打包,打包后的文件会在 unpackage
这个文件夹下面的dist/build/h5
微信小程序
AppId
:打开自己注册的小程序,进入开发者的主页,左侧菜单找到开发管理
,在这里找到开发设置
,在这里面就能找到AppID
appid填好后其他的基本上不需要配置,点击发行,发行到微信小程序,它会打包到unpackage/dist/build/mp-weixin
,然后就可以去微信开发者工具中进行配置: 点击右上角详情
下的 项目配置
找到合法域名
,把项目中的接口地址拿过去比如https://menghu.cloud
,这里不知道怎么配可以去小程序的后台,开发管理中找到服务器域名进行添加 ,也可以到本地设置中,不校验合法域名
之后,在微信开发者工具中点击右上角的上传,这时候你再去小程序的后台管理系统,版本管理中就能看到
App
在manifest.json
中选择App图标配置,启动界面配置,模块配置,等等。发行的时候选择 APP云打包。打包后在unpackage/release/apk/...
青年帮项目
1.左右滑动的导航
使用组件scroll-view
<template>
<view>
<scroll-view scroll-x class="navScroll">
<view class="item">国内</view>
<view class="item">国内</view>
<view class="item">国内</view>
<view class="item">国内</view>
<view class="item">国内</view>
<view class="item">国内</view>
<view class="item">国内</view>
<view class="item">国内</view>
<view class="item">国内</view>
<view class="item">国内</view>
</scroll-view>
<view class="content">
<view class="row">
每一行的新闻
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.navScroll{
height: 100rpx;
background-color: #F7F8FA;
// 显示在一行
white-space: nowrap;
/deep/ ::-webkit-scrollbar {
width: 4px !important;
height: 1px !important;
overflow: auto !important;
background: transparent !important;
-webkit-appearance: auto !important;
display: block;
}
.item{
font-size: 40rpx;
// 让它显示在同一行
display: inline-block;
line-height: 100rpx;
padding: 0 30rpx;
}
}
</style>
ew class=“item”>国内
国内
国内
国内
国内
国内
<view class="content">
<view class="row">
每一行的新闻
</view>
</view>
</view>