当前位置: 首页 > Web前端 > HTML

从零开始构建Vue组件库——VV-UI

时间:2023-04-02 11:15:38 HTML

前言:前端组件化是当今的热门话题之一,也是我们在开发单页应用时经常遇到的问题。现在我们有了一个非常实用的PerfectElement-UI。各大厂商也纷纷宣布开源XXX-UI。但也存在一些问题。比如每个公司可能需要不同的业务组件,或者我们想开发自己的组件库来增强组件的可控性。那么我们该怎么做呢?这里记录下我从零开始搭建组件库的过程。目前只有几个简单的组件,但我会慢慢更新维护:VV-UI1。环境准备我们需要准备一系列的环境来构建组件库。首先,我们考虑以下几个问题:如何搭建脚手架,如何规划目录结构,如何编写文档。首先,对于脚手架环境,已经有非常成熟的vue官方脚手架。直接用吧#全局安装vue-cli$npminstall--globalvue-cli#根据webpack模板新建项目$vueinitwebpackmy-project#安装依赖,开始吧$cdmy-project$npminstall$npmrundev那么我们来看第二个问题,如何规划我们设置的目录结构呢?首先,我们需要有一个存放组件的目录,和一个存放示例的目录。所以我们要对vue-cli生成的项目结构做一些改动:....|--examples//原来的src目录,改为examplesexampledisplay|--packages//新的packages用来写存储组件....在这种情况下,我们需要对我们的webpack配置文件进行一些调整。首先,我们要把原来编译指向src的目录改成examples。其次,为了npmrunbuild能够正常编译包,我们还需要在babel-loader中添加编译目录:{test:/\.js$/,loader:'babel-loader',include:[resolve('examples'),resolve('test'),resolve('packages')]}以便我们构建一个简单的目录结构。接下来我们需要考虑如何编写文档。对于文档的编写,markdown自然是最合适的,那么在vue下如何编写markdown文档呢?答案当然是vue-markdown-loader。然后我们根据文档配置相关插件信息:rules:[{test:/\.md$/,loader:'vue-markdown-loader'}]好了,我们可以开始尝试写文档了,例如/docs目录下新建test.md。#test>HelloWorld并创建一个指向我们的md文件的新路由:{path:'/test',name:'test',component:r=>require.ensure([],()=>r(require('../docs/test.md')))}打开我们的浏览器http://localhost:8080/#/test哈哈果然成功了。不要太高兴....问题还是来了:我们期望的文档不仅可以编译markdown,还可以更好地识别demo代码块。一方面最好是演示,另一方面可以展示演示代码,像这样:Sowhatdoweneedtodo?vue-mark-down的功能绝对不止于此!于是我们继续阅读它的文档,发现它其实是对markdown-it进行了封装,并且支持options选项。这样,我们就可以为我们的markdown定义一个唯一的标识符。这里我使用demo来识别需要显示代码块的地方,所以需要配置options选项:constvueMarkdown={preprocess:(MarkdownIt,source)=>{MarkdownIt.renderer.rules.table_open=function(){return''}MarkdownIt.renderer.rules.fence=utils.wrapCustomClass(MarkdownIt.renderer.rules.fence)返回源},使用:[[MarkdownItContainer,'demo',{//用于验证包含demo的代码块validate:params=>params.trim().match(/^demo\s*(.*)$/),render:function(tokens,idx){varm=tokens[idx].info.trim().match(/^demo\s*(.*)$/);if(tokens[idx].nesting===1){vardesc=tokens[idx+2].content;//编译成htmlconsthtml=utils.convertHtml(striptags(tokens[idx+1].content,'script'))//删除描述以防止它被添加到代码块tokens[idx+2]。孩子们=[];返回`${html}

`;}返回'
\n';}}]]}这里简单介绍一下这段代码的作用:先把vuefragment在content中编译成html展示,另一方面使用highlight来高亮代码块demo-block本身就是我们定义的组件:这样我们的test.md就可以这样写了:2.组件怎么写环境准备好了,然后我们需要开始编写组件,考虑到组件库,所以我们的组件有可能支持全局导入和按需导入。如果是全局导入,那么所有的组件都需要在Vue组件上注册并导出:constinstall=function(Vue){if(install.installed)return;components.map(component=>Vue.component(component.name,component));};exportdefault{install};那么要实现按需加载,我们只需要一个导出组件:importButtonfrom'./button/index.js';从'./row/index'导入行从'./col/index'导入列constcomponents=[Button,Row,Col];constinstall=function(Vue){if(install.installed)返回;components.map(component=>Vue.component(component.name,component));};if(typeofwindow!=='undefined'&&window.Vue){install(window.Vue);}exportdefault{安装,按钮,行,列};其次,我们还需要考虑一个问题:既然是单页应用,就要解决样式冲突的问题。如果组件中使用了soped,则无法从组件中提取样式,无法自定义。主题色的目的是我们需要一套可以单独处理的样式,可以自己编译,不能互相污染。这时候CSS的BEM规范就显得尤为重要了。如果您还不知道BEM是什么,请参考:http://www.w3cplus.com/css/css-architecture-1.html。说起来postcss是目前比较支持BEM规范的插件。它允许我们配置BEM之间的连接器和缩写:{"browsers":["ie>8","last2versions"],"features":{"bem":{"shortcuts":{"component":"b","modifier":"m","descendent":"e"},"separators":{"descendent":"__","modifier":"--"}}}}这样,我们可以单独提取样式,通过gulp打包编译:gulp.task('compile',function(){returngulp.src('./src/*.css').pipe(postcss([salad])).pipe(cssmin()).pipe(gulp.dest('./lib'));});最后生成我们的样式代码。好的,让我们开始我们的测试:importVVUIfrom'../packages/index'import'../packages/theme-default/lib/index.css'Vue.use(VVUI)一切看起来都很好...优化不足组件导出代码暂时不支持自动生成:比如我们的组件索引文件,每次添加组件都需要重写。我们可以尝试配置webpack,npmrundev时自动检测组件,然后帮我们写导出代码。目录结构划分缺陷:目前所有内容仅支持中文。如果要支持国际化,需要重新调整目录结构。发布标签:需要写脚本支持标签发布组件太少:文档刚写完,组件不多。慢慢维护吧。我相信会有越来越多的组件。也可以在做业务的过程中添加常用的组件。这样方便你以后维护和学习。结语:项目github地址:github项目demo地址:DemoPR欢迎共同维护,欢迎Star关注