碎碎念
上一篇文章,我们介绍了如何构建一个 react 插件,今天我们说说如何构建 vue 插件
准备工作
由于与上一篇 react 插件文章使用的是相同的结构,代码测试、持续集成及发布 npm 包也都是一个套路,这里就不再敖述。
下面主要说下不同的地方,let’s start 😊
- 开发依赖包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| { "devDependencies": { "@babel/core": "^7.0.0", "@babel/preset-env": "^7.0.0", "babel-loader": "^8.0.2", "chai": "^4.2.0", "coveralls": "^3.0.2", "css-loader": "^1.0.0", "jest": "^23.6.0", "style-loader": "^0.23.1", "vue": "^2.5.21", "vue-loader": "^15.5.0", "vue-style-loader": "^4.1.2", "vue-template-compiler": "^2.5.21", "webpack": "^4.17.2", "webpack-cli": "^3.1.0" }, }
|
- webpack 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| const path = require('path'); const { VueLoaderPlugin } = require("vue-loader");
module.exports = { mode: "production", entry: { "YanProgress": path.resolve(__dirname, './src/index.js') }, output: { path: path.resolve(__dirname, './dist'), filename: '[name].min.js', publicPath: "./dist/", libraryTarget: 'umd', }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { transformAssetUrls: { video: ['src', 'poster'], source: 'src', img: 'src', image: 'xlink:href' } }, include: path.resolve(__dirname, "./src"), }, { test: /\.js$/, use: [ { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } }, ], include: path.resolve(__dirname, "./src/"), }, {
test: /\.css$/, loader: "style-loader!css-loader" } ] }, plugins: [ new VueLoaderPlugin ], resolve: { extensions: ['.js', '.vue'], }, externals: { vue: 'vue', } };
|
编写插件
写 vue 插件稍微复杂一点 😢,根据官网的案例,我们需要提供一个包含 install 方法的对象或者一个函数(传送门),供 Vue.use 调用注册你的插件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import Component from './YanProgress.vue';
let plugin = { install(Vue,options) { Vue.component('yan-progress',Component); Vue.myGlobalMethod = function () { } Vue.directive('my-directive', { bind (el, binding, vnode, oldVnode) { } }) Vue.mixin({ created: function () { } }) Vue.prototype.$myMethod = function (methodOptions) { } } };
if (window && window.Vue) { window.Vue.use(plugin); }
export default plugin;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import Component from './YanProgress.vue';
function plugin(Vue,options) { Vue.component('yan-progress',Component); } };
if (window && window.Vue) { window.Vue.use(plugin); }
export default plugin;
|
这样写的原因是,下面源码伺候😄
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| export function initUse (Vue: GlobalAPI) { Vue.use = function (plugin: Function | Object) { const installedPlugins = (this._installedPlugins || (this._installedPlugins = [])) if (installedPlugins.indexOf(plugin) > -1) { return this }
const args = toArray(arguments, 1) args.unshift(this) if (typeof plugin.install === 'function') { plugin.install.apply(plugin, args) } else if (typeof plugin === 'function') { plugin.apply(null, args) } installedPlugins.push(plugin) return this } }
|
开源贡献
拥抱开源,这样才能让社区,乃至行业发展更有动力,哎,似曾相识的赶脚,😂
注:例如,你的 star 是对我最大的鼓励,是支持我继续开源的动力,😄
完结撒花🎉
👏 再次欢迎大家一起和我搞 ji 由(Github)😊
Last updated: