You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Alpine.js变量变化调用方法问题:模态框重开未初始化相机

解决Alpine.js模态框重新打开时相机不初始化的问题

问题根源

x-init 是Alpine.js的初始化指令,仅会在DOM元素首次渲染完成时执行一次。你的模态框关闭后并未被销毁,只是通过CSS隐藏,因此再次打开时不会触发x-init,自然不会重新初始化相机。

解决方案

借助Bootstrap模态框的原生事件(shown.bs.modal/hidden.bs.modal),在模态框显示/隐藏时主动触发相机的初始化和清理逻辑,替代x-init的一次性执行逻辑。

修改后的完整代码

HTML结构

<div x-data="initTestData()" 
     @data-transfer.window="check=$event.detail.check; runningTest=true;" 
     class="modal fade"
     @shown.bs.modal="initTest(check)"
     @hidden.bs.modal="closeTest()">

  <video
      class="w-100 rounded"
      id="test-video">
  </video>

</div>

触发代码(无需修改)

<i @click="$dispatch('data-transfer', {check: check})" data-bs-toggle="modal" role="button"></i>

JavaScript定义(优化后)

function initTestData() {
    console.log('init test data');
    return {
        check: null,
        resource: null,
        runningTest: false,
        initTest(check) {
            console.log('Check initialized: ', check);
            
            // 先清理已有流,避免重复申请相机资源
            if (this.resource) {
                this.resource.getTracks().forEach(track => track.stop());
                this.resource = null;
            }

            const video = document.getElementById('test-video');
            navigator.mediaDevices.getUserMedia({
                video: {
                    facingMode: 'user'
                }
            }).then(stream => {
                this.resource = stream;
                if ("srcObject" in video) {
                    video.srcObject = stream;
                } else {
                    video.src = window.URL.createObjectURL(stream);
                }
                video.onloadedmetadata = function () {
                    video.play();
                };
            }).catch(err => {
                console.error('相机初始化失败:', err);
            });
        },
        closeTest() {
            this.runningTest = false;
            if (this.resource) {
                this.resource.getTracks().forEach(track => track.stop());
                this.resource = null;
            }
            // 重置video元素,避免残留上一次的画面
            const video = document.getElementById('test-video');
            video.srcObject = null;
            if (video.src) {
                window.URL.revokeObjectURL(video.src);
                video.src = '';
            }
        }
    }
}

关键修改说明

  1. 移除video标签的x-init:放弃仅执行一次的初始化逻辑,改用模态框事件触发。
  2. 添加@shown.bs.modal监听:Bootstrap模态框完全显示时触发该事件,此时调用initTest()重新初始化相机。
  3. 添加@hidden.bs.modal监听:模态框关闭隐藏时触发该事件,调用closeTest()停止相机流并清理资源,避免内存泄漏。
  4. 优化initTest逻辑:初始化前先检查并停止已有流,防止重复申请相机权限导致冲突。

内容的提问来源于stack exchange,提问作者Anuj TBE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 02:46:23