如何实现一个简单的Vue移动端组件库
2017-09-10 18:55
901 查看
前段时间一直在研究组件库,终于在组内派上了用场。来给大家贡献一篇关于移动端组件库的相关知识。经验不是很多,如果有不合理的地方还请指出哦~~~
回想一下,在你们公司或者你们小组是否有一个以上的项目需要你维护?你是否遇到了两个项目需要开发类似的功能的情况?那么你是怎么做的呢?
有这么三种通俗的解决方案:
COPY 你可能会说我讲究速度,复制之前的组件到新项目中(如果之前没抽出组件那你可能得反思一下了),那么慢慢的你会发现随着你的项目的增加代码量在成倍上升。重复工作浪费了你很多时间。
子模块 我可以抽离出所有公共的组件添加一个子模块(git submodule),这种方式虽然解决了重复工作,但对目录结构以及使用者的要求比较多,还是不满意。。。
使用开源组件库 这可能是一个好的选择,但是,一用才发现很多并不是我们想要的,尤其是移动端组件库:
有些组件产品并不是想要那样做,你还是需要自己写
移动端的UI风格差异较大
不同终端的适配方案不同rem/px/vw等。
所以就写一个自己想要的组件库吧。我们以一个简单的vue移动端组件库为例讲一下重点部分:
1.把公共组件放入components目录中,并编写导出文件
此处需要注意的是install。Vue 的插件必须提供一个公开方法 install,该方法会在你使用该插件,也就是 Vue.use(yourPlugin) 时被调用,相当于是一个插件的注册或者声明。
2.webpack配置
这里需要注意:必须加上externals(打包去掉vue)和library,libraryTarget(打包产出模式)。可以去webpack官网查看详细说明。样式需要单独打包出来,否则打包的js文件过大影响性能。
3.在package.json中添加:
到此一个简单的组件库就可以publish了,赶快试试吧
4.引用
这样虽然通了,可是我要修改组件,测试组件效果怎么办?很明显,需要一个demo做测试。
5.创建demo,并在demo的入口文件中引入
然后按照正常的webpack配置好,你的测试也就能跑通了。
可是,你又发现有些项目只用一个组件,但Vue.use后会把所有的组件引入。所以如何做到按需引入组件呢?当然是webpack的多入口文件啦,当然还有别的方法,比如可以
6.按需引入
现在组件库的基本功能完成了,很开心吧,是不是觉得很简单呐~~~其实这只是最基础的,如果要做一个复杂的通用组件库要考虑的还有很多很多~~~
接下来说一些注意事项:
使用者会说修改组件库的样式怎么这么难呢?一看发现是组件中用了css modules或者层级嵌套太深,或者是在vue的style中写了scoped。
可是去掉这些又会导致全局样式出现,万一跟用户定义的class重名怎么办,所以我们就需要将所有的class命名重写,一定要有规范,可以用postcss的@component-namespace name {…}统一管理。
版本控制
依赖包的版本 为了让使用者安装的时候不会因为版本不一样出现一些不可预料的错误,我们需要package lock,可以使用npm 5的lock,也可以使用yarn管理
自身版本 控制好大版本小版本,小版本可以直接用npm version patch生成
说明文档
demo和文档最好放到一起
示例越多越好
属性,方法,slot等需要写详细清楚
为了提高开发效率,可以写一些自动生成文件,比如src/index.js等。
开发文档需要写清楚
回想一下,在你们公司或者你们小组是否有一个以上的项目需要你维护?你是否遇到了两个项目需要开发类似的功能的情况?那么你是怎么做的呢?
有这么三种通俗的解决方案:
COPY 你可能会说我讲究速度,复制之前的组件到新项目中(如果之前没抽出组件那你可能得反思一下了),那么慢慢的你会发现随着你的项目的增加代码量在成倍上升。重复工作浪费了你很多时间。
子模块 我可以抽离出所有公共的组件添加一个子模块(git submodule),这种方式虽然解决了重复工作,但对目录结构以及使用者的要求比较多,还是不满意。。。
使用开源组件库 这可能是一个好的选择,但是,一用才发现很多并不是我们想要的,尤其是移动端组件库:
有些组件产品并不是想要那样做,你还是需要自己写
移动端的UI风格差异较大
不同终端的适配方案不同rem/px/vw等。
所以就写一个自己想要的组件库吧。我们以一个简单的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 ...></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 class管理使用者会说修改组件库的样式怎么这么难呢?一看发现是组件中用了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>
版本控制
依赖包的版本 为了让使用者安装的时候不会因为版本不一样出现一些不可预料的错误,我们需要package lock,可以使用npm 5的lock,也可以使用yarn管理
自身版本 控制好大版本小版本,小版本可以直接用npm version patch生成
说明文档
demo和文档最好放到一起
示例越多越好
属性,方法,slot等需要写详细清楚
从开发者角度出发
js提取所有公共模块,工具函数等为了提高开发效率,可以写一些自动生成文件,比如src/index.js等。
开发文档需要写清楚
相关文章推荐
- 使用Vue组件实现一个简单弹窗效果
- 10vue组件入门_如何写一个最简单的vue组件_vue组件的作用是啥
- 用vue写一个商城的上货组件(简单易懂版,50行js实现效果)
- 如何在ns2中实现一个简单的网络协议
- HTTP协议简单了解,如何简单的实现一个web服务器
- 如何在ns2中实现一个简单的网络协议
- 如何在ns2中实现一个简单的网络协议
- C++的杂七杂八:如何实现一个简单的bind
- 如何在ns2中实现一个简单的网络协议
- 协议设计:如何实现一个最简单的通信协议(线程模拟)
- 协议实现:如何实现一个最简单的通信协议(线程模拟)
- 一个简单的例子看明白如何利用window.location.hash实现ajax操作时浏览器的前进/后退功能
- 用UDP实现可靠文件传输,如何利用UDX创建一个简单的WIN32程序
- linux设备驱动第三篇:如何实现一个简单的字符设备驱动
- 一个简单RPC框架是如何炼成的(IV)——实现RPC消息的编解码
- 转:ECharts图表组件之简单关系图:如何轻松实现另类站点地图且扩展节点属性实现点击节点页面跳转
- 【Android】使用Chronometer组件实现一个简单的计时器
- 简单的如何实现关闭网页时,弹出一个新网页
- linux设备驱动第二篇:一个简单hello world驱动如何实现
- 如何在ns2中实现一个简单的网络协议