浅谈vue项目重构技能宗旨和小结,pwa重构香岛大

时间:2019-10-08 09:28来源:网页制作
pwa重构北京大巴线路图 2018/03/28 · JavaScript· PWA 原来的书文出处:Neal    事先一向有在珍贵三个巴黎大巴线路图的 pwa,最根本的特征就是 “offlinefirst”。可是由于代码都以透过原生的

pwa重构北京大巴线路图

2018/03/28 · JavaScript · PWA

原来的书文出处: Neal   

事先一向有在珍贵三个巴黎大巴线路图的 pwa,最根本的特征就是 “offline first”。可是由于代码都以透过原生的 js 去完毕,以前笔者都不是很欣赏去用框架,不想具备别的框架的偏幸。不过到末代随着代码量的扩张,代码的确变得混乱不堪,扩充新职能也变得特别困难。因而,花了临近多少个礼拜的时候对于使用实行了一回完整的重构。网址访问地址:

前言

准备

预备干活先做好,在 vue 和 react 之间,作者要么选用了后世。基于 create-react-app 来搭建情状,crp 为您希图了贰个开箱即用的付出情状,因而你没有须求本人亲手配置 webpack,由此你也无需产生一名 webpack 配置程序猿了。

其它四只,大家还索要部分多少,包蕴站点音信,线路途径,文字表明等等。基于以前的应用,能够透过一小段的代码获取音信。就此如要大家获得大家原先的站点在 svg 图中的相关属性,普通的站点使用 circle 元素,为了赢得其性质:

const circles = document.querySelectorAll('circle'); let result = []; circles.forEach(circle => { let ele = { cx: circle.cx, cy: circle.cy, sroke: circle.stroke, id: circle.id }; result.push(ele); }) const str = JSON.stringify(result);

1
2
3
4
5
6
7
8
9
10
11
12
13
const circles = document.querySelectorAll('circle');
let result = [];
circles.forEach(circle => {
  let ele = {
    cx: circle.cx,
    cy: circle.cy,
    sroke: circle.stroke,
    id: circle.id
  };
  result.push(ele);
})
const str = JSON.stringify(result);
 

透过如此的代码大家就足以博得 svg 普通站点音信,同理还可获得中间转播站消息,线路门路新闻以及站点以及线路 label 消息。还应该有,大家还须求猎取每一种站点的时刻表音信,卫生间地点新闻,无障碍电梯新闻以及出入口新闻。这里是写了有些爬虫去官方网址爬取并做了有的数额处理,再次就不一一赘述。

近些日子太忙了,博客好久未有更新了。明天忙里偷闲,轻便总结一下以来vue项目重构的部分工夫大旨。

设计

数据希图好今后,正是选择的布置性了。首先,对组件举行三次拆分:

vue数据更新, 视图未更新

组件结构

将全方位地图知道成贰个 Map 组件,再将其分成 4 个小组件:

图片 1

  • Label: 地图上的文件音信,包括大巴站名,线路名称
  • Station: 大巴站点,富含常见站点和转账站点
  • Line: 大巴线路
  • InfoCard: 状态最复杂的二个零部件,首要包涵时刻表消息、卫生间地点音讯、出入口音讯、无障碍电梯新闻

那是叁个光景的组件划分,里面或许含有越来越多的任何成分,举例 InfoCard 就有 InfoCard => TimeSheet => TimesheetTable 那样的嵌套。

其一难点大家平时会遇见,通常是vue数据赋值的时候,vue数据变动了,然则视图未有创新。这一个不算是项目重构的手艺焦点,也和大家享受一下vue2.0普普通通的施工方案吗!

零件通讯和景况管理

地面开拓的最大的困难应该正是这一块的内容了。本来出于组件的层级并不算极度复杂,所以小编并不企图上 Redux 那体系型的全局状态管理库。主要组件之间的通讯就是老爹和儿子通讯和兄弟组件通讯。父亲和儿子组件通信相比较轻便,父组件的 state 即为子组件的 props,能够经过那么些达成老爹和儿子组件通讯。兄弟组件略为复杂性,兄弟组件通过分享父组件的地方来开展通讯。倘使这样的光景,作者点击站点,希望能够弹出新闻提示窗,那正是Station 组件和 InfoCard 组件之间的通信,通过 Map 组件来进展分享。点击 Station 组件触发事件,通过回调更新 Map 组件状态的更新,同有的时候候也兑现了 Info卡德组件的翻新。同有时间为了落实,点击任何区域就可以关闭消息提示窗,我们对 Map 组件举行监听,监听事件的冒泡来达成快速的破产,当然为了制止某个不须要的冒泡,还亟需在部分事件管理中阻止事件冒泡。

图片 2

InfoCard 是最棒复杂的叁个零件,因为中间包罗了有个别个 icon,以及气象音讯的切换,同一时间须要贯彻切换分裂的站点的时候能够更新新闻提醒窗。须要注意音信提醒窗消息初次点击音信的开始化,以及切换分歧icon 时分别展现分裂的音信,比如卫生间新闻依然出入口消息,以及对此时刻表,切换差异的路径的时候更新对应的时刻表。这几个处境的转发,要求值得注意。别的值得一题的点便是,在切换不一致站点的时候的情事,倘若笔者正在看有些站点的茶水间新闻的时候,笔者点击其它一个站点,那时候弹出的音讯提示窗应该是时刻表消息可能卫生间消息吗?小编的选项依旧卫生间新闻,俺对此这一景观举行了保全,那样的客户体验从逻辑上来说仿佛更佳。具体贯彻的代码细节就不一一说明了,里面肯能包涵越来越多的内部原因,迎接使用体验。

建设方案如下:

属性优化

以上那个的费用得益于此前的保险,所以重构进程照旧非常快的,稍微谙习了下 react 的用法就完事了重构。不过,在上线之后采纳 lighthouse 做分析,performan 的得分是 0 分。首屏渲染以及可互相得分都以 0 分,首先来剖判一下。因为全部应用都以经过 js 来渲染,而最棒宗旨的就是非常svg。整个看下来,有几点值得注意:

  • 代码直接将 json 导入,导致 js 体量过大
  • 抱有组件都在渲染的时候实行加载

找到标题点,就可以想到一些减轻方案了。第贰个比较轻松,压缩 json 数据,去除一些不需求的音讯。第叁个,好的消除办法便是经过异步加载来兑现组件加载,效果鲜明,尤其是对于 InfoCard 组件:

1、通过vue.set格局赋值

同步

class InfoCard extends React.Component { constructor(props) {    super(props) { ...    }  }  ... }

1
2
3
4
5
6
7
8
9
class InfoCard extends React.Component {
  constructor(props) {
   super(props) {
    ...
   }
 }
 ...
}
 
Vue.set(数据源, key, newValue)

异步

export default function asyncInfoCard (importComp) { class InfoCard extends React.Component {    constructor(props) { super(props); this.state = { component: null }; } asyncComponentDidMount() { const { default: component } = await importComp(); this.setState({ component: component })    }  } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export default function asyncInfoCard (importComp) {
  class InfoCard extends React.Component {
   constructor(props) {
      super(props);
      this.state = {
        component: null
      };
    }
    
    asyncComponentDidMount() {
      const { default: component } = await importComp();
      this.setState({
        component: component
      })
   }
 }
}
 

如此这般我们就兑现了将一起组件改变成贰个异步加载的零部件,那样就不需求一下子加载所有的零部件。那样大家就能够在 Map 中使用异步的章程来开展零部件的加载:

import asyncInfoCard from './InfoCard' const InfoCard = asyncInfoCard(() => import('./InfoCard')

1
2
3
import asyncInfoCard from './InfoCard'
const InfoCard = asyncInfoCard(() => import('./InfoCard')
 

经过上线之后的习性剖析,lighthouse 品质评分一下子就上涨到了 80 多分,评释那样的精雕细琢要么相比灵通的。别的叁个值得一提的点正是首屏,因为历史由来,整张图 svg 七月素的岗位都以定死的,及横坐标和纵坐标都已然是概念好的,而 svg 被定为在个中。在运动端加载时,展现的就是左侧的空域区域,所以给顾客一种程序未加载达成的错觉。此前的版本的做法正是透过 scroll 来完结滚动条的轮转,将视图的难题移动到中等地方。这一次的主张是经过 transform 来实现:

.svg { transform: translate(-100px, -300px) }

1
2
3
.svg {
transform: translate(-100px, -300px)
}

如此那般达成了全部 svg 图地点的撼动,使用 lighthouse 实行分析,质量分降到了 70 多分。继续思考有未有其他的办法,后来自个儿想在最左上上角定义一个箭头动画。

img src="right_arrow.png" alt="right arrow" title="right arrow" class="right-arrow"/>

1
img src="right_arrow.png" alt="right arrow" title="right arrow" class="right-arrow"/>

.right-arrow { animation: moveright 3s linear infinite; } @keyframs moveright { 0% { transform: translateX(2rem); } 50% { transform: translateX(3rem); } 100% { transform: translateX(5rem); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.right-arrow {
  animation: moveright 3s linear infinite;
}
@keyframs moveright {
  0% {
    transform: translateX(2rem);
  }
  50% {
    transform: translateX(3rem);
  }
  100% {
    transform: translateX(5rem);
  }
}

图片 3

那般大家就能够创立三个循环向右移动的卡通,提示顾客向右滑动。铺排之后察觉质量分立马降到 0,索性也就放任了那几个做法。最终来时间调节制运用 transform: translateX(-200px) translateY(-300px); ,因为如此经过 css3 的性质可以在有的运动道具上还足以行使 GPU 增加速度,並且 translateX 不会挑起页面包车型大巴重绘也许重排,只会形成图层重组,最小幸免对品质的影响。

2、 通过Array.prototype.splice方法

部署

前段时间的配置方案是接纳 create-react-app 的法定建议,通过 gh-pages 实现将 build 的打包文件上传到 gh-pages 分支上进而完结计划。

数据源.splice(indexOfItem, 1, newValue)

兼容性

现阶段该使用在 Chrome 浏览器的帮忙性是最棒的,安卓浏览器提出安装 Chrome 浏览器选取,笔者平日也都比较欣赏在三哥大上接纳Google浏览器。对于 Safari 浏览器,其余的浏览功效就好像未有怎么大主题材料,如今应该还没辅助增多到主显示屏。可是在后来的 ios 版本好像对于 pwa 有着更进一竿的帮助。

3、修改数据的尺寸

结语

图片 4

花了多少个礼拜的日子实现了花色的一体化的重构,从今年来的 commit 记录能够观察十二月份疯狂 commit 了一波,首若是首先个周天花费了二日的小运修改了累累代码,被特别 InfoCard的动静切换搞了非常久,后边就是本着质量做了有的优化。进度很优伤,一度疑惑自个儿的 coding 手艺。但是最终依旧有以下感悟:

  • 世界上平素不最棒的语言,最棒的框架,唯有最合适的
  • 最高贵的落实都不是轻便的,都以多少个个试出来的

最后三个冷笑话:

妙龄问禅师:“请问大师,笔者写的顺序为何平素不博得预期的出口?” 禅师答到:“年轻人,那是因为你的前后相继只会按您怎么写的实施,不会按你怎么想的实行啊……”

源代码地址,欢迎 star 或者 pr。

 

1 赞 收藏 评论

图片 5

数据源.splice(newLength)

4、变异方法

Vue.js 包装了被考察数组的多变方法,故它们能触发视图更新。被卷入的秘技有:

push()
pop()
shift()
unshift()
splice()
sort()
reverse()

prop 对象数组应用

在 JavaScript 中目的和数组是引用类型,指向同三个内部存款和储蓄器空间,假诺 prop 是三个对象或数组, 在子组件内部退换它会潜濡默化父组件的情景 。利用那点,我们在子组件中改换prop数组或许目的,父组件以及具备应用到prop中数据的地点都会变卦。小编前面写过一篇js深拷贝和浅拷贝的稿子,感兴趣的去看下,其实,原理是一模二样的。

案比如下:

<input class="pinput max" type="text" v-model="itemData.data.did">

<script>
export default {
 components: {
 },
 data() {
 },
 props: {
 itemData: Object
 },
 methods: {
 }
};
</script>

持有应用到itemData的地点都会变卦!

地方这种退换prop,Vue 不会在调控台给出警告,要是我们完全退换依旧赋值prop,调控台会发出警示!援引官方给出的减轻方案如下:

1、定义三个片段变量,并用 prop 的值伊始化它:

props: ['initialCounter'],
data: function () {
 return { counter: this.initialCounter }
}

2、定义二个图谋属性,管理 prop 的值并重返:

props: ['size'],
computed: {
 normalizedSize: function () {
 return this.size.trim().toLowerCase()
 }
}

v-model 的片段坑

事实上v-model和sync都以某些语法糖,作者事先有小说介绍过,官方网站也能找到类似的案例!

v-model 数据一时是undefined的时候,不会报错,所以,绝对要留心,v-model不能是undefined,不然某些莫名的难点!

重构-动态组件的开创

临时大家有成都百货上千类似的机件,独有一丢丢地点不等同,大家得以把那样的近乎组件写到配置文件中,动态创立和援引组件

方法一:component 和is合营使用

通过运用保留的 成分,并对其 is 特性进行动态绑定,你能够在同贰个挂载点动态切换两个零件:

var vm = new Vue({
 el: '#example',
 data: {
 currentView: 'home'
 },
 components: {
 home: { /* ... */ },
 posts: { /* ... */ },
 archive: { /* ... */ }
 }
})
<component v-bind:is="currentView">
 <!-- 组件在 vm.currentview 变化时改变! -->
</component>

主意二:通过render方法创制

<script>
export default {
 data() {
 return {
 };
 },
 render: function(createElement) {
 let _type = bi.chart.data.type;
 let _attr = bi.chart.components[_type]["attr"];
 return createElement(_attr, {
  props: {
  }
 });
 }
};
</script>

bi.chart.components[_type]["attr"]本条是在安顿文件中动态配置的,type点击的时候会变动,会取不相同type上边包车型地铁attr属性!

国有属性抽离

作者们在档期的顺序中,通常会用比非常多情状大概数额,大家可以把无数公共数据抽离出来,放到三个目的中,前面大家得以监听这么些数额对象变化。实行多里胥存照旧取得。

c: {
 handler: function (val, oldVal) { /* ... */ },
 deep: true
},
// 该回调将会在侦听开始之后被立即调用
d: {
 handler: function (val, oldVal) { /* ... */ },
 immediate: true
},

能够利用方面深度监听。借使开头化的时候要立时实行,我们能够用当下进行监听!

require动态加载信赖

大家得以应用require同步特性,在代码中动态加载信任,举例上边echart核心,大家得以点击切换的时候,动态加载!

require("echarts/theme/"+ data.theme);

import加载要放初始部,起首化的时候,能够把暗许主旨用import加载进来!

以上正是本文的全体内容,希望对大家的上学抱有利于,也意在大家多多关照脚本之家。

您或许感兴趣的稿子:

  • Map.vue基于百度地图组件重构笔记分享

编辑:网页制作 本文来源:浅谈vue项目重构技能宗旨和小结,pwa重构香岛大

关键词: