使用uni-app开发初体验
使用HBuilder X开发快捷键的使用及对vue的适配支持体验
一、多端支持的全局引入组件方法
问题描述: 在所有页面中增加功能性全局按钮
问题解析:
- 不需要在app.vue里添加router-view,这没法实现多端;
- 不需要在main.js使用document,这也没法实现多端;
- app端不需要创建新的窗口,效果不好,也没法实现多端
主要思路:通过创建一个总组件,把它当做所有页面的大盒子,利用插槽实现。
实现步骤: - 在components文件夹下创建page组件(组件名随意),在该组件内写上基本每个页面都能用上的组件和方法;
- 在main.js引入
<template>
<view class="globalpage">
<slot></slot>
<view class="globalpage-other">
<!-- 页面中的其他内容 -->
</view>
</view>
</template>
// 引入
import Page from './components/page.vue';
Vue.component('page', Page)
- 在你想使用总组件的页面下使用,template下应该是view,这时候把view改成page(带上ref方便操作),接下来就可以随心所欲的使用全局组件了。
<template>
<page ref="pageGlobal">
<!-- 这里写代码,会被放置在globalpage中 slot 定义的位置 -->
</page>
</template>
二、创建.gitignore文件
新创建的文件目录中不包含.gitignore文件,可以在项目根目录中新建一个,具体步骤如下:
- 在项目根目录下执行cmd,新建
.gitignore文件
touch .gitignore
如果遇到报错提示:‘touch’ 不是内部或外部命令,也不是可运行的程序 或批处理文件。 可以改用如下命令行进行创建:
echo test>.gitignore
这时在项目根目录中就可以看到新建的.gitignore文件夹了
- 把不需要提交到
git上面的文件提交进去
node_modules/
.project
unpackage/
.DS_Store
- 如果项目在之前提交过以上文件(如unpackage),则需要执行以下命令:
git rm -r --cached unpackage
- 执行完成后,重新提交代码即可。
三、常见业务需求开发
1. 判断登录设备
uni.getProvider({
service: 'oauth',
success: (res) => {
if (res.provider.indexOf('weixin') > -1) {
this.provider = 'weixin'
}
},
complete: () => {
}
})
2. 自定义头部导航栏
<template>
<view class="navBarWarp" :style="{height:navHeight+'px'}">
<view class="navBar" :style="{marginTop:searchMarginTop+'px',width:searchWidth+'px'}">
<view class="navBarName" :style="{lineHeight:searchHeight+'px'}">{{title}}</view>
<view class="searchGroup" :style="{width: searchBtnWidth, height:searchHeight+'px'}">
<image src="/static/images/home/search.png" class="searchImage" />
<input class="searchInput" placeholder="请输入关键字搜索"/>
</view>
</view>
</view>
</template>
<script>
export default {
props: ['title'],
data () {
return {
navHeight: '',
menuButtonInfo: {},
searchMarginTop: 0,
searchWidth: 0,
searchHeight: 0,
searchBtnWidth: '60%'
}
},
created() {
this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
const { top, width, height, right } = this.menuButtonInfo
const statusBarHeight = uni.getSystemInfoSync().statusBarHeight
const margin = top - statusBarHeight
this.navHeight = height + statusBarHeight + (margin * 2)
this.searchMarginTop = statusBarHeight + margin +3
this.searchHeight = height-6
this.searchWidth = right - width
if(this.title.length == 4) this.searchBtnWidth = '50%'
}
}
</script>
<style lang="scss" scoped>
.navBarWarp{
width:100%;
position: fixed;
left: 0;
top: 0;
background: #846efd;
z-index: 999;
.navBar{
display: flex;
flex-direction: row;
justify-content:space-between;
width: 100%;
color:#ffffff;
.navBarName{font-size: 16px;margin:0 0 0 24rpx;}
.searchGroup {
position:relative;
background-color: #ffffff;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 60rpx;
padding: 0 30rpx;
margin-right:30rpx;
.searchInput {
font-size: 12px;
margin-left: 40rpx;
color:#999999;
}
.searchImage {
position:absolute;
height: 32rpx;
width: 32rpx;
}
}
}
}
</style>
3.下拉刷新,上拉加载
方法二、使用uniapp 相关配置和对应生命周期实现
首先我们要知道,uniapp的上拉加载和下拉刷新一样都存在两种情况,一个是整体的上拉(生命周期函数 onReachBottom 实现), 一个是局部的上拉(基于 scrpll-view 组件实现);
因为列表内容嵌套出现问题,导致 onReachBottom 事件无法被触发,记住:列表内容如果是组件,外层不需要再包裹一层,即列表项必须是页面内容的第一层级。这就是整体的上拉
scrpll-view 实现局部的下拉,代码实现在下面
整体的下拉
// 在 pages.json 中配置
"pages": [
{
"path": "pages/list/list",
"style": {
"navigationBarTitleText": "列表页",
"enablePullDownRefresh": true, // 开启下拉刷新
"onReachBottomDistance": 200 // 页面上拉触底事件触发时距页面底部距离,单位只支持px
}
}
]
// 开启后均有对应的生命周期,便可以在相应的页面中进行逻辑处理了。
// 在 list.vue 页面中,与生命周期同级
onPullDownRefresh() {
console.log("触发了下拉刷新")
setTimeout(() => {
uni.stopPullDownRefresh() // 完成刷新,关闭下拉loading
}, 2000)
},
onReachBottom() {
console.log("页面触底了")
},
methods: {
pullDown() {
uni.startPullDownRefresh() // 开启下拉
}
}
// 示例:接口调用实现上拉加载更多和下拉刷新
data() {
return {
listData: [],
pageindex: 1,
pageSize: 10,
flag: false
}
},
onLoad() {
this.getListData()
},
onPullDownRefresh() {
console.log("触发了下拉刷新")
// 数据初始化
this.pageindex = 1
this.listData = []
this.flag = false
// 完成刷新,关闭下拉loading,否则会一直存在
setTimeout(() => {
this.getListData(() => {
uni.stopPullDownRefresh()
})
}, 1000)
},
onReachBottom() {
console.log("页面触底了")
// 当加载到全部数据后,给出一个到底标识
if(this.listData.length < this.pageindex * this.pageSize) return this.flag = true
this.pageindex++
this.getListData()
},
methods: {
async getListData(callBack) {
const res = await this.$myRequest({
url: '/api/getlist/pageindex='+this.pageindex
})
this.listData = [...this.listData, ...res.data.items]
callBack && callBack() // 回调函数,有就执行
},
}
局部的下拉
#scroll-view# 官方文档
如不触发滚动事件,则可能出现的原因分析如下:
- scroll-view组件是局部的滚动, 如果只滚动整个页面, scroll不滚动到底, 就不会触发局部的上拉;
- scroll-view组件里的数据太少, 不能进行滚动;
- 没有给scroll固定高;
- 没有用view将scroll包裹住;
- 使用了overflow:hidden;
- 没有设置scroll-y;
<scroll-view :scroll-top="scrollTop" scroll-y="true" class="list-content scroll-Y" @scrolltolower="onScrollToBottom">
<view class="list-content--item">
// ……
</view>
<!-- 很多item 项 -->
<!-- 到底标识 -->
<view v-if="flag">------ 我到底啦!------</view>
</scroll-view>
methods: {
/**
* 代码实现和 onReachBottom 一样
*/
onScrollToBottom() {
// ……
}
}
4.遮罩层事件穿透解决办法
问题描述:出现遮罩层后,比遮罩层层级低的其他组件依然能滑动滚动
解决方案:直接在需要防止事件穿透的组件标签上加上
:catchtouchmove="true"
5.需要在手机页面上元素跟随手指,用了touchmove,但所有手机都有点卡顿的感觉?
1、用transform:translateY移动,避免直接操作top、margin-top等导致页面频繁reflow
2、touchmove的handler里面,需要执行preventDefault(),屏蔽掉原生滚动
html,body{
top:0;
left:0;
position: absolute;
-webkit-overflow-scrolling: touch;
z-index:1;
}
6. 使用索引列表(uni-indexed-list),自定义展示列表
uni-app中页面部分内容使用索引列表(uni-indexed-list),动态数据
四、开发微信小程序遇到的问题
1. Cannot read property 'forceUpdate' of undefined
原因: 在uni-app里没有配置微信小程序的 AppID
解决: 在项目的 manifest.json 文件中配置已经注册申请的AppID
2. TypeError: Cannot read property 'call' of undefined
问题描述:
- 时有时无,偶有代码变换就会报错;
- uniapp开发,之前是不会的,更新带有热重载的版本后,就出现这种问题。 原因: 未知,一说是因为js和vue不在一起导致的
解决: 在 manifest.json 文件中配置
/* 分包优化 */
"optimization" : {
"subPackages" : true
},
使用这个配置主要是包太大,加上这个分包的依赖只会打包到分包里,可以看到每个分包都有vendor.js,否则所有的依赖都打包到主包里面,会导致主包的vendor过大;
一般上线的包,可以用"optimization" : { "subPackages" : true}压缩代码,平时开发热更新就不用了。
或者在uniapp重启项目进行解决。
3. 获取用户手机号,提示:getPhoneNumber:fail no permission
<button
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
@click="getPhonenum"
>立即授权</button>
按照界面提示进行认证,认证时约需要支付300元认证费用。大概需要1-3工作日,认证完成后重新启动IDE,即可。