场景:

项目vue项目开发中,使用addEventListener方法对页面某一元素添加监听事件。在addEventListener方法内部无法获取data内部定义的变量。

编写 videoList.vue 页面,页面代码如下所示。

<template>
    <div class="container">
        <div class="video-list">
            <div class="remote-video">
                <div class="remote-video-item" v-for="pull in pullStreamList">
                    <video controls="controls" controlslist="nodownload" :disablePictureInPicture="true"
                           autoplay="autoplay" :id="`remote-video-${pull.id}`">
                        <source src="http://vjs.zencdn.net/v/oceans.mp4" type="video/mp4">
                    </video>
                </div>

            </div>

        </div>
    </div>
</template>

<script>
    export default {
        name: "test",
        data(){
            return{
                pullStreamList:[],
            }
        },
        mounted:function () {
            let _this = this;
            _this.pullStreamList.push({"id":"00001","name":"test00001"});

            let timer = setInterval(function () {
                _this.removeRemoteVideo('00001');
                clearInterval(timer)
            },10)
        },
        methods:{
            removeRemoteVideo:function (pullId) {
                let newRemoteVideo = document.getElementById("remote-video-" + pullId);
                console.log("newRemoteVideo",newRemoteVideo);
                console.log(" _this.pullStreamList before", this.pullStreamList);
                newRemoteVideo.addEventListener("play",function () {
                    console.log(" _this.pullStreamList after", this.pullStreamList);
                })
            }
        }
    }
</script>
数据展示

页面控制台输出_this.intervalList after的值是为undefinded,在_this.intervalList before输出intervalList的内容。结果如下图所示。

image.png

同样的变量在不同位置输出的结果不一样,原因只能有一个,就是两个this表示不同的对象。这里需要引入一个知识点,=>与function()匿名方法的区别。

=>与function()匿名方法的区别

function匿名函数this指向运行时实际调用该方法的对象。
=>没有自己的this,这里this在编写时已经确定的,根据vue官方文档得知,生命周期钩子的 this 上下文指向调用它的 Vue 实例。根据它们的区别,有两种解决方案

方案一:在removeRemoteVideo方法内部使用统一的this对象,在removeRemoteVideo内部声明,在addEventListener方法内部使用。

removeRemoteVideo:function (pullId) {
    let newRemoteVideo = document.getElementById("remote-video-" + pullId);
    console.log("newRemoteVideo",newRemoteVideo);
    let _this = this;
    console.log(" _this.pullStreamList before", _this.pullStreamList);

    newRemoteVideo.addEventListener("play",function () {
        console.log(" _this.pullStreamList after", _this.pullStreamList);
    })
}

方案二:将addEventListener对应的第二个参数修改为 "() => {}"

removeRemoteVideo:function (pullId) {
    let newRemoteVideo = document.getElementById("remote-video-" + pullId);
    console.log("newRemoteVideo",newRemoteVideo);
    console.log(" _this.pullStreamList before", this.pullStreamList);

    newRemoteVideo.addEventListener("play",() => {
        console.log(" _this.pullStreamList after", this.pullStreamList);
    })
}
测试结果

image.png


杨帆
28 声望3 粉丝