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

自定义你的专属Vue组件库

时间:2023-03-31 21:06:25 vue.js

业务的后续需求会复用很多之前开发的组件,所以打算抽取成一个组件库,以提高后续开发的效率。本文主要讲解如何构建和发布基于vue的组件库,以及使用Vuese自动生成组件文档。vue/cli3.x初始化项目vuecreatezui按照默认配置复制代码初始化流程。修改项目结构修改前:修改后:1、为了更加语义化,将src重命名为examples,并新增一个vue.config.js文件,用于配置项目启动入口。//vue.config.jsmodule.exports={pages:{index:{entry:'examples/main.js',template:'public/index.html',filename:'index.html'}}}复制代码2.Add文件夹components,我们开发组件的地方。开发一个测试组件1.在lib下新建一个自定义组件目录(1)main.vue编写组件逻辑//src/main.vue复制代码(2)demo.scss组件样式//demo.scss.z-demo{color:aqua;}复制代码(3)index.js导出组件//index.jsimportDemofrom'./src/main.vue'//eslint-disable-next-linefunc-namesDemo.install=function(Vue){Vue.component(Demo.name,Demo)}exportdefaultDemo复制这里的代码,按需加载组件。下一步是实现全局引用功能。2.在components目录下配置index.js导出所有组件,配置index.scss导入所有样式。//components/index.jsimportDemofrom'./demo';从'../../package.json'导入{版本};const组件={演示};constinstall=function(Vue){if(install.installed)返回;Object.keys(components).forEach(key=>{Vue.component(components[key].name,components[key]);})};if(typeofwindow!=='undefined'&&window.Vue){安装(窗口。Vue);}constAPI={version,install,...components};导出默认API;复制代码//components/css/index.scss@import'./demo.scss';复制代码本地测试1.导入组件库//examples/main.jsimportVuefrom'vue'importAppfrom'./App.vue'import'../components/css/index.scss'importzuifrom'../components/lib'Vue.use(Zui)Vue.config.productionTip=falsenewVue({render:h=>h(App),}).$mount('#app')复制代码2.使用组件//examples/App.vue复制代码3.效果组件库打包目前为止都是采用编译后的形式,只要把组件库发布到npm,可以直接使用,但是一般第三方库都会提前预编译打包,提供各种版本的文件。1.使用gulp打包css文件//gulpfile.jsconstgulp=require("gulp")constsass=require('gulp-sass')constminifyCSS=require('gulp-minify-css')constdel=require('del');gulp.task("sass",asyncfunction(){awaitdel(['dist/css']);returngulp.src("components/css/**/*.scss")。pipe(sass()).pipe(minifyCSS()).pipe(gulp.dest("dist/css"))})复制代码2.打包js,这里我分别提供了rollup和webpack。建议使用Rollup,因为可以导出ES6模块——未来的标准。(1)rollup方式//rollup.jsconstrollup=require('rollup');constresolve=require('rollup-plugin-node-resolve');//可以告诉Rollup如何查找外部模块constvue=require('rollup-plugin-vue');constcommonjs=require('rollup-plugin-commonjs');//将CommonJS模块转换为ES6constjson=require('rollup-plugin-json');constbabel=require('rollup-plugin-babel');const{terser}=require("rollup-plugin-terser");constfs=require('fs');constpath=require('path');constglob=require("glob");异步函数makeList(dirPath){constlist={};constfiles=glob.sync(`${dirPath}/**/index.js`);for(letfileoffiles){constoutput=file.split(/[/.]/)[2];列表[输出]={输入:文件,输出};}returnlist;}constformatTypeList=[{format:'cjs',min:false,suffix:'.js'},{format:'cjs',min:true,suffix:'.common.min.js'},{format:'umd',min:false,suffix:'.umd.js'},{format:'umd',min:true,suffix:'.umd.min.js'},{format:'es',min:false,后缀:'.js'},{格式:'es',min:true,后缀:'.es.min.js'},]start('dist/','components/lib');异步函数开始(outputPath,libPath){fsExistsSync(outputPath)&&removeDir(outputPath);创建目录(输出路径);constlist=awaitmakeList(libPath);for({format,min,suffix}offormatTypeList){awaitbuild(list,format,min,suffix)}}asyncfunctionbuild(list,format,min,suffix){console.log(`开始打包成${format}${min?'.min':''}格式`);for(Object.keys(list)的模块名称){awaitbuildFile(list[moduleName].input,list[moduleName].output,format,min,suffix);}console.log(`${format}${min?'.min':''}格式文件打包完成`);console.log('=========================================');}asyncfunctionbuildFile(input,outputName,format,min,suffix){console.log(`开始构建文件:${outputName}`)constbundle=awaitrollup.rollup({input,output:{file:`dist/${outputName}${suffix}`,格式,名称:outputName},plugins:[resolve(),commonjs(),vue(),json(),babel({babelrc:false,//忽略外部配置文件exclude:'node_modules/**',runtimeHelpers:true,}),min&&terser()]})const{output:outputData}=awaitbundle.generate({format,name:outputName});awaitwrite({output:outputData,fileName:outputName,suffix})console.log(`完成构建文件:${outputName}${suffix}`)}asyncfunctionwrite({output,fileName,suffix}={}){for(const{code}ofoutput){fs.writeFileSync(`dist/${fileName}${suffix}`,code)}}functionremoveDir(dir){letfiles=fs.readdirSync(dir)for(vari=0;imain.js中导入组件库//importallimportZUIfrom"@tencent/zui-pure";Vue.use(ZUI);//按需导入import{Demo}from"@tencent/zui-pure";Vue.use(Demo);Copyright(c)2019-presentzackguo复制代码2.注册/登录npm账号npmadduser复制代码发布tnpm私有包(在npm-中packagedirectory)npmpublish复制代码4、登录npm官网查看组件库测试1、全量导入方式(1)新建一个vue项目。(2)安装组件库。tnpmi@tencent/zui-pure复制代码(3)在main.js中引入组件库,在App.vue中使用组件。测试成功2.按需加载(1)安装babel-plugin-component插件,在babel.config.js中添加配置。tnpmibabel-plugin-component复制代码//babel.config.jsmodule.exports={presets:['@vue/app'],plugins:[["component",{"libraryName":"@tencent/zui-pure","libDir":"dist","styleLibrary":{"base":false,"name":"css"}}]]}复制代码(2)在main.js中按需加载组件//src/main.jsimportVuefrom'vue'importAppfrom'./App.vue'//importZUIfrom'@tencent/zui-pure'//Vue.use(ZUI)import{Demo}from'@tencent/zui-pure'Vue.use(Demo);Vue.config.productionTip=falsenewVue({render:h=>h(App),}).$mount('#app')复制代码测试成功获取Vuese自动生成文档1.按照vuesetnpmivuese--save-d复制代码2.在根目录添加一个配置文件。vueserc{"include":["./components/**/*.vue"],"title":"zui-doc","genType":"docute","outDir":"./docs"}复制codeinclude:指定构建目录。genType:指定生成的文档类型,docute会将vue文件构建的所有markdowns整合到一个单页应用中。outDir:指定文档输出目录,这里指定为./docs,用于在master分支上配置和访问OAPages。3.在package.json中添加一个新的脚本并启动它。//package.json{"name":"zui",..."scripts":{..."build_doc":"npxvuesegen&&npxvueseserve--open"},...}复制代码vuesegen:构建文档。vueseserve--open:启动文档服务器,打开浏览器查看生成的文档。npmrunbuild_doccopycode注意:由于demo组件结构过于简单,生成时被vuese忽略,所以添加了props。还有一个问题,我发现首页报404:解决方法:在docs根目录添加readme.md到这个,整个Vue自定义组件库架子就搭建好了~完整的组件库应该还包括单元测试和类型定义,这里不再赘述,可以直接参考demo代码。附录文章demo地址:github.com/Best921/zui...npm包地址:www.npmjs.com/package/zui...Vuese使用指南:vuese.org/注意:Vuese自定义文档写起来不是很方便demo演示,当前项目使用vuepress代替。