前段时间一直在研究组件库,终于在组内派上了用场。来给大家贡献一篇关于移动端组件库的相关知识。经验不是很多,如果有不合理的地方还请指出哦~~~
回想一下,在你们公司或者你们小组是否有一个以上的项目需要你维护?你是否遇到了两个项目需要开发类似的功能的情况?那么你是怎么做的呢?
有这么三种通俗的解决方案:
所以就写一个自己想要的组件库吧。我们以一个简单的vue移动端组件库为例讲一下重点部分:
1.把公共组件放入components目录中,并编写导出文件
// src/index.js
import Btn from './components/btn'
import Swipe from './components/swipe'
const install = function(Vue) {
if (install.installed) return;
// 此处注意:组件中需要添加name属性,代表注册的组件名,也可修改成其他
Vue.component(Btn.name, Btn)
Vue.component(Swipe.name, Swipe)
}
// Vue 是全局变量时,自动 install
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue);
};
module.exports = {
install,
Btn,
Swipe
}
此处需要注意的是install。Vue 的插件必须提供一个公开方法 install,该方法会在你使用该插件,也就是 Vue.use(yourPlugin) 时被调用,相当于是一个插件的注册或者声明。
2.webpack配置
var path = require('path')
var options = require('./webpack.base')
var merge = require('webpack-merge')
var webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = merge(options, {
entry: path.resolve(__dirname, '../src/index.js'),
output: {
filename: 'UiLib.js',
path: path.resolve(__dirname, '../dist'),
library: 'UiLib',
libraryTarget: 'umd' // commonjs2
},
externals: {
vue: {
root: 'Vue',
commonjs: 'vue',
commonjs2: 'vue',
amd: 'vue'
}
},
plugins: [
new ExtractTextPlugin({
filename: './style.css',
disable: false,
allChunks: true
})
]
})
这里需要注意:必须加上externals(打包去掉vue)和library,libraryTarget(打包产出模式)。可以去webpack官网查看详细说明。样式需要单独打包出来,否则打包的js文件过大影响性能。
3.在package.json中添加:
{
"main": "dist/UiLib.js" // 引用的入口文件
"name": "vue-ui-lib"
"version": "0.0.1"
}
到此一个简单的组件库就可以publish了,赶快试试吧
4.引用
// index.js
npm i vue-ui-lib --register [服务器地址]// 默认是
import UiLib from 'vue-ui-lib'
Vue.use(UiLib)
// test.vue 注意写对组件名,即上边提到的组件中的name属性
btn>
<swipe ...>swipe>
这样虽然通了,可是我要修改组件,测试组件效果怎么办?很明显,需要一个demo做测试。
5.创建demo,并在demo的入口文件中引入
// demo/index.js
import UiLib from '../src/index'
Vue.use(UiLib)
然后按照正常的webpack配置好,你的测试也就能跑通了。
可是,你又发现有些项目只用一个组件,但Vue.use后会把所有的组件引入。所以如何做到按需引入组件呢?当然是webpack的多入口文件啦,当然还有别的方法,比如可以
6.按需引入
module.exports = merge(options, {
// 举例
entry: {
'btn': __dirname + '/../src/components/btn/index.js',
'swipe': __dirname + '/../src/components/swipe/index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, '../dist'),
library: 'ypUiLib',
libraryTarget: 'umd'
}
})
现在组件库的基本功能完成了,很开心吧,是不是觉得很简单呐~~~其实这只是最基础的,如果要做一个复杂的通用组件库要考虑的还有很多很多~~~
接下来说一些注意事项:
使用者会说修改组件库的样式怎么这么难呢?一看发现是组件中用了css modules或者层级嵌套太深,或者是在vue的style中写了scoped。
可是去掉这些又会导致全局样式出现,万一跟用户定义的class重名怎么办,所以我们就需要将所有的class命名重写,一定要有规范,可以用postcss的@component-namespace name {…}统一管理。
// bad
<style lang="scss" scoped>
.loading {
color: red;
.box {
width: pxToRem(60px);
}
}
...
style>
// good 这样命名都加了前缀,并且没有层级嵌套
<style lang="scss">
.zzyp-loading {
position: fixed;
top: 0;
&-box {
width: pxToRem(60px);
}
...
}
style>
版本控制
说明文档