• 前端系列-移动端开发踩过的一些坑


    本博文总结顺序大概如下

    • 移动端开发通用坑
    • vue移动开发特有坑以及小技巧分享
    • 移动端开发性能优化

    一、移动端开发通用坑

    1、click300ms延迟?

    讲道理,现在开发移动端基本是不会有这么一个问题的。但作为移动端以前的经典坑,我这里也拿出来说上一说吧。
    移动设备上的web网页是有300ms延迟的,玩玩会造成按钮点击延迟甚至是点击失效。这是由于区分单击事件和双击屏幕缩放的历史原因造成的。但在2014年的Chrome 32版本已经把这个延迟去掉了,so you know。但如果你还是出现了300ms的延迟问题,也是有路子搞定的。

    解决方案如下:

    • fastclick可以解决在手机上点击事件的300ms延迟
    • zepto的touch模块,tap事件也是为了解决在click的延迟问题
    • 触摸事件的响应顺序为 touchstart --> touchmove --> touchend --> click,也可以通过绑定ontouchstart事件,加快对事件的响应,解决300ms延迟问题
    • 若移动设备兼容性正常的话(IE/Firefox/Safari(IOS 9.3)及以上),只需加上一个meta标签
      <meta name="viewport" content="width=device-width">

      即把viewport设置成设备的实际像素,那么就不会有这300ms的延迟。

    2、移动端样式兼容处理

    当今的手机端,各式各样的手机,屏幕分辨率也是各有不同,为了让页面可以可以兼容各大手机,解决方案如下

    • 设置meta标签viewport属性,使其无视设备的真实分辨率,直接通过dpi,在物理尺寸和浏览器之间重设分辨率,从而达到能有统一的分辨率的效果。并且禁止掉用户缩放
       <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
    • 使用rem进行屏幕适配,设置好root元素的font-size大小,然后在开发的时候,所有与像素有关的布局统一换成rem单位。针对不同的手机,使用媒体查询对root元素font-size进行调整

    3、阻止旋转屏幕时自动调整字体大小

    移动端开发时,屏幕有竖屏和横屏模式,当屏幕进行旋转时,字体大小则有可能会发生变化,从而影响页面布局的整体样式,为避免此类情况发生,只需设置如下样式即可

    1 * {
    2   -webkit-text-size-adjust: none;
    3 }

    4、修改移动端难看的点击的高亮效果,iOS和安卓下都有效

    1 * {
    2   -webkit-tap-highlight-color: rgba(0,0,0,0);
    3 }

    不过这个方法在现在的安卓浏览器下,只能去掉那个橙色的背景色,点击产生的高亮边框还是没有去掉,有待解决!

    一个CSS3的属性,加上后,所关联的元素的事件监听都会失效,等于让元素变得“看得见,点不着”。IE到11才开始支持,其他浏览器的当前版本基本都支持。详细介绍见这里:https://developer.mozilla.org/zh-CN/docs/Web/CSS/pointer-events

    pointer-events: none;

    5、iOS下取消input在输入的时候英文首字母的默认大写

    <input type="text" autocapitalize="none">

    6、禁止 iOS 识别长串数字为电话

    <meta name="format-detection" content="telephone=no" />

    7、禁止 iOS 弹出各种操作窗口

    -webkit-touch-callout: none;

    8、禁止ios和android用户选中文字

    -webkit-user-select: none;

    9、calc的兼容处理

    CSS3中的calc变量在iOS6浏览器中必须加-webkit-前缀,目前的FF浏览器已经无需-moz-前缀。 Android浏览器目前仍然不支持calc,所以要在之前增加一个保守尺寸:

    1 div { 
    2    95%; 
    3    -webkit-calc(100% - 50px); 
    4    calc(100% - 50px); 
    5 }

    10、fixed定位缺陷

    iOS下fixed元素容易定位出错,软键盘弹出时,影响fixed元素定位,android下fixed表现要比iOS更好,软键盘弹出时,不会影响fixed元素定位 。iOS4下不支持position:fixed

    解决方案: 可用iScroll插件解决这个问题

    11、一些情况下对非可点击元素如(label,span)监听click事件,ios下不会触发

    针对此种情况只需要对不触发click事件的那些元素添加一行css代码即可

    cursor: pointer;

    12、消除transition闪屏问题

    1 /*设置内嵌的元素在 3D 空间如何呈现:保留 3D*/
    2 -webkit-transform-style: preserve-3d;
    3 /*(设置进行转换的元素的背面在面对用户时是否可见:隐藏)*/ 
    4 -webkit-backface-visibility: hidden; 

    13、CSS动画页面闪白,动画卡顿

    解决方法:

    1.尽可能地使用合成属性transform和opacity来设计CSS3动画,不使用position的left和top来定位
    2.开启硬件加速

    1 -webkit-transform: translate3d(0, 0, 0);
    2    -moz-transform: translate3d(0, 0, 0);
    3     -ms-transform: translate3d(0, 0, 0);
    4         transform: translate3d(0, 0, 0);

    14、iOS系统中文输入法输入英文时,字母之间可能会出现一个六分之一的空格

    解决方法:通过正则去除

    this.value = this.value.replace(/u2006/g, '');

    15、input的placeholder会出现文本位置偏上的情况

    input 的placeholder会出现文本位置偏上的情况:PC端设置line-height等于height能够对齐,而移动端仍然是偏上,解决方案时是设置css

    line-height:normal;

    16、浮动子元素撑开父元素盒子高度

    解决方法如下:

    1 父元素设置为 overflow: hidden;
    2 父元素设置为 display: inline-block; 等

    这里两种方法都是通过设置css属性将浮动元素的父元素变成间接变成BFC元素,然后使得子元素高度可以撑开父元素。这里需要注意的时,最好使用方法1, 因为inline-block元素本身会自带一些宽高度撑开其本身。

    17、往返缓存问题

    点击浏览器的回退,有时候不会自动执行js,特别是在mobilesafari中。这与往返缓存(bfcache)有关系。 解决方法 :

    window.onunload = function () {};

    18、overflow-x: auto在iOS有兼容问题

    解决方法:

    -webkit-overflow-scrolling: touch;

    二、vue移动开发特有坑以及小技巧分享

     1、iOS原始输入法问题

    iOS原始输入法,中文输入时,无法触发keyup事件,且keyup.enter事件无论中英文,都无法触发

    解决方法:

    1. 改用input事件进行监听
    2. 将keyup监听替换成值的watch
    3. 让使用者安装三方输入法,比如搜狗输入法(不太现实)

    2、input元素失焦问题

    业务场景重现: 项目中需要写一个搜索组件,相关代码如下

     1 <template>
     2   <div class="y-search" :style="styles" :clear="clear">
     3     <form action="#" onsubmit="return false;">
     4       <input type="search"
     5         class="y-search-input"
     6         ref="search"
     7         v-model='model'
     8         :placeholder="placeholder"
     9         @input="searchInputFn"
    10         @keyup.enter="searchEnterFn"
    11         @foucs="searchFocusFn"
    12         @blur="searchBlurFn"
    13       />
    14       <y-icons class="search-icon" name="search" size="14"></y-icons>
    15     </form>
    16     <div v-if="showClose" @click="closeFn">
    17       <y-icons class="close-icon" name='close' size='12'></y-icons>
    18     </div>
    19   </div>
    20 </template>

    其中我需要在enter的时候进行对应的搜索操作并实现失焦,解决方法其实很简单,在enter时进行DOM操作即可

    1 searchEnterFn (e) {
    2   document.getElementsByClassName('y-search-input')[0].blur()
    3   // dosomething yourself
    4 }

    对了,这里还有一个坑,就是在移动端使用input类型为search的时候,必须使用form标签包裹起来,这样在移动端呼出键盘的enter才会是搜索按钮,否则只是默认的enter按钮。

    3、vue组件开发

    这个点不能算坑,只能算是小技巧分享吧。

    业务场景重现:很多时候,在开发项目的时候是需要抽离公共组件和业务组件的。而有些公共组件在全局注册的同时可能还需要拓展成vue的实例方法,通过把它们添加到 Vue.prototype 上实现,方便直接使用js全局调用。拿一个Message组件做例子吧,代码比较简单,就直接上代码了。

    1.首先开发好Message.vue文件

     1 <template>
     2   <div class='y-mask-white-dialog' v-show='show'>
     3     <div class='y-message  animated zoomIn' >
     4       <span v-html="msg"></span>
     5     </div>
     6   </div>
     7 </template>
     8 
     9 <script>
    10 export default {
    11   name: 'yMessage',
    12   props: {
    13     msg: String,
    14     timeout: Number,
    15     callback: Function,
    16     icon: String,
    17   },
    18   data() {
    19     return {
    20       show: true,
    21     };
    22   }
    23 };
    24 </script>
    25 
    26 <style lang="stylus"  scoped>
    27 .y-mask-white-dialog {
    28   background-color: rgba(0, 0, 0, .4);
    29   position: fixed;
    30   z-index: 999;
    31   bottom: 0;
    32   right: 0;
    33   left: 0;
    34   top: 0;
    35   display: -webkit-box;
    36   display: -webkit-flex;
    37   display: -ms-flexbox;
    38   display: flex;
    39   -webkit-box-pack: center;
    40   -webkit-justify-content: center;
    41   -ms-flex-pack: center;
    42   justify-content: center;
    43   -webkit-box-align: center;
    44   -webkit-align-items: center;
    45   -ms-flex-align: center;
    46   align-items: center;
    47 }
    48 .y-message {
    49   min- 2.9rem;
    50   max- 5.5rem;
    51   100%;
    52   padding: 0.32rem;
    53   font-size: 14px;
    54   text-align: center;
    55   border-radius: 4px;
    56   background :rgba(0,0,0,0.8);
    57   color: #fff;
    58   animation: zoomIn .15s ease forwards;
    59 }
    60 </style>

    2.构建Message的Constructor

     1 import Vue from 'vue';
     2 
     3 const MsgConstructor = Vue.extend(require('./Message.vue'));
     4 
     5 const instance = new MsgConstructor({
     6   // el: document.createElement('div'),
     7 }).$mount(document.createElement('div'));
     8 
     9 MsgConstructor.prototype.closeMsg = function () {
    10   const el = instance.$el;
    11   el.parentNode && el.parentNode.removeChild(el);
    12   typeof this.callback === 'function' && this.callback();
    13 };
    14 
    15 const Message = (options = {}) => {
    16   instance.msg = options.msg;
    17   instance.timeout = options.timeout || 2000;
    18   instance.icon = options.icon;
    19   instance.callback = options.callback;
    20   document.body.appendChild(instance.$el);
    21 
    22   const timer = setTimeout(() => {
    23     clearTimeout(timer);
    24     instance.closeMsg();
    25   }, instance.timeout + 100);
    26 };
    27 
    28 export default Message;

    3.在main.js里面进行组件注册

     1 import Message from './components/Message';
     2 
     3 Vue.component(Message.name, Message)
     4 Vue.prototype.$message = Message
     5 然后你就可以尽情使用Message组件了.
     6 
     7 // <y-message msg="test message"><y-message>
     8 
     9 // or
    10 
    11 this.$message({
    12   msg: 'test message'
    13   // ...
    14 })

    4、巧用flex布局让图片等比缩放

    这也是一个小技巧!项目中需要开发swiper轮播图,那么你懂的,图片肯定是需要保证等比缩放展示。

     1 <div class="parent">
     2   <img :src="imgSrc" alt="">
     3 </div>
     4 
     5 <style lang="stylus" scoped>
     6 .parent {
     7    100px;
     8   height: 100px;
     9   display: flex;
    10   align-items: center;
    11   
    12   img {
    13     width :100%;
    14     height: auto;
    15   }
    16 }
    17 </style>

    是不是贼简单,是的,贼简单这个样式同时适应手机全屏预览竖屏的情况,当手机横屏的时候,加一个媒体查询即可搞定

    1 @media (orientation: landscape) {
    2   img {
    3     width auto
    4     height 100%
    5     margin auto
    6   }
    7 }

    这里我就不上轮播图的代码了,有点小多。有需要的小伙伴可以私聊我,我后期直接传到github上去,代码可以自行查阅。效果图如下

    5、枚举值过滤处理

    业务重现:考虑到项目后期会做国际化,前端需要对项目中几乎所有的枚举值进行过滤处理,从而进行展示

    接下来就直接讲讲这块吧。既然要过滤,那么首选肯定是vue提供的filter指令。这里我举一个支付方式的枚举值处理的例子。首先配置代码如下

     1 // 配置文件
     2 export default {
     3   env: (process.env.NODE_ENV === 'development' ? require('./env/dev') : require('./env/pro')),
     4   headShow: false,
     5   lng: 'zh',
     6 };
     7 枚举代码如下
     8 
     9 // 获取语言环境
    10 import config from '../config/index';
    11 
    12 const {lng} = config;
    13 // 账户类型
    14 const type = {
    15   zh: {
    16     1: '银行',
    17     2: '支付宝',
    18     3: '微信支付',
    19   },
    20   en: {
    21     1: 'bank_type',
    22     2: 'alipay_type',
    23     3: 'wxpay_type',
    24   }
    25 }
    26 export default type[lng];

    枚举注册代码分别如下

     1 import accountType from './accountType'; // 账户类型
     2 
     3 const factory = {
     4   accountType(value) {
     5     if (value === -1) {
     6       return '请选择账户类型';
     7     }
     8     return accountType[value] ? accountType[value] : '请选择账户类型';
     9   }
    10 }
    11 const filter = [
    12   {
    13     name: 'formatEnum', // 过滤类型
    14     filter: function(value, type, status) {
    15       return factory[type](value, status);
    16     }
    17   }
    18 ];
    19 export default {
    20   filter
    21 };
    22 // filter
    23 import baseFilter from './filter/index';
    24 
    25 const filters = [
    26   ...baseFilter.filter
    27 ];
    28 filters.map(f => {
    29   Vue.filter(f.name, f.filter);
    30   return '';
    31 });

    接下来就可以轻松使用啦

    1 <li>
    2   <label支付类型</label>
    3   <span>
    4     {{info.account_type | formatEnum('accountType')}}
    5   </span>
    6 </li>

    6、时间过滤处理

    这点还是属于过滤处理的一个part,但是手机端有个兼容问题,如果是时间戳转的话,那么可以转化成任意我们想要的形式,但是String类型的时间转化的话,他只能兼容 "yyyy/MM/dd" 形式的时间值,因为我们DateTime组件默认的形式是"yyyy-MM-dd",那么只需要在DateTime组件正则替换一下即可,代码如下

    currentValue = _this.currentValue = _this.value ? _this.value.replace(/-/g, '/') : '';

    时间过滤代码如下

     1 const filter = [
     2   {
     3     name: 'formatEnum', // 过滤类型
     4     filter: function(value, type, status) {
     5       return factory[type](value, status);
     6     }
     7   },
     8   {
     9     name: 'formatDate', // 日期
    10     filter: function(value, format = 'yyyy-MM-dd') {
    11       if (!value || value === '') return '';
    12       let v = value;
    13       if (!isNaN(value)) {
    14         v = +value * 1000;
    15       }
    16       const newDate = new Date(v);
    17       return newDate.Format(format);
    18     },
    19   }
    20 ];

    7、路由权限判定

    业务重现:由于不同的用户,可能拥有不同权限,而目前我们的项目是基于微信公众号进行开发的,页面权限这边也是交给了我们前端处理。既然要前端配置权限,那么我们能想到的比较好的方式就是通过配置路由文件,完成权限判定。下面我会列举一小部分代码(以我们的工单列表)进行演示,路由配置代码如下

     1 const getWorkOrder = pageName => resolve => require(['../pages/WorkOrder'], pages => resolve(pages[pageName]))
     2 
     3 let routers = [];
     4 routers = [
     5   {
     6     path: '/workorder',
     7     name: 'workorder',
     8     component: room,
     9     children: [
    10       {
    11         path: 'list', // 管家端工单列表
    12         name: 'list',
    13         rule: 3,
    14         component: getWorkOrder('WorkOrderList') //WorkOrder,
    15       },
    16       {
    17         path: 'managerList', // 店长端工单列表
    18         name: 'managerList',
    19         rule: 6,
    20         component: getWorkOrder('ManagerWorkOrder') // WorkOrder,
    21       },
    22     ]
    23   }
    24 ]

    然后进行路由统一过滤处理

     1 import Vue from 'vue';
     2 import Store from 'store';
     3 import Router from 'vue-router';
     4 
     5 import routers from './router.config';
     6 Vue.use(Router);
     7 
     8 // 遍历路由名称以及权限
     9 let arr = {};
    10 const routeName = function (router) {
    11   if (!router) return false;
    12   router.forEach((v) => {
    13     arr[v.name] = v.rule;
    14     routeName(v.children);
    15   })
    16 }
    17 routeName(routers);
    18 
    19 const RouterModel = new Router({
    20   mode: 'history',
    21   routes: routers,
    22 });
    23 
    24 // 路由钩子,进入路由之前判断
    25 RouterModel.beforeEach((to, from, next) => {
    26   // 处理query 参数,传入到 jumpUrl,便于登录后跳转到对应页面
    27   let qu =  Object.entries(to.query);
    28   if (qu.length > 0) {
    29     qu = qu.map((item, index) => {
    30       return item.join('=');
    31     })
    32   }
    33   if (arr[to.name]) {
    34     // 如果有权限需要
    35     const userInfo = Store.get('yu_info');
    36     const cookie = Vue.prototype.$util.getCookie('X-Auth-Token');
    37     const userId = Vue.prototype.$util.getCookie('userid');
    38     if (userInfo && cookie && +userId > 0) {
    39       next();
    40     } else {
    41       // 未登录,跳转登录
    42       let param = `jumpUrl=${to.path}`;
    43       if (qu.length > 0) {
    44         param += `&${qu.join("&")}`;
    45       }
    46       if (arr[to.name] && !to.query.rule) {
    47         param += `&rule=${arr[to.name]}`;
    48       }
    49       window.location.href = `/login?${param}`;
    50     }
    51   } else {
    52     // 如果不需要权限放行
    53     next();
    54   }
    55 })
    56 
    57 export default RouterModel;

    然后在登陆界面定位到微信授权

     1 getCode() {
     2   // 定位到微信授权,若是不需要授权可以在此处处理
     3   let query = this.$route.query;
     4   let param = `jumpUrl=${query.jumpUrl || '/home'}`;
     5   let path = window.location.origin;
     6   // 登录角色处理
     7   let cfg = api[query.rule ? query.rule : 1];
     8   if (query.rule) {
     9     param += `&rule=${query.rule}`;
    10   }
    11 
    12   let redirect_url = encodeURIComponent(`${path}/login?${param}`);
    13   let url =  `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${cfg.tempApp}&redirect_uri=${redirect_url}&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect`;
    14   if (query.rule === 3) {
    15     url += '&agentid=1000004';
    16   }
    17   location.replace = url;
    18 }

    如果不是微信端,访问到到rule规则的界面时,则会如下

    而当微信授权通过的时候,rule权限不足的情况则会如下

    8、使用vue-cli proxyTable进行反向代理,解决跨域问题

    开发项目,在前后端联调的时候肯定是会遇上跨域的问题的。很简单,做个反向代理呗,对于想了解正向代理和反向代理的,请点击这里

    vue-cli脚手架搭建的工程中,在config/index.js文件中可以利用预留的proxyTable一项,设置地址映射表,如下

    1 proxyTable: {
    2   '/api': {
    3     target: 'http://www.example.com', // your target host
    4     changeOrigin: true, // needed for virtual hosted sites
    5     pathRewrite: {
    6       '^/api': ''  // rewrite path
    7     }
    8   }
    9 }

    然后使用http-proxy-middleware插件对api请求地址进行代理

    1 // proxy api requests
    2 Object.keys(proxyTable).forEach(function (context) {
    3   var options = proxyTable[context]
    4   if (typeof options === 'string') {
    5     options = { target: options }
    6   }
    7   app.use(proxyMiddleware(options.filter || context, options))
    8 })

    http-proxy-middleware地址

     

    三、移动端开发性能优化

    对于这点,有一篇文章建议大家可以先看看《移动前端H5性能优化指南》。接下来我会结合实际项目抽几个点配合代码进行较为详细的讲解。

    1、首屏渲染优化

    决定用户体验最重要的一个点之一,这个点的重要性,相信不用我说了。下面直接谈实战。

    • 减少资源请求次数

    • 加载时使用过渡样式,防止用户网络太差影响对首页的体验

    • 图片使用懒加载,这一part,我们目前项目中使用的vue的三方插件vue-lazyload,大致使用方法如下

       1 // 全局注册
       2 import VueLazyload from 'vue-lazyload';
       3 
       4 Vue.use(VueLazyload, {
       5   error: require('./assets/close.svg'),
       6   loading: require('./assets/loading.svg'),
       7   attempt: 1,
       8 });
       9 
      10 // 使用
      11 <img v-lazy="room.img" :alt="room.community_name" width="100%">
    • HTML使用Viewport,Viewport可以加速页面的渲染。

      <meta name=”viewport” content=”width=device-width, initial-scale=1″>

      除此之外,还有很多点可做优化,进而提升首屏加载速度。

    2、雪碧图

    这个老生常谈了,为了减少图片请求次数,加快页面加载,当然会考虑使用雪碧图。大家这个应该没啥疑问吧。来个小例子,一天,设计小姐姐给了我一张设计稿,稿子如图

    然后给了我6张图片,一看,每张图都有6K左右的大小。好嘛,只能自己在线合张雪碧图,不然,太影响页面加载,合完雪碧图顺带在线压缩优化下,然后总大小只有6K。还有一个点,就是尽量使用::before或::after伪类,Sprites中的图片排版可以更紧 ,图片体积更小, HTML更简洁。部分代码如下

     1 <style lang="stylus" scoped>
     2   .chose-house {
     3     height: 86px;
     4      64px;
     5     margin 0 auto
     6     position relative
     7     &::before {
     8       content: '20';
     9       height: 100%;
    10        100%;
    11       position: absolute;
    12       left: 0;
    13       top: 0;
    14       background: url('../../assets/sprite-min.png') 0px 0px no-repeat;
    15     }
    16   }
    17 </style>

    3、路由懒加载

    关于路由懒加载这一部分,尤大在vue-router文档中也有所提及,链接点击这里

    其实在vue项目中使用路由懒加载非常简单,我们要做的就是把路由对应的组件定义成异步组件,代码如下

    /
     1 /在router/index.js中引入组件时可使用如下异步方式引入
     2 const Foo = resolve => {
     3   // require.ensure 是 Webpack 的特殊语法,用来设置 code-split point
     4   // (代码分块)
     5   require.ensure(['./Foo.vue'], () => {
     6     resolve(require('./Foo.vue'))
     7   })
     8 }
     9 // or
    10 const Foo = resolve => require(['./Foo.vue'], resolve)

    再将组件按组分块,如

    const Foo = r => require.ensure([], () => r(require('./Foo.vue')), 'group-foo')

    实际项目中的代码则如同我在章节《路由权限判定》提及到的一样

     1 const getWorkOrder = pageName => resolve => require(['../pages/WorkOrder'], pages => resolve(pages[pageName]))
     2 
     3 let routers = [];
     4 routers = [
     5   {
     6     path: '/workorder',
     7     name: 'workorder',
     8     component: room,
     9     children: [
    10       {
    11         path: 'list', // 管家端工单列表
    12         name: 'list',
    13         rule: 3,
    14         component: getWorkOrder('WorkOrderList') //WorkOrder,
    15       },
    16       {
    17         path: 'managerList', // 店长端工单列表
    18         name: 'managerList',
    19         rule: 6,
    20         component: getWorkOrder('ManagerWorkOrder') // WorkOrder,
    21       },
    22     ]
    23   }
    24 ]

    如上将组件通过传递pageName参数分别打包到了各个chunk中,这样每个组件加载时都只会加载自己对应的代码,从而加快渲染速度!

    4、全局组件按需注册

    当时我们为了优化首屏渲染速度,也是考虑到这一点,项目的src/main.js文件主要负责注册全局组件,插件,路由,以及实例化Vue等。在webpack的配置里面也是当成entry入口进行了配置,如果我在main.js里面讲每个组件都进行import的话,那么它将会全部一起注册打包,页面加载也会将每个组件文件都加载下来,这样对渲染速度还是有一定影响的。

    解决方法就是:按需注册,这样在打包的时候,会按需加载首页(其他界面也同样适用)使用到的全局组件。基本步骤如下:

    将需要注册的组件写进components/base.js文件中,然后exports出来

    1 exports.Foo = require('./Foo.vue');
    2 exports.Bar = require('./Bar.vue');
    3 exports.Baz = require('./Baz.vue');

    在main.js中进行注册

    c
    1 onst components = [
    2   require('./components/base').Foo,
    3   require('./components/base').Bar,
    4   require('./components/base').Baz,
    5 ];
    6 
    7 components.map(component => {
    8   Vue.component(component.name, component);
    9 });

    OK,大功告成!

    以上便是我在最近的移动端项目实战中的一些经验总结,希望对各位小伙伴或多或少有些帮助吧!如果有帮助,别吝惜你手上的赞哦~

  • 相关阅读:
    洛谷【P1109 学生分组】 题解
    卡特兰数
    并查集
    深度优先搜索DFS;递归
    【71】序列模型和注意力机制
    c/c++ 常用的几个安全函数
    win32 Ui 编程 收集
    vc获取特殊路径(SpecialFolder)
    std::map 自定义排序
    16-----BBS论坛
  • 原文地址:https://www.cnblogs.com/ljx20180807/p/9729941.html
Copyright © 2020-2023  润新知