原生的JS中给元素绑定点击事件是通过操作DOM,获取到这个元素,然后通过addEventListener来绑定点击事件,在Vue中不推荐操作DOM的这种方式,由于是动态生成的元素通过@click是没有效果的,那么有什么方式可以实现相同效果呢?

/** 这里利用了事件总线,代码如下:*/

const install = function (Vue) {

         const Bus = new Vue({

         methods: {

                  emit (event, ...args) {

                  this.$emit(event, ...args);

          },

            on (event, callback) {

                   this.$on(event, callback);

            },

            off (event, callback) {

                  this.$off(event, callback);

            }

        }

    });

    Vue.prototype.$bus = Bus;

    window.window$BUS = (event, ...args) => {        //主要代码

            Bus.$emit(event, ...args);

    };

};

Date.prototype.Format = function (fmt) {

        var o = {

              "y+": this.getFullYear(),                //年

              "M+": this.getMonth() + 1,                 //月份

              "d+": this.getDate(),                    //日

              "h+": this.getHours(),                   //小时

             "m+": this.getMinutes(),                 //分

             "s+": this.getSeconds(),                 //秒

             "q+": Math.floor((this.getMonth() + 3) / 3), //季度

             "S": this.getMilliseconds()             //毫秒

       };

    if (/(y+)/.test(fmt)) {

        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));

    }

    for (var k in o) {

        if (new RegExp("(" + k + ")").test(fmt)) {

            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));

        }

    }

    return fmt;

};

String.prototype.splice = function(start, newStr) {

    return this.slice(0, start) + newStr + this.slice(start);

};

export default install;

在window 对象上定义了一个方法,名为window$BUS,这个方法接收两个参数,第一个就是事件对象,第二个是一个...args意思是允许我们传多个参数。

定义好后使用方法如下:

  let str = '<div class="layerInformation-title">事件详情</div>' +

          '<div style="width: calc(100% - 20px);height: 200px;padding: 10px;">' +

          '<img src="'+ url +'" style="width: 100%;height: 100%;cursor:pointer;" οnclick="window$BUS(\'enlargePicture\',\'' + dataStr + '\')" />' +

          '</div>' +

          '<div class="layerInformation" style="width:460px;">' +

          '<span style="width: 50%;float: left;">所属单位:' + data.deptName + '</span>' +

          '<span style="width: 50%;float: left;">处理人:' + (data.conductor || '') + '</span>' +

          '<span style="width: 50%;float: left;">事件状态:' + this.treatmentFormatter({}, {}, data.treatmentState) + '</span>' +

          '<span style="width: 50%;float: left;">事件名称:' + data.eventName + '</span>' +

          '<span style="width: 50%;float: left;">事件类型:' + this.eventTypeFormatter({}, {}, data.eventType) + '</span>' +

          '<span style="width: 50%;float: left;">事件等级:' + this.eventGradeFormatter({}, {}, data.eventGrade) + '</span>' +

          '<span style="width: 50%;float: left;">经度:' + data.longitude + '</span>' +

          '<span style="width: 50%;float: left;">纬度:' + data.latitude + '</span>' +

          '<span style="width: 50%;float: left;">采集地点:' + data.gatheringPlaceName + '</span>' +

          '<span style="width: 50%;float: left;">上报人员:' + data.reportPersonnel + '</span>' +

          '<span style="width: 50%;float: left;">上报时间:' + data.reportTime + '</span>' +

          '<span style="width: 100%;float: left;">事件描述:' + data.incidentDescription + '</span>'

          '</div>'

这里通过onclick点击事件来触发 window$BUS方法,并且抛出事件对象,最后执行Bus.$emit(event, ...args),所以我们需要通过 this.$bus.on('enlargePicture', (odata)=>{let data = JSON.parse(decodeURI(odata));})来监听抛出的数据;

/**注意事项*/

这里直接获取的odata 是通过utf-8编码后的数据,需要通过decodeURI来进行解析,得到的是一个字符串对象,使用JSON.parse转成对象;

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐