vue 渲染后动态添加属性及方法 addEventListener extend

1动态添加属性

<template>
 <div>

<button class='app-share' @click="share" ></button>
 </div>
</template>
<script>
 export default {
   name:'shareIcon',
   data() {
    return {
      obj:{},
    };
  },
   components: {

   },
   methods:{
     share(){
     //方法一 类似 Object.assign()
     this.$set(this.obj,'name','zs')
      // 方法二 强制刷新
      //this.obj.name='lis'
     //this.$forceUpdate()//重新渲染 赋值组件
}
}
 }
</script>

<style lang='scss' scoped>

</style >

2动态监听
事件拖管

  <div class="content">
      <div  @click="audioplay($event)" v-html="detail.content"></div>
    </div>
 var str = `
             <div class="pride-audio">
                <div class="pride-audio-title">${audio[i].parentNode.previousElementSibling.innerHTML}</div>
                <div class="pride-audio-subhead-title">来自好尔美健康管理语音版</div>
                <div class="pride-audio-content">
                <div class="pride-audio-progress">
                    <div class="pride-audio-progress-percent"></div>
                    <div class="pride-audio-progress-time">
                        <span>04:25</span> 16:45
                    </div> 
                </div>
                <img class="pride-audio-icon" data-audio=${audio[i].src} @click='xxx' src="${audioicon}" alt="">
              </div>
               <audio src="${audio[i].src}" ></audio>
            </div>`;
             audio[i].parentNode.innerHTML = str;

//addEventListener 事件监听 //e.target.dataset 自己 
//this === e.currentTarget 总是为true
//this === e.target 有可能不是true

 audioplay(e) {
        audioplay(e) {
      // console.log(e.target.dataset);
      let audiosrc=e.target.dataset.audio
      let audio=new Audio()
      audio.src=audiosrc
      audio.play()
    }

    }

方式二(事件拖管)

 var str = `
             <div class="pride-audio">
                <div class="pride-audio-title">${audio[i].parentNode.previousElementSibling.innerHTML}</div>
                <div class="pride-audio-subhead-title">来自好尔美健康管理语音版</div>
                <div class="pride-audio-content">
                <div class="pride-audio-progress">
                    <div class="pride-audio-progress-percent"></div>
                    <div class="pride-audio-progress-time">
                        <span>04:25</span> 16:45
                    </div> 
                </div>
                <img class="pride-audio-icon" index='${i}' data-audio=${audio[i].src}  src="${audioicon}" alt="">//click='clicks()'不能使用是 vue将原始事件禁止了
              </div>
              <audio id='${i}' src="${audio[i].src}" ></audio>
            </div>`;
             audio[i].parentNode.innerHTML = str;
                document.getElementsByClassName(
              "pride-audio-icon"
            )[0].onclick = function(e) {
              console.log(e.target.getAttribute("index"), "e---------");
              let id = e.target.getAttribute("index");

              let audio = document.getElementById(id);
              audio.play();
            };

方式三(事件拖管)

 var str = `
             <div class="pride-audio">
                <div class="pride-audio-title">${audio[i].parentNode.previousElementSibling.innerHTML}</div>
                <div class="pride-audio-subhead-title">来自好尔美健康管理语音版</div>
                <div class="pride-audio-content">
                <div class="pride-audio-progress">
                    <div class="pride-audio-progress-percent"></div>
                    <div class="pride-audio-progress-time">
                        <span>04:25</span> 16:45
                    </div> 
                </div>
                <img class="pride-audio-icon" index='${i}' data-audio=${audio[i].src}  src="${audioicon}" alt="">//click='clicks()'不能使用是 vue将原始事件禁止了
              </div>
              <audio id='${i}' src="${audio[i].src}" ></audio>
            </div>`;
             audio[i].parentNode.innerHTML = str;
            window.clicks = function() {            
              let id = x+'';

              let audio = document.getElementById(id);
              audio.play();
            };

              let audio = document.getElementById(id);
              audio.play();
            };
            };

vue enxe

  
<template>

    <div class="content">
      <div v-html="detail.content"></div>
    </div>

</template>
<script>
import Util from "../libs/util";

var audioicon = require("@/assets/image/message/audioicon.png");
var audioplay = require("@/assets/image/message/audio.gif");
import priaudio from "@/components/priaudio/priaudio.js";
export default {
  data() {
    return {
      // isWxmp: this.$util.isWxmp(),
      isshare: true,
      detail: {}
    };
  },

  components: {},
  methods: {
    //详情
    pageData() {
      this.$http
        .request({
          url: "/ajax/user/wx/information/detail",
          method: "get",
          params: {
            contentId: this.contentId
          }
        })
        .then(res => {
          console.log(res);
          if (res && res.respBody) {
            let detail = res.respBody.content;
            res.respBody.content = detail;
            this.detail = res.respBody;

            Util.share({
              type: "message", // 类型
              title: this.detail.title, // 标题
              imageUrl: this.detail.coverPicUrl // 图片
            });
            this.dealhtml();
          }
        });
    },
    // 点赞

   
    // html 样式处理
    dealhtml() {
      this.$nextTick(() => {
        let audio = document.querySelectorAll("audio");
        let audioarr = [];
        if (audio) {
          for (var i = 0; i < audio.length; i++) {
            audio[i].parentNode.previousElementSibling.style.color =
              "transparent";
            priaudio.aa(audio, i,audioplay , audioicon);
             var MyComponent = Vue.extend({
               template: `
              <div class="pride-audio">
                 <div class="pride-audio-title">${audio[i].parentNode.previousElementSibling.innerHTML}</div>
                 <div class="pride-audio-subhead-title">来自好尔美健康管理语音版</div>
                 <div class="pride-audio-content">
                 <div class="pride-audio-progress">
                     <div class="pride-audio-progress-percent" :style="{width:precent}"></div>
                     <div class="pride-audio-progress-time">
                         <span>{{currentTime|duration}}</span> <span>{{duration|duration}}</span>
                     </div>
                 </div>
                 <img class="pride-audio-icon"  @click='clicks(${i})'  :src="isaudio" alt="">
               </div>
                <audio id='${i}' ref='xx' src="${audio[i].src}" ></audio>
             </div>`,
               data() {
                 return {
                   showaudio: false,
                   duration: 0,
                   currentTime: 0,
                   precent: 0,
                   audiolock: false
                 };
               },

               methods: {
                 clicks: function(id) {
                   if (this.audiolock) {
                     // 播放
                     this.$refs.xx.pause();
                     this.audiolock = false;
                     this.showaudio = false;
                     return;
                   }
                   let lock = null;
                   // 播放
                   this.$refs.xx.play();
                   this.audiolock = true;
                   //监听播放了
                   this.$refs.xx.addEventListener("play", e => {
                     this.showaudio = true;
                   });
                   //时间函数
                   this.$refs.xx.addEventListener("timeupdate", e => {
                     if (lock) {
                       return;
                     }
                     lock = setTimeout(() => {
                       this.currentTime = this.$refs.xx.currentTime;
                       this.precent = `${(
                         this.currentTime / this.duration
                       ).toFixed(3) * 100}%`;
                       lock = null;
                     }, 1000);
                   });
                    //监听播放了
                   this.$refs.xx.addEventListener("pause", e => {
                     this.currentTime=0
                     this.audiolock = false;
                     this.showaudio = false;
                   });
                 }
               },
              filters: {
                duration(val) {
                   if (val) {
                     let duration = Math.round(val);
                     let minute = Math.floor(duration / 60);
                     let second = duration % 60;
                     return [minute, second].map(fn).join(":");
                     function fn(n) {
                       n = n.toString();
                       return n[1] ? n : "0" + n;
                     }
                   } else {
                     return "00:00";
                   }
                 }
               },
               computed: {
                 isaudio() {
                   return this.showaudio ? audioplay : audioicon;
                 }
               },
               mounted() {
                 this.$refs.xx.addEventListener("canplay", () => {
                   this.duration = this.$refs.xx.duration;
                   this.currentTime = this.$refs.xx.currentTime;
                 });
               }
             });

             var component = new MyComponent().$mount();
             audio[i].parentNode.replaceChild(component.$el, audio[i])
             document.getElementById("edituser").appendChild(component.$el);
          }
        }
      });
    }
  },
  created() {
    this.contentId = this.$route.query.id || 408;
    this.pageData();
  },
  mounted() {}
};
</script>
<style lang='scss' scoped>
@import "src/style/mixin";

.content {
  padding: 0 rem(36);
  & > div {
    width: 100%;
  }
  & >>> audio {
    background-color: #f00;
  }
}


</style>

参考:https://cn.vuejs.org/v2/api/#vm-mount
参考:https://www.jianshu.com/p/398825b673e7
方式四
创建vue 组件

//priaudio.vue

<template>
  <div>
    <div class="pride-audio">
      <div class="pride-audio-title">{{title}}</div>
      <div class="pride-audio-subhead-title">来自...管理语音版</div>
      <div class="pride-audio-content">
        <div class="pride-audio-progress">
          <div class="pride-audio-progress-percent" :style="{width:precent}"></div>
          <div class="pride-audio-progress-time">
            <span>{{currentTime|duration}}</span>
            <span>{{duration|duration}}</span>
          </div>
        </div>
        <img class="pride-audio-icon" @click="clicks()" :src="isaudio" alt />
      </div>
      <audio id="${i}" ref="xx" :src="audio[i].src"></audio>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showaudio: false,
      duration: 0,
      currentTime: 0,
      precent: 0,
      audiolock: false
    };
  },
  methods: {
    clicks: function(id) {
      if (this.audiolock) {
        // 播放
        this.$refs.xx.pause();
        this.audiolock = false;
        this.showaudio = false;
        return;
      }
      let lock = null;
      // 播放
      this.$refs.xx.play();
      this.audiolock = true;
      //监听播放了
      this.$refs.xx.addEventListener("play", e => {
        this.showaudio = true;
      });
      //时间函数
      this.$refs.xx.addEventListener("timeupdate", e => {
        if (lock) {
          return;
        }
        lock = setTimeout(() => {
          this.currentTime = this.$refs.xx.currentTime;
          this.precent = `${(this.currentTime / this.duration).toFixed(3) *
            100}%`;
          lock = null;
        }, 1000);
      });
      //监听播放了
      this.$refs.xx.addEventListener("pause", e => {
        this.currentTime = 0;
        this.audiolock = false;
        this.showaudio = false;
      });
    }
  },
  filters: {
    duration(val) {
      if (val) {
        let duration = Math.round(val);
        let minute = Math.floor(duration / 60);
        let second = duration % 60;
        return [minute, second].map(fn).join(":");
        function fn(n) {
          n = n.toString();
          return n[1] ? n : "0" + n;
        }
      } else {
        return "00:00";
      }
    }
  },
  computed: {
    isaudio() {
      return this.showaudio ? this.audioplay : this.audioicon;
    },
    title() {
      return this.audio[this.i].parentNode.previousElementSibling.innerHTML;
    }
  },
  mounted() {
    console.log(this.audio, "this.audio");
    this.$refs.xx.addEventListener("canplay", () => {
      this.duration = this.$refs.xx.duration;
      this.currentTime = this.$refs.xx.currentTime;
    });
  }
};
</script>

<style lang="scss" scoped>
@import "src/style/mixin";

.pride-audio {
  width: rem(672);
  height: rem(200);
  background-color: #f9f9f9;
  border-radius: rem(16);
  padding: 0 rem(30);
  box-sizing: border-box;

  .pride-audio-title {
    height: rem(78);
    line-height: rem(78);
    font-size: rem(32);
    color: #323232;
    white-space: nowrap;
    /* text-emphasis: none; */
    text-overflow: ellipsis;
    overflow: hidden;
    text-align: left;
  }

  .pride-audio-subhead-title {
    text-align: left;
    color: #979797;
    font-size: rem(22);
  }

  .pride-audio-content {
    height: rem(70);
    display: flex;
    align-items: center;
    justify-content: space-between;
    .pride-audio-progress {
      width: rem(504);
      height: rem(6);
      background-color: #999;
      position: relative;
      .pride-audio-progress-percent {
        position: absolute;
        left: 0;
        top: 0;
        height: 100%;
        width: 0;
        background-color: #03020c;
      }

      .pride-audio-progress-percent::before {
        content: "";
        position: absolute;
        right: 0;
        top: 50%;
        margin-top: rem(-5);
        width: rem(10);
        height: rem(10);
        border-radius: 50%;
        background-color: #03020c;
      }

      .pride-audio-progress-time {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: rem(60);
        display: flex;
        align-items: center;
        justify-content: space-between;
      }
    }

    .pride-audio-icon {
      width: rem(72);
      height: rem(72);
    }
  }
}
</style>


       

import Vue from "vue";
import priaudio from "./priaudio.vue";

const MyComponent = Vue.extend(priaudio);
priaudio.aa = function (audio, i, audioplay, audioicon) {
  console.log(audio, "audio");
  let data = {
    audio: audio, //音频标签
    i: i, //索引,
    audioplay: audioplay,
    audioicon: audioicon,
  };
  var component = new MyComponent({ data }).$mount();
  audio[i].parentNode.replaceChild(component.$el, audio[i]);
};

export default priaudio;

参考 https://editor.csdn.net/md/?articleId=106473100

import Vue from 'vue'
import Popup from './share.vue'

const PopupBox = Vue.extend(Popup)

Popup.install = function () {
  let data = {
   imgUrl: require("@/assets/image/message/share.png"), // 顶部图片
  };

  let instance = new PopupBox({
    data
  }).$mount();

  document.body.appendChild(instance.$el)

  Vue.nextTick(() => {
    instance.show = true
    // show 和弹窗组件里的show对应,用于控制显隐
  })
}

export default Popup

使用

import priaudio from "@/components/priaudio/priaudio.js";
priaudio.aa(audio, i,audioplay , audioicon);
  mounted() {
    console.log(this.arr);
    this.arr.forEach(element => {
      var MyComponent = Vue.extend({
        template: `<img ref="oimg" :src="img">`,
        data() {
          return {
            img: element
          };
        },
        methods: {},
        mounted() {
          this.$nextTick(() => {
            let turnwidth = 316;
            let turnheight = 186;
            let canvas = document.createElement("canvas");
            let ctx = canvas.getContext("2d");

            canvas.width = turnwidth;
            canvas.height = turnheight;
              this.$refs.oimg.crossOrigin = "Anonymous";
            ctx.drawImage(this.$refs.oimg, 0, 0, turnwidth, turnheight);
            let dataURL = canvas.toDataURL("image/png", 1);
            console.log(dataURL, "dataURL");
          });
        }
      });
      var component = new MyComponent().$mount();
      document.getElementById("edituser").appendChild(component.$el);
    });
  }
 var MyComponent = Vue.extend({
        template: `<div id="dom" class='food_content' :style="{backgroundImage:'url('+img+')'}" >
           <div class='food_line' v-for="(item,index) in lsit" :key="index">
              <img class='food_icon' :src='food_icon' /> 早餐:花生赤豆羹+豆浆+豆腐干+黄瓜
           </div>
        </div>`,
        data() {
          return {
            img: element,
            food_icon: food_icon,
            lsit: [1, 2, 3]
          };
        },
        methods: {},
        mounted() {
          let dom = document.getElementById("dom");
          html2canvas(dom, {
            width: dom.offsetWidth,
            height: dom.offsetHeight,
            scale: 0.1,
            useCORS: true
          }).then(canvas => {
            let url = canvas.toDataURL("image/png", 1);
            console.log(url, "url");
          });
        }
      });
      var component = new MyComponent().$mount();
      document.getElementById("edituser").appendChild(component.$el);
  1. video 层级最高 不能使用事件委托
  2. video 不能使用 标签事件
  3. 蒙尘 替换
    // video 标签替换
    videohtml() {
      let video = document.querySelector("video");
      var MyComponent = Vue.extend({
        template: `<div>
        <div class="masking"  @click="payclick('video')"></div>
        <video
        id="zz"
        controls
        poster
        preload
        src="${video.src}"
      ></video>
      </div> `,
          data() {
          return {};
        },
        methods: {
          payclick() {
            let video = document.querySelector("video");
            // 通过全局api 进行操作
            let paly = document.getElementsByClassName("video-model")[0];
            video.pause();
            paly.style.display = "flex";
          },
        },
      });
      var component = new MyComponent({
        data: {
          ispaly: this.ispaly,
        },
      }).$mount();
      video.parentNode.replaceChild(component.$el, video);
      // let odiv = document.createElement("div");
      // odiv.innerHTML = videostr;
      // video.parentNode.innerHTML = videostr;
    },
   payclick(type) {
      let video = document.querySelector("video");
      if (type == "play") {
        video.play();
        // 通过全局api 进行操作
        this.$refs.paly.style.display = "none";
      }
    },
  },
  created() {
    console.log(this.$route.query)
  },
  mounted() {
    // 样式格式化
    this.videohtml();
     let video = document.querySelector("video");
  },
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

web修理工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值