美文网首页
use vue-web-extension to build c

use vue-web-extension to build c

作者: GoddyWu | 来源:发表于2019-07-10 11:05 被阅读0次

Accidentally, I need to build a chrome plugin. This plugin require to post its data(source html) to restful api and also get data from api. In short, this blog will help u build a chrome plugin project using these tech stack:

  • vue
  • element ui / iview
  • additionally, this plugin can get source html file from the visiting tab page

code repo: https://gitlab.com/goddy-test/public/vue-web-extesion-bp

1. init project

You can follow the official documentation steps.

$ vue init kocal/vue-web-extension tmp2

And I choose these...

? Project name tmp2
? Project description A Vue.js web extension
? Author goddy <wuchuansheng@yeah.net>
? License 
? Use Mozilla's web-extension polyfill? (https://github.com/mozilla/webextension-polyfill) No
? Provide an options page? (https://developer.chrome.com/extensions/options) Yes
? Install vue-router? No
? Install vuex? No
? Install axios? Yes
? Install ESLint? No
? Install Prettier? No
? Automatically install dependencies? no

Then install the node modules.

$ cd my-extension
# In China, use cnpm is better.
$ npm install

2. build & run with hot-loading

$ npm run build:dev
$ npm run watch:dev

3. load plugin

open chrome://extensions/ use your chrome.

make sure you have open 'developer model', then click 'load unpacked plugin'. Then the plugin will alert 'Hello world!'.

4. add element-ui

# you can use cnpm instead of npm
$ npm i element-ui -S

then, edit src/popup/popup.js into this

import Vue from 'vue'
import App from './App'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(ElementUI)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  render: h => h(App)
})

add some element-ui to src/popup/App.vue

<template>
  <div>
    <p>Hello world!</p>
    <el-button type="danger" icon="el-icon-delete" circle />
    <el-avatar src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" />
  </div>
</template>

<script>
export default {
  data () {
    return {}
  }
}
</script>

<style lang="scss" scoped>
p {
  font-size: 20px;
}
</style>
reload plugin, you can see this、!

you can also add iview in the same way.

5. config global axios

axios is a 'Promise based HTTP client for the browser and node.js'. I use it instead of ajax. Config a global axios may be best practice.
new build src/js/axios.js, insert below code:

/*
 * Reference:
 *  https://blog.csdn.net/baidu_38492440/article/details/78193766
 */

import axios from 'axios'
import qs from 'qs'

# change to yours
let _BASE_URL = 'http://118.31.52.226/chromit'

# if u r using cookies, set true
axios.defaults.withCredentials=true

// 请求方式的配置
export default {
    post(url, data) {  //  post
        return axios({
            method: 'post',
            baseURL: _BASE_URL,
            url,
            data: qs.stringify(data),
            timeout: 5000,
            headers: {
                'X-Requested-With': 'XMLHttpRequest',
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
            }
        })
    },
    get(url, params) {  // get
        return axios({
            method: 'get',
            baseURL: _BASE_URL,
            url,
            params, // get 请求时带的参数
            timeout: 5000,
            headers: {
                'X-Requested-With': 'XMLHttpRequest'
            }
        })
    }
}

For easy to import, we give an alias to the path src, edit webpack.config.js:

  resolve: {
    extensions: ['.js', '.vue'],
    alias: {
      '@': __dirname + '/src'
    }
  },

add these into src/popup/popup.js

import axios from '@/js/axios.js'
Vue.prototype.$axios = axios

ok, done. When you want to request restful api,

# get
this.$axios.get('http://118.31.52.226/chromit/username')
.then(res => {
  console.log(res.data)
}).catch(error => {
  console.log('some error info')
})
# post
this.$axios.post('http://118.31.52.226/chromit/login', {
   username: 'goddy',
   password: 'something'
}).then(res => {
  console.log(res.data)
}).catch(error => {
  console.log('some error info')
})

6. get source html

If you don't use vue to create chrome plugin, just follow steps of this blog: https://stackoverflow.com/questions/11684454/getting-the-source-html-of-the-current-page-from-chrome-extension?answertab=votes#tab-top
But how to mix above method with vue-web-extension、? PAEz also provide a way: https://github.com/PAEz/QtTabBar-Scripts/issues/1

In my way, I create src/popup/getPagesSource.js

function DOMtoString(document_root) {
  var html = '',
      node = document_root.firstChild;
  while (node) {
      switch (node.nodeType) {
      case Node.ELEMENT_NODE:
          html += node.outerHTML;
          break;
      case Node.TEXT_NODE:
          html += node.nodeValue;
          break;
      case Node.CDATA_SECTION_NODE:
          html += '<![CDATA[' + node.nodeValue + ']]>';
          break;
      case Node.COMMENT_NODE:
          html += '<!--' + node.nodeValue + '-->';
          break;
      case Node.DOCUMENT_TYPE_NODE:
          // (X)HTML documents are identified by public identifiers
          html += "<!DOCTYPE " + node.name + (node.publicId ? ' PUBLIC "' + node.publicId + '"' : '') + (!node.publicId && node.systemId ? ' SYSTEM' : '') + (node.systemId ? ' "' + node.systemId + '"' : '') + '>\n';
          break;
      }
      node = node.nextSibling;
  }
  return html;
}

chrome.runtime.sendMessage({
  action: "getSource",
  source: DOMtoString(document)
});

then, edit webpack.config.js

# add it to CopyWebpackPlugin
{ from: 'popup/getPagesSource.js', to: 'popup/getPagesSource.js'},

# or change your entry into this
  entry: {
    'background': './background.js',
    'popup/popup': './popup/popup.js',
    'options/options': './options/options.js',
    # add this
    'getPagesSource': './popup/getPagesSource.js'
  },

add these into src/popup/popup.js

function onWindowLoad() {
  chrome.tabs.executeScript(null, {
    file: "getPagesSource.js"
  }, () => {
    // If you try and inject into an extensions page or the webstore/NTP you'll get an error
    if (chrome.runtime.lastError) {
      console.log('There was an error injecting script : \n' + chrome.runtime.lastError.message)
    }
  });
}

window.onload = onWindowLoad;

edit src/manifest.json to give plugin permissions.

"permissions": ["tabs", "<all_urls>"]

add these into src/popup/App.vue

  beforeCreate() {
    chrome.runtime.onMessage.addListener(function(request, sender) {
      if (request.action == "getSource") {
        console.log(request.source)
      }
    });
  },
then rebuild plugin, you can see..

I seems working well now. Thanks to Kocal and PAEz.

Reference

相关文章

网友评论

      本文标题:use vue-web-extension to build c

      本文链接:https://www.haomeiwen.com/subject/vvohkctx.html