简体   繁体   English

从 Chrome 扩展访问 Vue 组件方法

[英]Accessing Vue component methods from Chrome Extension

I'm building a chrome extension for an specific page: https://www.vidangel.com/ .我正在为特定页面构建 chrome 扩展: https://www.vidangel.com/

I don't own the page, but inspecting it, I can see it's built on Vue.我不拥有该页面,但检查它,我可以看到它是基于 Vue 构建的。 I need to read a specific information that the page uses multiple times, which is accessed trough a method called "getActiveTags" (in case anyone will bother looking at the bundle file https://www.vidangel.com/js/app.25e52655.js ).我需要阅读该页面多次使用的特定信息,该信息通过一种名为“getActiveTags”的方法访问(以防有人会费心查看捆绑文件https://www.vidangel.com/js/app.25e52655 .js )。 It is a method in one of the Vue components:它是 Vue 组件之一中的一个方法:

<template>
      <div class="lineup-barvisual">
        <div class="lineup-barvisual-panel">
          <div class="lineup-barvisual-title">You'll see</div>
          <svg>
            <defs>
              <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
                <stop class="stop-start" offset="0%" />
                <stop class="stop-end" offset="100%" />
              </linearGradient>
            </defs>
            <rect class="backdrop"></rect>
            <g v-if="tag_set && lineup">
              <rect class="cuts" v-for="tag in getActiveAudioTags()" :key="tag.id" :x="tagLeft(tag)" :width="tagWidth(tag)"/>
            </g>
          </svg>
        </div>
        <div class="lineup-barvisual-panel">
          <div class="lineup-barvisual-title">You'll hear</div>
          <svg>
            <rect class="backdrop"></rect>
            <g v-if="tag_set && lineup">
              <rect class="cuts" v-for="tag in getActiveTags()" :key="tag.id" :x="tagLeft(tag)" :width="tagWidth(tag)" />
            </g>
          </svg>
        </div>
      </div>
    </template>
    
    <script>
      import api from 'services/api'
      export default {
        props: ['tag_set', 'lineup'],
        methods: {
          tagLeft(tag) {
            return ((tag.start_approx / this.lineup.work.duration) * 100) + '%'
          },
          tagWidth(tag) {
            return Math.max((((tag.end_approx - tag.start_approx) / this.lineup.work.duration) * 100), 0.075) + '%'
          },
          getActiveTags() {
            return this.tag_set.tags.filter(tag => this.lineup.isTagOn(tag))
          },
          getActiveAudioTags() {
            return this.getActiveTags().filter(tag => tag.type === 'audiovisual')
          },
          paint() {
            this.$forceUpdate()
          }
        },
        watch:{
          'lineup.id'(id, old_id) {
            api.hub.$off(`model.lineup.${old_id}.touched`, this.paint)
            if (id) api.hub.$on(`model.lineup.${id}.touched`, this.paint)
          }
        },
        beforeDestroy() {
          if (this.lineup) {
            api.hub.$off(`model.lineup.${this.lineup.id}.touched`, this.paint)
          }
        }
      }
    </script>

I couldn't figure out where these 'tag_set' and 'lineup' props come from (I don't have a great Vue knowledge), but they seem to be related to this:我不知道这些 'tag_set' 和 'lineup' 道具来自哪里(我没有很好的 Vue 知识),但它们似乎与此有关:

import api from 'services/api'从“服务/api”导入 api

let TagSet = api.defineResource({
  name: 'TagSet',
  endpoint: 'tag-sets',
  relations: {
    belongsTo: {
      CatalogItem: {
        localField: 'work',
        localKey: 'work_id'
      }
    },
    hasMany: {
      Tag: {
        localField: 'tags',
        foreignKey: 'tag_set_id'
      }
    }
  },
  methods: {
    tags_count() {
      return this.tags.length
    },
    tags_active(lineup) {
      return this.tags.filter(t => lineup.refmap[t.ref_id])
    },
    tags_active_count(lineup) {
      return this.tags_active(lineup).length
    }
  },
  watchChanges: false
})

api.defineResource({
  name: 'Tag',
  relations: {
    belongsTo: {
      TagCategory: {
        localField: 'category',
        localKey: 'category_id'
      }
    }
  }
})

export default TagSet

Though I have no idea how this works.虽然我不知道这是如何工作的。 I suppose the tagset information is stored in some kind of redux object, because it is accessed from multiple components.我想标签集信息存储在某种 redux object 中,因为它是从多个组件访问的。

The current solution I'm using is to override the bundle file with declarativeNetRequest, with a slightly modified script, which includes in the getActiveTags method a small bit of code that creates or updates an invisible span on the DOM, which has as it's InnerText a strigfied version of the return value of getActiveTags:我正在使用的当前解决方案是使用 declarativeNetRequest 覆盖捆绑文件,并使用稍微修改的脚本,该脚本在 getActiveTags 方法中包含一小段代码,用于创建或更新 DOM 上的不可见跨度,因为它是 InnerText getActiveTags 的返回值的严格版本:

    getActiveTags: function () {
        var t = this;
        let tags = this.tag_set.tags.filter(e => t.lineup.isTagOn(e));
        let tagsMap = tags.map(tag => ({begin: tag.begin, end: tag.end}));
        let elemento = document.getElementById('lista-tags');
        if (!elemento) {
          elemento = document.createElement('span');
          elemento.id = 'lista-tags';
          elemento.style = 'display: none';
          document.body.appendChild(elemento);
        }
        elemento.innerText = JSON.stringify(tagsMap);
        return tags;

I have tried to add the "getActiveTags" method to the global window object, which became accessible on dev tools, but couldn't be accessed from the extension code, even at contentScript (I don't know why).我尝试将“getActiveTags”方法添加到全局 window object,它可以在开发工具上访问,但无法从扩展代码访问,即使在 contentScript 中也是如此(我不知道为什么)。 But even that solution being better, it's still problematic, because I have to keep a copy of the bundle saved with theses modifications, so the user could be seeing an outdated version of the page, in case the original page makes modifications.但即使该解决方案更好,它仍然存在问题,因为我必须保留与这些修改一起保存的捆绑包的副本,因此用户可能会看到页面的过时版本,以防原始页面进行修改。

So what I would really want is a way to access from the window object, the method of the vue component defined by the original script, without having to override the bundle.所以我真正想要的是一种从原始脚本定义的vue组件的方法window object访问的方法,而不必重写捆绑包。 Is there a way to achieve that?有没有办法做到这一点? How would I go about finding the vue component?我将如何 go 关于找到 vue 组件? (I have tried for a long time inspecting the window object on dev tools, without finding the vue components.) Thank you. (我已经尝试在开发工具上检查 window object 很长时间,但没有找到 vue 组件。)谢谢。

I figured it out after a long time.很久之后我才明白。 You can access vue components methods by the.__vue__ object of the element.您可以通过元素的.__vue__ object 访问vue组件方法。 So, in my case I had to do:所以,就我而言,我必须这样做:

document.querySelector('.lineup-barvisual').__vue__.getActiveTags()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM