Vue开发移动端项目,这个工具对你一定有帮助-LMLPHP

转载自:OmniDebug

https://juejin.cn/post/6949433236787298335

  • 1. 剥离front

    首先一个问题就是 Vue-devtools并不是一个库,所以npm上没有它,无法引用,其次这个工程也不适合作为库输出,因为它的打包方式比较特殊,还有这个工程本身的目的就是打包成一个可执行的App或者chrome插件,所以如果想引用它里面的代码,我想到最简单的方式就是拷贝了。。。所以剥离frontend非常简单,在Vue-devtools工程的package.json中增加script:"buildvc": "cd packages/shell-dev && cross-env NODE_ENV=production webpack \--progress \--hide-modules", 同时在shell-dev里增加一个文件叫 inject.js:

    import { initDevTools } from '@front'
    import Bridge from '@utils/bridge'

    const targetWindow = window.parent;
    document.body.style.overflow = "scroll";
    initDevTools({
      connect (cb) {
        cb(new Bridge({
          listen (fn) {
            window.addEventListener('message', evt => {
              fn(evt.data)
            })
          },
          send (data) {
            targetWindow.postMessage(data, '*')
          }
        }))
      },
      onReload (reloadFn) {
        reloadFn.call();
      }
    })

    当然shell-dev里的webpack.config.js里 增加一个入口配置 inject: './src/inject.js'

    打出来的包就是我们要的front部分,最终嵌入iframe里。

    2. 实现通信

    上面的inject.js中已经包含了 front部分 接收和发送消息的代码了。接下来完成backend部分的消息发送和接收,

    import { initBackend } from '@back'
    import Bridge from '@utils/bridge'

    const initBackendWithTargetWindow = function(win,targetWindow){
      const bridge = new Bridge({
        listen (fn) {
          win.addEventListener('message', evt => {
            fn(evt.data)})
        },
        send (data) {
          targetWindow.postMessage(data, '*')
        }
      })
      
      initBackend(bridge)
    }

    export default { initBackendWithTargetWindow }

    3. front嵌入iframe

    这个比较麻烦,也遇到了一些兼容性问题,最终方案是:

    import injectString from './inject.txt'

    function inject (scriptContent, done{
      const script = document.getElementById('vue-iframe').contentWindow.document.createElement('script')
      script.text = scriptContent
      document.getElementById('vue-iframe').contentWindow.document.body.appendChild(script)
    }

    inject(injectString)

    4. iframe嵌入vconsole

    实现一个plugin类,继承VConsolePlugin,然后实现对应的方法即可,具体文档可以查看VConsole文档vConsole Readme

    class VConsoleVueTab extends VConsolePlugin {

      constructor(...args) {
        super(...args);
      }
      onRenderTab(cb){
        cb(`<iframe id="vue-iframe" style="width:100%;position:absolute;top:0;bottom:0;min-height:100%;"></iframe>`);
      }
      onReady() {
        target = document.getElementById('vue-iframe')
        targetWindow = target.contentWindow;
        be.initBackendWithTargetWindow(window,targetWindow);    
      }

      onShow() {    
        injectOnce(injectString)
      }
    }

    5. 制作npm包并发布

    这一步需要打包发布,并且优化

    const initPlugin = function(vConsole){
      var tab = new VConsoleVueTab('vue''Vue');
      vConsole.addPlugin(tab);
    }
    export default {
      initPlugin
    }

    最后

    本文分享自微信公众号 - 前端瓶子君(pinzi_com)。
    如有侵权,请联系 [email protected] 删除。
    本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

    04-20 15:14