当前位置: 首页 > Web前端 > vue.js

开发一个Vue插件

时间:2023-04-01 12:43:11 vue.js

//styleslightly前言在开发Vue项目的过程中,经常会用到插件,比如原生插件vue-router、vuex,以及element-ui提供的notify、message等。这些插件让我们的开发更加简单高效。那么Vue插件是如何开发的呢?如何自己开发一个vue插件然后打包发布到npm?本文涉及的技术点:Vue插件本质Vue.extend()全局方法如何手动挂载Vue实例Vue.use()原理如何打包成umd格式如何在发布前测试npm包1.定义什么是Vue插件,它和Vue组件有什么区别?看看官网的解释:“插件通常??用于为Vue添加全局功能”。“组件是具有名称的可重用Vue实例。”-Emmmm,Vue.js官网,似乎有一种朦胧的美。..我试着解释一下,其实Vue插件和Vue组件只是封装在Vue.js中的两个概念。无论是插件还是组件,最终目的都是为了实现逻辑复用。它们的本质都是对代码逻辑的封装,只是封装方式不同而已。必要的时候,也可以将组件封装成插件,插件也可以改写成组件,就看用哪个封装更方便了。另外,插件是全局的,组件可以全局注册,也可以本地注册。我们今天只关注Vue插件。插件一般有以下几种:添加全局方法或属性。如:vue-custom-element添加全局资源:directives/filters/transitions等。比如vue-touch通过全局混合添加一些组件选项。例如,vue-router通过将它们添加到Vue.prototype来添加Vue实例方法。在提供上述一种或多种特性的同时提供自己的API的库。如vue-router——Vue.js官网2.插件的使用插件需要通过Vue.use()方法注册到全局,需要在调用newVue()之前完成启动应用程序。那么在其他Vue实例中,就可以通过this.$xxx来调用插件中提供的API了。下面以实现一个简单的提示框插件toast为例,一步步介绍如何开发和发布一个Vue插件。想要的效果:useinmain.js://src/main.jsimportVuefrom'vue'importtoastfrom'@champyin/toast'Vue.use(toast)在App.vue生命周期的mounted方法中被调用this.$toast()://src/App.vue运行后,点击页面上的按钮,弹出成功通知,然后在3秒后消失。在线体验地址:http://champyin.com/toast/三、插件开发1、编写toast的本体。在Vue项目的src目录下创建components/Toast/index.vue文件(可以使用Vue-cli快速生成Vue项目,也可以自己用webpack搭建)。//src/components/Toast/index.vue//styleslightly现在toastbody已经完成了,但是里面的数据暂时还不能改,因为我还没有定义props它的属性。这不是错误,而是插件不会通过pops传递值。2.手动挂载toast实例的dom为了给插件传值,可以使用基本的Vue构造函数Vue.extend()创建一个“子类”。该子类相当于继承自Vue的Toast构造函数。然后在new的构造函数中,给Toast的data属性传一个值,然后手动调用这个实例的$mount()方法进行手动挂载,最后使用原生JS的appendChild转换真正的DOM(通过$el获取实例上的属性)到正文。在src目录下新建components/Toast/index.js文件://src/components/Toast/index.jsimportVuefrom'vue';importToastfrom'./index.vue';//useVue.extend()ConstToastConstructor=Vue.extend(Toast);consttoast=function(options={}){//创建一个Toast实例,通过构造函数传递参数,//并在Vue实例上调用$mount()手动挂载consttoastInstance=newToastConstructor({data:options}).$挂载();//手动挂载真正的dom到html的body上document.body.appendChild(toastInstance.$el);返回toastInstance;};//导出打包好的toast方法exportdefaulttoast;3.将安装方法暴露给Vue.use()。为了支持Vue.use(),Vue.js插件应该公开一个安装方法。该方法的第一个参数是Vue构造函数,第二个参数是一个可选的选项对象。——Vue.js官网从Vue.js源码也可以看出,Vue.use()方法的作用是调用插件或组件的install方法,然后传入全局Vue供插件和组件使用。//https://github.com/vuejs/vue/blob/dev/src/core/global-api/use.js/*@flow*/import{toArray}from'../util/index'导出函数initUse(Vue:GlobalAPI){Vue.use=function(plugin:Function|Object){constinstalledPlugins=(this._installedPlugins||(this._installedPlugins=[]))if(installedPlugins.indexOf(plugin)>-1){returnthis}//附加参数constargs=toArray(arguments,1)args.unshift(this)if(typeofplugin.install==='function'){plugin.install.apply(plugin,args)}elseif(typeofplugin==='函数'){plugin.apply(null,args)}installedPlugins.push(plugin)returnthis}}在src目录新建components/index.js文件,定义一个install方法,把toast实例放到Vue上。原型并作为Vue实例的方法全局公开。//src/components/index.jsimporttoastfrom'./Toast/index';import'../icon/iconfont.css';//使用constinstall=function(Vue){if(install.installed)返回;install.installed=true;//把打包的toast挂在Vue原型上,作为Vue实例上的一个方法Vue.prototype.$toast=toast;}//默认导出installexportdefault{install,};现在插件已经开发完成,可以在当前项目本地引用了。//从main.js中的src/components/index.js导入toast;App.vue中的vue.use(toast);//handleClick(){this.$toast();}4.发布到npm为了方便其他人使用这个插件,我们可以发布到npm。发布步骤很简单,但是在发布之前需要一些小的配置和一些注意事项。1.打包配置首先我们需要将其打包成浏览器可以解析的UMD格式的模块,去掉Vue.js的打包,这样其他人在Vue项目中使用这个插件时,就不会出现两份Vue或存在Vue版本冲突的问题,从而保证它们能更好的独立引用。如果你是使用Vue-cli生成项目,只需要在你的npm脚本中配置库的打包命令://package.json"build:lib":"vue-cli-servicebuild--targetlib--nametoast--destlibsrc/components/index.js》命令说明:--target:构建目标targetType有三个选项:lib|厕所|wc-asynclib:librarywc:webcomponentwc-async:asynchronouswebcomponent--name:库或组件的名称。当条目是单个文件时,名称是库或组件的文件名。当entry为全局表达式时,name为每个库或组件文件名的前缀[entry]:packagingentry可以是.vue文件或.js文件。注册多个web组件时,入口可以是全局表达式,如components/*.vue--dest:默认输出目录为dist目录,也可以修改为自定义目录,运行npmrunbuild:lib在lib目录中生成以下文件:toast.umd.js浏览器或AMD加载程序直接使用的UMD包toast.umd.min.jsUMD的压缩版本构建版本toast.common.js是CommonJS包,用于包装商。如果使用webpack构建Vue项目,需要在webpck中配置output.libraryTarget等属性://build/webpack.lib.conf.jsconstpath=require('path');const{CleanWebpackPlugin}=require('clean-webpack-plugin');module.exports={mode:'production',entry:'./src/components/index.js',输出t:{path:path.resolve(__dirname,'../lib'),文件名:'toast.js',library:'toast',libraryTarget:'umd',libraryExport:'default',umdNamedDefine:true,globalObject:'typeofself!==\'undefined\'?self:this',},externals:{vue:{root:'Vue',commonjs:'vue',commonjs2:'vue',amd:'vue',},},插件:[newCleanWebpackPlugin(),],};然后运行npmrunbuild:lib,在lib目录下可以生成如下文件:toast.js直接到浏览器或者AMD加载器使用的UMD包中2.发布前测试发布前,我们需要配置name和package.json中的main字段:name的值为最终包的名称,install和import的名称相同(请保证全网唯一)main的值为包的名称入口文件路径(相对于当前文件的路径),必须填写正确,否则无法引用包。"name":"@champyin/toast","main":"lib/toast.js",为了保证包的配置没有问题,我们可以使用npmlink命令来测试使用包的本地。npmlinktest包的使用估计很多人都会知道,我就不赘述了。有需要的可以看我的另一篇文章npmlink详细解释。这个时候我们其实是可以发布的,但是为了防止发布不必要的文件(比如测试用例和demo)浪费大家的下载流量,我们最好创建一个.npmigore文件,语法和.gitignore一样.3、发布的方法很简单(不过首先你需要有一个npm账号),在package.json所在目录执行这两句即可:npmaddusernpmpublish这篇文章有一个特别详细的介绍:howto发布一个npm模块。4.其实安装测试已经到这一步了——99.99%不会出错,安装只是为了那0.01%以防万一。在另一个Vue项目中(不是在开发toast的项目中),安装你刚刚从npm发布的包:npmi-D@champyin/toast然后在项目中使用你自己的插件,点击按钮就可以了弹出吐司提示。//从main.js中的“@champyin/toast”导入toast;App.vue项目中的vue.use(toast);//handleClick(){this.$toast();}体验地址:http://champyin.com/toast/npm地址:https://www.npmjs。com/package/@champyin/toast欢迎提issue:https://github.com/yc111/toast/issuesHappycoding:)文章同时发表于公众号《前端手册》,喜欢的可以关注哦。更多参考:https://cn.vuejs.org/v2/guide...https://cn.vuejs.org/v2/api/#...https://cli.vuejs.org/zh/guid...https://webpack.js.org/guides...https://docs.npmjs.com/cli-co...https://docs.npmjs.com/cli-co...https://docs.npmjs.com/cli-co...://www.npmjs.com/package...本文作者:ChampYin转载请注明出处:http://champyin.com/2020/03/05/developaVueplugin/