一、问题

之前写过一篇文章,关于 weex 的内置组件 picker,主要描述了 weex picker 组件的使用方式。

不过在使用的时候,遇到了一个问题,就是 picker 组件在 web 端的使用出现问题。

文章地址:

为了解决这个问题,我提了一个 issue :

二、解决问题

官方给出的三端兼容,只是一段描述:

如果需要同时三端支持 picker,需要在引入 weex-vue-render 后再引入 weex-picker

在代码上的引入顺序其实是这样子:

import Vue from 'vue'
import weex from 'weex-vue-render'
import WeexPicker from '@weex-project/weex-picker'

1、错误的解决方法

issue 的回答中,给出的第一个解决办法实际上和我在这篇文章中的解决方式差不多,只不过我是在组件内部引用的。

他给出的解决方式是在项目的入口文件 entry.js 中加入引用:

/*global Vue*/

/* weex initialized here, please do not move this line */
import '@weex-project/weex-picker';
const router = require('./router');
const App = require('@/index.vue');
/* eslint-disable no-new */
new Vue(Vue.util.extend({el: '#root', router}, App));
router.push('/');

但是在 web 上没问题,在 weex 上直接抛出错误。

313642325564188869.jpg

2、能够解决问题的方法

他给出的第二种方法,是直接修改了 webpack.common.conf.js

webpack.common.conf.js中,getEntryFileContent 函数向 entry 文件前面加入了引入 vue ,weex-vue-render 的操作,在引入 weex-vue-render 后面加上引入 weex-picker

文件目录 ./configs/webpack.common.conf.js

主要是加入 dependence += "import WeexPicker from '@weex-project/weex-picker'\n";这一个引用依赖,具体位置在下面方法的注释中。

const getEntryFileContent = (source, routerpath) => {
  let dependence = `import Vue from 'vue'\n`;
  dependence += `import weex from 'weex-vue-render'\n`;
  // 这是加入的新的引用
  dependence += `import WeexPicker from '@weex-project/weex-picker'\n`;
  let relativePluginPath = helper.rootNode(config.pluginFilePath);
  let entryContents = fs.readFileSync(source).toString();
  let contents = '';
  entryContents = dependence + entryContents;
  entryContents = entryContents.replace(/\/\* weex initialized/, match => `weex.init(Vue)\n${match}`);
  if (isWin) {
    relativePluginPath = relativePluginPath.replace(/\\/g, '\\\\');
  }
  if (hasPluginInstalled) {
    contents += `\n// If detact plugins/plugin.js is exist, import and the plugin.js\n`;
    contents += `import plugins from '${relativePluginPath}';\n`;
    contents += `plugins.forEach(function (plugin) {\n\tweex.install(plugin)\n});\n\n`;
    entryContents = entryContents.replace(/\.\/router/, routerpath);
    entryContents = entryContents.replace(/weex\.init/, match => `${contents}${match}`);
  }
  return entryContents;
}

通过这种方式能够完美的解决三端兼容 picker 的问题,至于为什么第一种方式不可以(理论上是可以的),这个有时间可以研究一下。