我这边项目比较复杂,需要调用摄像头,并且录制视频,最后还需要上传视频。由于开发环境是正常的,生产环境是坏的,所以无法定位代码哪里错误,只能用排除法,不断修改,打包,修改,打包。效率低的很。导致光这个打包问题,就浪费了两天时间,从昨天下午到今天下午。半夜还在加班到11点半,就修复这一个问题。不得不说前端是真的不成熟,vue3更新迭代估计还有很多你想象不到的bug。后续我肯定不会再学vue4了。
这是dom结构
<div id="defaultId1" :style="{ width: width + 'px', height: height + 'px' }" class=" u69ed5">
{{gameStatus}}
<canvas id="heatMap" class=" uqdp8an" ref="canvasLine" :width="width" :height="height">
</canvas>
<video id="webcam" class=" u2wO8T9" :width="width" :height="height" autoplay ref="myVideo">
</video>
<canvas id="overlay" class=" u7K2LfL" width="80" height="50" ref="canvasEye">
</canvas>
<!-- <div id="g8fe8e" class=" ub4573" >
<div id="gb53dd" @click="startCamera()" class=" u8a30b" >打开摄像头
</div>
<div id="gb1bef" @click="stopCamera()" >关闭摄像头
</div>
</div> -->
</div>
这个是组件传参
const props = defineProps({
// height
height: {
type: Number,
default: 300
},
// width
width: {
type: Number,
default: 400
},
gameStatus: {
type: String,
default: 'noStart',
}
})
let {
height,
width,
gameStatus
} = toRefs(props)
首先的第一个问题是proxy.$refs.组件名称,这种写法突然不支持了,其他页面支持。后面改为
<div ref='组件名'>
const 组件名 = ref(null)
这种形式的写法就可以直接获取组件了。完全看不出他们的关系,但就是这么巧妙,只要名称一样他们就是赋值的关系。
好不容易过了这第一关。到了第二关又继续报错。
<mycomponent :gameStatus="gameStatus" ref="md">
后来才发现上面的案例中gameStatus的一个父组件与子组件的通信,我只要改了gameStatus就报错,什么$refs undfined特别的无语。
可能是这个组件过于复杂,父组件参数一旦修改子组件就挂了。
目前我都没找到原因,只能换一种方式处理。这种游戏状态组件里直接用局部变量,myStatus来做判断,然后父组件直接修改子组件的myStatus。
md.value.myStatus = true
这个调用摄像头的组件,后续又发现了新的问题,就是变量修改,动态渲染就直接挂掉如下代码
<div v-if="isBigVideo">
<div v-show="show_camera_picture" class="img_box" id="bigImg">
<img class="img_video" src="@/assets/images/common_sp_0105.png" alt="摄像头" >
</div>
<video id="webcam2" class=" u2wO8T5" width="800" height="700" autoplay v-show="!show_camera_picture">
</video>
</div>
show_camara_picture变量修改,页面虽然做了切换但是直接报错refs找不到。当然这个也是只有打包才有这个错误。
我个人分析可能有几个原因
1.可能vue3渲染的时候,发现这个摄像头实时渲染界面过于复杂,处理不了。就强制刷新了整个dom结构,导致js脚本读流的时候卡死。
2.读流的过程过于复杂,vue3本身的bug没有处理调用底层硬件的情况,比如调用摄像头,调用录音功能等。
解决办法是用原生的方法做效果。
也就是父组件调用一下方法来做动态切换显示隐藏功能。
function toggleBigImgOrVideo(isShowVideo){
if(isShowVideo){
document.getElementById('bigImg').style.display = 'none'
document.getElementById('webcam2').style.display = 'block'
}else{
document.getElementById('bigImg').style.display = 'block'
document.getElementById('webcam2').style.display = 'none'
}
}