Vux使用
作者:高天阳
邮箱:13683265113@163.com
更改历史
* 2018-10-30 高天阳 补充最佳实践
* 2018-10-29 高天阳 整理文档、补充最佳实践
* 2018-10-22 高天阳 补充安装与使用、最佳实践
* 2018-10-15 高天阳 初始化文档1 简介
VUX(读音[v’ju:z],同views)是基于WeUI和Vue(2.x)开发的移动端UI组件库,主要服务于微信页面。
基于webpack + vue-loader + vux可以快速开发移动端页面,配合vux-loader方便你在WeUI的基础上定制需要的样式。
vux-loader保证了组件按需使用,因此不用担心最终打包了整个VUX的组件库代码。
VUX并不完全依赖于WeUI,VUX在WeUI的基础上扩展了多个常用组件,但是尽量保持整体UI样式接近WeUI的设计规范。
VUX 并不是一个能解决所有场景的完美解决方案(实际上也没有一个方案能解决所有问题),也会出现某些
bug或者某些特性不支持, 所以如果遇到问题麻烦及时不带情绪正确反馈,我们乐于及时解决描述详细方便重现的问题。即使你不直接使用
VUX组件代码, 你依然可以参考VUX代码来实现自己的组件库。如果一定程度上帮助到了你,那么维护这个项目也就有所意义。
提示
VUX 是库而非框架,虽然有专用的 vux-loader,但并不影响你自由地使用其他组件库或者工具库。
VUX 使用的 CSS 预处理工具是 less(同 WeUI),但(利益于 .vue 单文件组件的灵活性)这并不影响你使用 SASS 等其他预处理器。
用以表示该组件库时请使用大写名字 VUX,用在说明版本号时使用小写 vux@2.x。
在使用VUX之前
如果你刚从后端转到前端,可能会被目前前端(表面的)工程复杂度惊吓到,但是放心,使用
vue-cli从模板创建项目可以快速开始编码、构建, 仅仅是几行简单的命令不是么?
在使用VUX之前需要你至少已经会使用Vue,同时需要你大概了解Node.js,npm,cnpm,yarn这些东西。
建议
Node.js版本在7.6.0以上。
相关工具
WeUI
VUX样式基于WeUI,但是你不必通过使用VUX来使用WeUI。 简单的页面你可以直接引入WeUI样式。详细请参考WeUI 文档。
Vue
VUX基于Vue的组件库,意味着你需要有Vue的基础知识。
如果还没有了解过,建议先看看Vue官方文档。
Webpack
如果你直接使用vux2模板,你可以暂时不用了解。当你需要自定义一些配置时自然就能很快了解了。
vue-cli
Vue 官方用于快速创建项目的工具。
或者使用 yarn
vue-loader
webpack loader,用于编译.vue文件,官方模板已经帮你配置好。
vux-loader
VUX组件库的webpack loader,实现按需加载等功能。它不是替代vue-loader而是配合vue-loader使用。 如果你使用vux2模板,暂不需要手动使用它。
2 安装和使用
2.1 安装
如果你从没使用过 VUX,请参考 快速入门。
不推荐使用 umd 方式引用组件,但是如果不得不使用,可以参考 umd 构建
直接安装或者更新:
或者使用yarn
如果你想直接从Github安装,请指定 v2 分支
如果你是从0.x更新,请参考: 更新到2.x
vux2必须配合vux-loader使用, 请在build/webpack.base.conf.js里参照如下代码进行配置:
vux@0.x 已经停止维护,请尽快迁移到 vue@2.x & vuex@2.x & vux@2.x,虽然要花点时间,但是完全值得。
2.2 快速开始
vux@2.x 推荐webpack+vue-loader方式的开发,如果要使用umd文件,请参照文档。 不建议使用引入script的方式进行开发,因为它会带来一系列的开发、维护、效率、部署问题。
Life is short, use webpack.
vux2 模板
vux2 模板 fork 自 webpack 模板,基本和官方同步。
默认为 webpack2 模板
使用淘宝 npm 镜像
cnpm
你可以直接使用 cnpm 来加速模块下载。
yarn
或者如果你已经用上了 yarn,建议配置淘宝源:
2.3 手动配置使用
注意的是下面事项并非表示 VUX 使用繁琐,部分只是出于确保有正确的依赖和配置,而部分是出于优化。
请将
babel-loader的配置写到.babelrc里而不是使用options,否则可能会出错。
折腾能力强的同学参考一下,下面即airyland/vux2模板主要处理的事项:
引入
reset.less,默认样式不包含reset,并且部分用户自己有一套reset样式,因此需要在App.vue进行手动引入
配置
vue-loader通过配置vux-loader实现)
配置
babel-loader以正确编译 VUX 的js源码(通过配置vux-loader实现)
安装
less-loader以正确编译less源码
安装
yaml-loader以正确进行语言文件读取
添加
viewportmeta
添加
Fastclick移除移动端点击延迟
添加
vue-router(如果不需要前端路由,可忽略)
添加 webpack plugin, 在构建后去除重复css代码(通过配置vux-loader实现)
如果你使用
webpack-simple模板或者 webpack 配置里缺少 .vue extension 配置,请记得配置:
2.4 代码示例
.vue文件中调用组件
main.js中调用plugin
3 定制
3.1 主题颜色配置
配置插件
暂时只支持配合
vux-loader使用。 注意的是主题文件不能引入其他less文件,只能为简单变量列表。
请配置vux-loader的less-theme插件,指定用以覆盖的less文件路径:
可配置颜色
源码地址:https://github.com/airyland/vux/blob/v2/src/styles/variable.less
更多配置需求请通过 issue 提出。
demo站点的示例配置
源代码地址:https://github.com/airyland/vux/blob/v2/src/theme.less
内部如何实现的?
vux-loader在每个less文件的编译过程中重写了less-loader的变量参数,使其能直接覆盖原来变量。
4 开发
4.1 路由
推荐直接使用官方vue-router, VUX部分组件支持link属性直接支持vue-router的路由参数,vux2模板内置了vue-router。
如果使用了过渡(转场动画),在iPhone上使用左划返回时动画会再执行一遍,目前没有找到可行的处理方法,如果你有处理方案,欢迎PR。https://github.com/airyland/vux/pull/2259
4.2 在Nuxt.js中使用
请直接参考源码目录/ssr/nuxt
4.3 TypeScript 支持
即将支持
4.4 Ajax 请求
版本要求
AjaxPlugin在vux@^2.1.0-rc.20开始支持
引入
main.js入口文件中引入:
兼容性问题
需要注意的是axios是基于Promise的,因此如果你需要兼容低版本浏览器(caniuse),需要引入polyfill。
Polyfill推荐使用 es6-promise
全局使用
组件中使用
4.5 点击延迟
直接使用
WeUI样式并引入fastclick会导致一些点击问题,VUX组件内部已经做了相关处理。
引入 fastclick
在main.js里引用fastclick
4.6 使用微信 jssdk
分享接口只有认证公众号才能使用,域名必须备案且在微信后台设置。 先确认已经满足使用
jssdk的要求再进行开发。
WechatPlugin插件提供了commonJS的引入方式,因此你不需要在index.html引入文件。
版本要求
WechatPlugin在vux@^2.1.0-rc.19开始支持
引入
在main.js中全局引入:
组件外使用
考虑到你需要在引入插件后调用config方法进行配置,你可以通过Vue.wechat在组件外部访问wx对象。
jssdk需要请求签名配置接口,你可以直接使用 VUX 基于Axios封装的AjaxPlugin。
组件中使用
那么之后任何组件中都可以通过this.$wechat访问到wx对象。
4.7 添加谷歌统计
单页面应用切换时要手动发送页面统计,首先在index.html或者main.js里引入谷歌统计代码:
4.8 页面切换显示 Loading
移动端如果使用异步组件加载那么还是需要一点等待时间的,在网络慢时等待时间会更长。显示Loading状态缓解一下用户等待情绪就十分重要。
如果你使用vue-router和vuex,那么可以很容易实现。
首先,注册一个module来保存状态
然后使用vue-router的beforeEach和afterEach来更改loading状态
在App.vue里使用loading组件并从vuex获取isLoading状态
done.
如果你觉得在加载比较快时Loading组件一闪而过体验也不大好,那么你可以延迟设置loading=false。
4.9 异步加载组件
将所有页面组件一次性加载是一个很浪费资源和考验用户耐心的做法,尤其在移动端。
使用方法
webpack提供了code splitting,你可以按照下面写法实现当切换到特定路由时才加载代码。
需要注意的是vue-loader@13.0.0语法有所变更,具体参照发布说明v13.0.0
组件打包问题
如果你在不同的进行了代码分割的 .vue 文件引入了相同的组件,在打包时两个路由的代码都会重复打包该组件。
你可以对重复使用的组件在main.js进行全局注册,以减少相应 chunk file 的大小并提高下载速度。
4.10 区分测试环境和生产环境
4.11 全局公共函数
4.12 autoprefix 配置
4.13 禁用 eslint
5 vux-loader
5.1 vux-loader 是什么?
5.2 安装使用
5.3 插件列表
6 最佳实践
6.1 常见问题及处理
6.1.1 VUX tabber切换图标及字体颜色
通过path判断当前页面,并切换选中tabbar,如果tabbar不多,使用组件一般方式即可(即在每个子模块引入tabbar并写好默认选中项)
/src/App.vue
6.1.2 x-header、tabbar固定位置
此处组件fix失效是因为在app.vue引用tabbar导致的,若在子页面分别引用不会影响固定效果
处理方案:
添加class 固定于页面底部
../src/assets/style/main.less
6.1.3 下拉加载更多
先上效果图

创建项目
使用vue-cli 创建一个vue项目
安装vux,可以参考:vux快速入门
配置
官方文档中声明,该组件已经不再维护,也不建议使用,大部分情况下也不需要用到该组件。 建议使用第三方相关组件,相关 issue 将不会处理。不知道作者为啥不维护了,明明需求挺多的
我没有用demo里的 LoadMore 组件,用的是 Scroller里自带的 use-pullup, use-pulldown 下面是我的配置
代码示例:
6.1.4 scroller下拉失败回弹
引用vux中的scroller插件注意事项: 1、scroller标签内部必须紧套一层div标签 2、注意scroller的enabled属性,表示可以下拉刷新
6.1.5 Vue下路由History模式打包后页面空白
vue的路由在默认的hash模式下,默认打包一般不会有什么问题,不过hash模式由于url会带有一个#,不美观,而且在微信分享, 授权登录等都会有一些坑.所以history模式也会有一些应用场景.新手往往会碰到history模式打包后页面一片空白的情况, 而且没有资源加载错误的报错信息.这个其实仔细研究下会发现,如果项目直接放的跟目录, 那么是没有问题的,如果是子目录, 那么就会一片空白了.这个vue官方有解释,需要加一个base
这个base即为项目路径.以上两个都解决了,还是会发现,此时只有首页能访问,通过首页点进去其他路由也是可以的, 但是如果在其他路由刷新就有错误了,这个懂history模式的也应该知道,history模式是h5 api的 history.pushState, 相对于是浏览器模拟了一条历史,而真正服务器上没有这个路径资源,为什么hash模式不存在这个问题呢?hash模式是带#, 这个服务器不会解析,相对于还是返回html而已,index.html会根据vue路由去解析,而history模式则会请求服务器上的此地址, 服务器上没有相关路径就会报错了,vue-router的官方文档有介绍各种配置,比如ngnix的配置
上面这个对于直接项目的根目录是可以的,但是如果项目不是根目录还是会有问题,
上面这个是项目路径名为history,这样配置后就不会有vue打包后页面空白问题了,history路由也可以自由访问了, 不过要记得上面说的,非根目录的项目需要加上base 的路径
6.1.6 打包后css引用图片资源找不到
使用vue打包,通过css引用图片资源。
热更新开发环境的效果是这样

但打完包出来的页面却报找不到资源的错误。
查了一下原因,css引入图片再打包后,style-loader无法设置自己的publicPath,于是我改变了ExtractTextPlugin的css路径publicPath。
在build一次,没有报错,正常显示!
6.1.7 打包后js引用图片资源找不到
在vue组件的js部分导入图片要使用require的形式导入,否则webpack不能正常导入,因为其路径不符合其解析规范
原因:
在引入图片的时候的地址数据的时候需要使用require来讲图片作为模块引入,这样才会被webpack正确的打包的项目文件中,否则会因为webpack根据依赖打包而找不到指定的图片
如果是在HTML中的img中通过v-bind引入引入图片,src为对应的数据变量的话也是需要使用require来将图片作为模块引入才会被webpack正常打包
在HTML中直接书写的img地址以及css中引入的图片地址无需使用其他手段正常引用即可被webpack正常打包

6.1.8 vux框架组件自定义样式
6.1.8.1 全局方式
方法一 在webpack.base.conf.js文件中配置

然后在配置的路径写入对应的.less文件,类似下图这样

6.1.8.2 局部方式
方法二 使用/deep/或>>>
在引用的组件包一个div,例如类名为sample
要改变里面组件样式可以用在<style>标签中用.sample /deep/ xxxxx组件样式类来选择

注意:/deep/在less和sass中不支持,本人在使用>>>测试的时候没有生效
6.1.9 vux-cell title 插槽使用
注意:样式被修改,可能是公共样式或其他模块样式在打包后被修改
vux cell title插槽可添加样式并使得超长文字隐藏。 可参考/yumaomoney_WeChat/src/components/user/message/Message.vue .cell-overflow
6.1.10 输入框验证
使用is-type的情况
vux使用x-input情形如下:
表单中需要填写手机号,填完手机号之后,进行提交。点击“提交”按钮的时候, 需要判断手机号是否通过校验,vux提供了is-type内置验证器,我们省去了自己校验手机号的过程。

有3点需要注意:
x-input控件上加了 ref ,加了ref才能使用this.$refs.mobile.valid
x-input控件上加required将其变成必填项
@click需要加上 .native 才能触发submitData方法
使用vux-ui自定义表单验证
表单内容都填写无误之后,提交表单的按钮才能被触发(如图)

注意:使用x-input组件的@on-change事件,及使用ref
示例:可参考yumaomoney_WeChat/src/components/user/reviseLogin/ReviseLogin.vue
效果图如下:

6.1.11 声明公共变量、函数
在项目中,经常有些函数和变量是需要复用,比如说网站服务器地址,从后台拿到的:用户的登录token, 用户的地址信息等,这时候就需要设置一波全局变量和全局函数,这两个设置不太难,而且有一些共通之处。
定义全局变量
原理:
设置一个专用的的全局变量模块文件,模块里面定义一些变量初始状态,用export default 暴露出去, 在main.js里面使用Vue.prototype挂载到vue实例上面或者在其它地方需要使用时,引入该模块便可。
全局变量模块文件:
Global.vue文件:
1:全局变量专用模块
在需要的地方引用进全局变量模块文件,然后通过文件里面的变量名字获取全局变量参数值。
在text1.vue组件中使用:
2:全局变量模块挂载到Vue.prototype 里
在程序入口的main.js文件里面,将上面那个Global.vue文件挂载到Vue.prototype。
接着在整个项目中不需要再通过引用Global.vue模块文件,直接通过this就可以直接访问Global文件里面定义的全局变量。
text2.vue:
Vuex也可以设置全局变量:
通过vuex来存放全局变量,这里东西比较多,也相对复杂一些,有兴趣的小伙伴们,可自行查阅资料,折腾一波、
定义全局函数
原理
新建一个模块文件,然后在main.js里面通过Vue.prototype将函数挂载到Vue实例上面,通过this.函数名,来运行函数。
在main.js里面直接写函数
简单的函数可以直接在main.js里面直接写
组件中调用:
写一个模块文件,挂载到main.js上面。
base.js文件,文件位置可以放在跟main.js同一级,方便引用
}; main.js入口文件:
组件里面调用:
6.1.12 全局注册第三方插件
6.2 报错、警告处理
6.2.1 报错处理:Failed to load resource: net::ERR_FILE_NOT_FOUND
Failed to load resource: net::ERR_FILE_NOT_FOUND或者vue dist文件下的index.html没显示
vue的图片路径,和背景图片路径打包后错误解决


找到 config->index.js里面,如下修改

找到 build->utils.js,在里面加入一句publicPath:’../../’

配置修改完成,接下来,使用有两种方式,这里一般和文件结构有关,下面是我的文件结构下的使用
1、图片资源放在 assets->img文件夹下面
img标签引入图片
css使用图片
2、图片资源放在static->img文件夹下面
img标签引入图片
css使用图片
6.2.2 警告处理:warning:component lists rendered with v-for should have explicit keys
命令行warning(Emitted value instead of an instance of Error)。 component lists rendered with v-for should have explicit keys。 See https://vuejs.org/guide/list.html#key for more info.
截图如下:

这里只是推荐使用key. 原本的代码如下:
运行时显示warning,添加:key即可,如下:
这样就不会报错啦,具体看文档,key不是必须的,仅仅是warning
6.2.3 报错处理:exports is not defined
在引入插件后,控制台报错Uncaught ReferenceError: exports is not defined
处理方法:
引入插件需重新编译,重新
npm run devwebpack 2后不允许混合使用import和module.exports
统一修改为
export default XXX找到
.babelrcf删除transform-runtime
去掉 { "modules": false }其中{ "modules": false }阻止了babel进行模块转换,具体见modules配置的说明。
将modules改为默认设置即可
删除该配置

6.2.4 报错处理:Default export is not declared in imported module

升级 webstorm 到 2016.1 即可解决,以前的版本有这个规则但是没选项关闭
可参考yumaomoney_WeChat/src/components/container/Container.vue,export default为必要内容。
7 同类型技术比较
8 课后练习
初始化项目
配置路由,并创建3个页面(要求1级2个,二级1个)
使用VUX组件,编写demo页(必须使用组件: XHeader、Cell、XInput)
路由跳转并传参(A页面传参至B页面,使用query传参方式;B页面input输入内容传参至C页面,使用params传参方式,C页面返回后,B页面输入框重新渲染之前的数据;)
编辑B页面,使用三种方式引入图片资源(css、js、img)
声明全局变量,并使用
声明全局函数,并使用
声明全局样式,并使用
引入axios插件并使用
引入lodash插件并使用
参考资料
Last updated
Was this helpful?