美文网首页
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