Skip to content

Uniapp-踩坑汇总

html
//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标签解决该问题

html
//创建一个公共组件,使用时直接传入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,支持请求拦截,响应拦截,全局配置等等;

js
//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,并提供丰富的插件生态和云打包。这些组合方案,帮助开发者切实的提高效率、降低成本。

html
//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,别的事件无法触发(坑)

html
<!-- 父组件 -->
<Children v-model='test'></Children>
<!-- 子组件 -->
<script>
export default{
  mode:{
    event:"input",//如果改为其他事件名wx小程序无法触发
    prop:"value"
  },
  props:{
    value:{
      type:String 
    }
  },
}
</script>

暂时就想到这么多,后续想到会继续填坑