转载 https://blog.csdn.net/kingbox000/article/details/103993233
没错,我用Vue写了一个H5项目,来看下我踩坑记录吧。
1、按需引入
在开发过程中,会遇到很多五花八门的库。其实这些库中有很多功能/模块是用不到的,所以,这里推荐按需引入:
import { Slider } from 'element-ui'; Vue.use(Slider);
- 1
- 2
- 3
像这样,如果只用到滑条,只需引入Slider,并挂载到Vue实例。
2、全局样式抽离
Css样式在前端开发中是绕不开的话题,以Vue开发为例,每个.vue文件都有自己的局部样式scoped,但是全局性的样式可以抽离到一个统一的文件(main.css),大概有以下四种情况:
- 项目中的特有颜色(其他类比),它会在不同的地方出现
- 全局的组件样式,比如对滚动条颜色的控制
- 对一些引用的公共组件的定制化样式
- 单个维度的样式,比如
.fl{ float: left }
然后样式文件在项目入口引入:
import 'assets/css/main.css';
- 1
3、统一的页面入口
用Vue开发的话,如果配置好路由,其实页面之间大可以独立运行。但是项目越来越复杂,交互越多,就更需要一个统一的入口,这样可以统一控制事件监听、处理公共组件(比如Toast)等等。所以,咱们需要一个App.vue,代码如下:
<template> <div class="page"> <router-view class="page-content"></router-view> </div> </template> <script> export default { name: 'app', data(){ return { // TODO }; }, }; </script> <style lang="scss" scoped> </style>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
然后,在Vue实例化的时候把它作为选项传入:
import App from 'modules/App.vue'; new Vue({ router, ...App }).$mount(`#app-wrapper`);
- 1
- 2
- 3
- 4
- 5
最后,页面的跳转都会在App.vue内,一切尽在掌握。
4、缓存
听到业务需求说要做持久化我是懵逼的,不过后来理解他们的意思就是做个缓存,那就简单了,哈哈。Vue有提供keep-alive组件:
<template> <div class="page"> <keep-alive> <router-view class="page-content"></router-view> </keep-alive> </div> </template>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
在上一节的基础上,加上这个组件包裹它就行了。原理就是它会缓存不活动的组件,而不是销毁它。详情可以参见 keep-alive api,官方有详细的解释。
5、监听移动设备的横屏事件
如果是用RN开发,可以调用接口来监听横屏事件,H5的话,Js有没有接口可以给你调用,但是可以监听事件,通过监听orientationchange事件,可以监听横屏动作,然后通过Orientation来获取当前角度:
window.addEventListener( "orientationchange", () => { let angle = window.orientation; if(angle % 180 != 0){ // TODO } else { // TODO } // TODO }, false);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
根据上一节说的App.vue,这个监听事件就可以放在其中,然后向其他组件广播。
6、不同组件间通信
那么,如何向其他组件广播?如果是父子,子父这种的,都好说。但是,如果是多层级的组件间通信就不好处理了,这里推荐一种网上广为流传的方法,借用Vue实例,把它作为中间方,在各组件中注册或者监听事件。直接看代码:
// inner.js import Vue from 'vue'; const bus = new Vue(); export {bus};
- 1
- 2
- 3
- 4
- 5
- 6
在inner.js中,new 一个Vue实例,然后,可以这样监听事件:
import {bus} from 'common/utils/inner'; bus.$on('my_event', (bool) => { // TODO });
- 1
- 2
- 3
- 4
- 5
广播事件:
import {bus} from 'common/utils/inner'; bus.$emit('my_event', {});
- 1
- 2
- 3
这样一来,就不用管什么层级关系了,都是广播的对象。
7、简单实现Dom拖动
如果不想引用其他库的话,可以自己实现一个移动的Dom,原理就是监听touchmove事件,然后改变它的top/left值:
document.getElementById("toolbar").addEventListener('touchmove', (e) => { e.stopPropagation(); e.preventDefault(); let y = e.touches[0].clientY; let height = window.screen.height; if(y > height) { y = height; } else if (y < 0) { y = 0; } document.getElementById("toolbar").style.top = y + "px"; });
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
不依赖任何插件,达到手指拖动toolbar的效果(这里只是让toolbar在Y轴上拖动,所以只改了它的top值)。注意要把冒泡和默认事件禁止掉,不然会影响其他模块。
8、禁止页面被拖动
H5开发会有很多问题,有些时候客户想拖动的只是某个区域,但是整个页面都会随之拖动,那就把它禁了吧,很简单:
document.getElementById("page").addEventListener('touchmove', function(e) { e.preventDefault(); }, {passive: false});
- 1
- 2
- 3
对于Vue页面来说,把它的顶部Dom禁掉就可以了,这样页面就不会有拖动的效果。
9、Ios设备下的特定样式
通常,H5开发都会遇到适配问题,特别是Iphone下,同一套样式Iphone和安卓下效果的就是会有区别。所以,我们需要判断Iphone,并给它配置特定样式,代码如下:
const isIos = () => { var ua = navigator.userAgent.toLowerCase(); if (/iphone|ipad|ipod/g.test(ua)) { return true; } else { return false; } };
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
其实原理就是通过UserAgent去判断这个设备是否是Ios设备,如果是,就把相应的样式引用进来,如下:
if(isIos()) { //是ios系统 require('assets/css/ios.scss'); }
- 1
- 2
- 3
这样就能达到根据设备配置指定样式。
10、调用引用组件的内部方法
在Vue项目已经组件化之后,经常会面临一个很常见的问题,调用组件的内部方法。其实很简单,通过Ref就可以实现:
<my-comp ref="myRef"> </my-comp>
- 1
在给引用的组件加上ref之后,在代码中去调用就行了。
this.$refs.myRef.fun();
- 1
这样就不用去传Props触发了。
11、下载文件
这个功能其实涉及到前后端的配合,如果你想下载一个文件,首先需要这个文件存在,或者是先生成,然后再获取路径下载。这是比较常规的方式了。以Excel文件为例,后台要根据业务生成Excel文件:
static async createDownloadFile(data) { try { let xls = json2xls(data); let fileName = `file.xlsx`; await fs.writeFileSync(`./dist/${fileName}`, xls, 'binary'); return fileName; } catch (err) { logger.error(`createDownloadFile error is : ${err && err.message || ''}`); return; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
nodejs实现一个Excel文件下载就是这样,把文件放到服务器指定目录,将文件名称返回到前端,前端去下载。
<a :href="downloadUri" download >保存到本地</a>
- 1
downloadUri就是拼接好的文件路径,然后别忘记加上download属性,这个属性在移动端大部分浏览器内核是支持的,但是,IE浏览器不支持(Safari浏览器也不支持,但是实测是可以下载的),没关系,它是移动端,哈哈。
12、动画效果
有些时候,整个项目交互没有点动画过渡会显的很沉重,所以,还是加点动画吧。手写吗?我知道要定义keyframes,然后设置animation之类的,但是这个东西我还是推荐使用一个库: animation. 非常轻量,就是一个css文件。使用的时候也很简单:
<div class="animated fadeOutDown" > </div>
- 1
像这样写样式就可以了。
13、表格
什么,要加表格?还是可以固定列,自定义的那种?我反手就是Element-ui表格,哈哈,完成。
巨坑啊,
Element-ui并不适合在移动端用,前期适配完之后,发现非常卡顿,最后发现是它的数据结构的问题,可折叠表格的数据结构就是子母嵌套的,数据量一上来,渲染过程就会页面卡死。不推荐。
这里推荐一个小众的组件: vue-easytable,功能都有主要是不卡,然后,把数据结构换成平级的,层级用样式实现。大概就是这个意思:
[ { id: -1, children: [ { id: -1.1, } ] }, { id: 2, } ]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
换成这样:
[ { id: -1, }, { id: -1.1, }, { id: 2, } ]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
通过自定义属性来设置样式,达到不同层级缩进效果。
最后
今天我看到鱿鱼须在VueConf的演讲了,Vue3.0用的是Typescript写的,想想微软还是强大,这种类Java的语言也能被他搞的这么火,吓得我赶紧去看下Typescript。前端变化真快~