Uniapp-踩坑汇总
//uview Input有前后两插槽插槽正常情况下可以这么写
<u-input placeholder="请输入内容">
<template #prefix>
前插槽
</template>
<template #suffix>
后插槽
</template>
</u-input>
//但是在app中使用该写法会出现undefined,应改为
<u-input placeholder="请输入内容">
<view slot='prefix'>
前插槽
</view>
<view slot='suffix'>
后插槽
</view>
</u-input>
//input手动获取焦点
<u-input :focus='focus' @blur='focus = false'></u-input>
//失去焦点时将focus设为false
<script>
export default{
data(){
return{
focus:false
}
},
methods:{
//手动获取焦点时触发该方法,将focus设为true
//使用ref获取input实例并没有focus获取焦点方法
//该方法在nvue页面中会有bug,暂未找到解决办法
inputFocus(){
this.focus = true
}
}
}
</script>
video标签
根据uniapp官方文档说明
<video/>
组件在非H5端是原生组件,层级高于普通前端组件,覆盖其需要使用cover-view组件或plus.nativeObj.view、subNVue。并且,在实际案例中,如果使用了video
标签,在app表现层,使用scroll-view
标签包裹滚动video
,app会出现黑块,卡顿等现象.
解决办法.1 使用富文本解析器来使用h5video
标签解决该问题
//创建一个公共组件,使用时直接传入src即可
<template>
//u-view富文本解析组件
<u-parse class='w-full' :content="videoHtml"></u-parse>
</template>
<script>
export default{
props:{
src:{
type:String,
required:true
},
height:{
type:String,
default:'180px'
}
},
computed:{
videoHtml() {
return `<video class="video" muted src="${this.src}" :loop="${true}" :autoplay="${true}" object-fit="fill" style="width:100%;height:${this.height}"></video>`;
},
}
}
</script>
解决办法.2 使用nvue页面来渲染有video
的页面
根据官方文档介绍如深度使用video,建议使用 nvue。比如如下 2 个场景:video 内嵌到 swiper 中,以实现抖音式视频滑动切,通过cover-view实现内容覆盖,比如增加文字标题、分享按钮。nvue页面写法局限很多,如果不是深度使用video还是不建议使用nvue页面
网络请求
网络请求我使用了第三方库,luch-request,支持请求拦截,响应拦截,全局配置等等;
//request.js
import Request from './luch-request/luch-request/index.js'
import config from '@/common/config'//全局配置文件
const http = new Request();
// 初始化请求配置
http.setConfig((defaultConfig) => {
/* defaultConfig 为默认全局配置 */
defaultConfig.baseURL = config.baseUrl /* 根域名 */
return defaultConfig
})
//requestInterceptors.js
/**
* 请求拦截
* @param {Object} http
*/
import http from '@/util/js_sdk/index.js'
module.exports = (vm) => {
http.interceptors.request.use((config) => {
config.data = config.data || {}
const token = vm.$ls.getItem('access_token')
if(token){
config.header={
"Authorization":`bearer ${token}`,
...config.header,
}
}
return config
}, (config) =>
Promise.reject(config))
}
export default http
//responseInterceptors.js
/**
* 响应拦截
* @param {Object} http
*/
import http from '@/util/js_sdk/index.js'
module.exports = (vm) => {
http.interceptors.response.use((response) => {
const data = response.data
// 自定义参数
const custom = response.config?.custom
if (data.code !== 0) { // 服务端返回的状态码不等于0,则reject()
// 如果没有显式定义custom的toast参数为false的话,默认对报错进行toast弹出提示
if (custom.toast !== false) {
uni.$u.toast(data.msg)
}
if(data.code === 400){
uni.navigateTo({
url: '/pages/login/index',
animationType:'none'
})
}
// 如果需要catch返回,则进行reject
if (custom?.catch) {
return Promise.reject(data)
} else {
// 否则返回一个pending中的promise
return new Promise(() => { })
}
}
return data || {}
}, (response) => { /* 对响应错误做点什么 (statusCode !== 200)*/
return Promise.reject(response)
})
}
//request.js
module.exports = (vm) => {
require('./requestInterceptors')(vm)
require('./responseInterceptors')(vm)
}
//main.js引入
const app = new Vue({
store,
...App
})
// 引入请求封装
//传入vue实例,可通过vue实例访问vuex下的数据
require('./util/request/index')(app)
NVUE页面
据官方文档介绍uni-app App 端内置了一个基于 weex 改进的原生渲染引擎,提供了原生渲染能力。 在 App 端,如果使用 vue 页面,则使用 webview 渲染;如果使用 nvue 页面(native vue 的缩写),则使用原生渲染。一个 App 中可以同时使用两种页面,比如首页使用 nvue,二级页使用 vue 页面,hello uni-app 示例就是如此。 虽然 nvue 也可以多端编译,输出 H5 和小程序,但 nvue 的 css 写法受限,所以如果你不开发 App,那么不需要使用 nvue。 以往的 weex ,有个很大的问题是它只是一个高性能的渲染器,没有足够的 API 能力(比如各种 push sdk 集成、蓝牙等能力调用),使得开发时非常依赖原生工程师协作,开发者本来想节约成本,结果需要前端、iOS、Android 3 拨人开发,适得其反。 nvue 解决了这个问题,让前端工程师可以直接开发完整 App,并提供丰富的插件生态和云打包。这些组合方案,帮助开发者切实的提高效率、降低成本。
//nvue页面有许多css属性不能支持,写法受限,列举一些常见的坑
- 1. 如果要修改字体相关属性,字必须包裹在text标签内
- 2. text标签在app中不能嵌套(如果实在要嵌套可使用富文本解析来写)
- 3. 不支持百分比布局,所有百分比写法将失效
- 4. nvue页面默认布局为flex布局,也只支持flex布局,并且flex-direction默认为column
- 5. css选择器支持的比较少,只能使用 class 选择器
- 6. class 进行绑定时只支持数组语法
- 7. 如果要让顶层元素占满全屏可使用`width: 750rpx;flex: 1;`来让顶级元素占满全屏
自定义组件双向绑定
uniapp 再编译到小程序时,使用自定义双向绑定组件,绑定触发事件只能用input,别的事件无法触发(坑)
<!-- 父组件 -->
<Children v-model='test'></Children>
<!-- 子组件 -->
<script>
export default{
mode:{
event:"input",//如果改为其他事件名wx小程序无法触发
prop:"value"
},
props:{
value:{
type:String
}
},
}
</script>