新蒲京-前端
零构件结构
将全体地图知道成三个 Map 组件,再将其分成 4 个小器件:
- Label: 地图上的文书音讯,包含地铁站名,线路名称
- Station: 地铁站点,包含日常站点和转载站点
- Line: 大巴线路
- InfoCard: 状态最复杂的贰个组件,首要含不时刻表新闻、卫生间地点音信、出入口信息、无障碍电梯音信
这是叁个大致的零件划分,里面或许带有越多的其他成分,比如 InfoCard 就有 InfoCard => TimeSheet => 提姆esheetTable 那样的嵌套。
几天前太忙了,博客好久未有更新了。几日前强颜欢笑,轻便总计一下如今vue项目重构的有个别才具中心。
设计
数码打算好之后,就是行使的宏图了。首先,对组件举行一次拆分:
bi.chart.components[_type]["attr"]以此是在安插文件中动态配置的,type点击的时候会变动,会取分化type下边包车型大巴attr属性!
属性优化
以上这一个的开销得益于早前的保险,所以重构进度依旧超快的,稍稍了解了下 react 的用法就形成了重构。可是,在上线之后选择 lighthouse 做深入分析,performan 的得分是 0 分。首屏渲染以致可相互得分都是 0 分,首先来剖判一下。因为全部应用都以透过 js 来渲染,而最棒大旨的就是可怜 svg。整个看下来,有几点值得注意:
- 代码直接将 json 导入,招致 js 体量过大
- 抱有组件都在渲染的时候进行加载
找到题目点,就能够想到一些实施方案了。第三个比较轻巧,压缩 json 数据,去除一些没有需求的音讯。第三个,好的消除办法正是由此异步加载来完结组件加载,效果显著,特别是对于 InfoCard 组件:
require("echarts/theme/"+ data.theme);
零构件通讯和状态管理
本地开拓的最大的难题应该正是这一块的原委了。本来出于组件的层级并不算非常复杂,所以本人并不思量上 Redux 那类别型的大局状态管理库。主要组件之间的通讯正是父子通讯和兄弟组件通讯。父亲和儿子组件通讯比较容易,父组件的 state 即为子组件的 props,能够透过那么些完结父亲和儿子组件通讯。兄弟组件略为复杂性,兄弟组件通过分享父组件的事态来举行通讯。若是那样的光景,笔者点击站点,希望可以弹出音信提醒窗,那正是Station 组件和 InfoCard 组件之间的通讯,通过 Map 组件来张开分享。点击 Station 组件触发事件,通过回调更新 Map 组件状态的翻新,同有时间也兑现了 InfoCard组件的改善。同期为了兑现,点击任何区域就足以关闭新闻指示窗,我们对 Map 组件实行监听,监听事件的冒泡来达成快速的关闭,当然为了防止有个别不供给的冒泡,还亟需在有的事件处理中阻止事件冒泡。
InfoCard 是无比复杂的多少个构件,因为在那之中包涵了一些个 icon,以致气象音信的切换,同偶然间须要完结切换分裂的站点的时候能够立异消息提示窗。须要注意信息提示窗音信初次点击消息的早先化,以至切换分裂icon 时分别显示分化的音信,比如卫生间音信可能出入口音信,以至对那个时候刻表,切换差别的线路的时候更新对应的时刻表。那几个意况的转会,需求值得注意。其余值得风流洒脱题的点正是,在切换不一样站点的时候的情况,假若本人正在看有个别站点的盥洗室新闻的时候,作者点击别的五个站点,这时弹出的新闻提醒窗应该是时刻表音讯照旧卫生间新闻吗?作者的精选依旧卫生间新闻,作者对此那黄金时代情况进行了保证,那样的客户体验从逻辑上来说仿佛更佳。具体落到实处的代码细节就异常的小器晚成一表达了,里面肯能包涵更加多的内部原因,迎接使用体验。
props: ['initialCounter'],
data: function () {
return { counter: this.initialCounter }
}
结语
花了三个礼拜的年华完成了种类的整体的重构,从今年来的 commit 记录能够看来5月份发狂 commit 了一波,首假如第两个周末花费了二日的岁月修正了重重代码,被丰富 InfoCard的情状切换搞了相当久,前面就是本着质量做了生龙活虎部分优化。进程好痛楚,生机勃勃度嫌疑本身的 coding 技巧。可是最终仍然有以下感悟:
- 世界上没有最佳的语言,最棒的框架,只有最合适的
- 最文雅的完结都不是轻巧的,都以三个个试出来的
终极一个冷笑话:
妙龄问禅师:“请问大师,作者写的顺序为啥未有赢得预期的输出?” 禅师答到:“年轻人,那是因为您的主次只会按你怎么写的实行,不会按你怎么想的施行啊……”
源代码地址,欢迎 star 或者 pr。
1 赞 收藏 评论
var vm = new Vue({
el: '#example',
data: {
currentView: 'home'
},
components: {
home: { /* ... */ },
posts: { /* ... */ },
archive: { /* ... */ }
}
})
<component v-bind:is="currentView">
<!-- 组件在 vm.currentview 变化时改变! -->
</component>
兼容性
时下该应用在 Chrome 浏览器的帮衬性是最棒的,安卓浏览器建议安装 Chrome 浏览器选择,笔者日常也都相比较赏识在手提式无线电话机上接纳谷歌(Google卡塔 尔(英语:State of Qatar)浏览器。对于 Safari 浏览器,别的的浏览效率就像是从未什么大难点,近来理应还未扶植增添到主荧屏。可是在那后的 ios 版本好像对于 pwa 有着更进一层的支持。
v-model 的片段坑
异步
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);
}
}
|
那样大家就能够创制贰个生生不息向右移动的卡通片,提醒顾客向右滑动。计划之后察觉质量分立马减低到0,索性也就丢掉了那么些做法。最后来时间调整制动用
transform: translateX(-200px) translateY(-300px);
,因为那样经过 css3
的天性可以在风度翩翩部分移动设备上还是能够行使 GPU 加快,并且 translateX
不会孳生页面包车型客车重绘只怕重排,只会促成图层重新组合,最小制止对质量的熏陶。
能够接收方面深度监听。假若伊始化的时候要立时实行,我们得以用当下施行监听!
同步
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) {
...
}
}
...
}
|
prop 对象数组应用
准备
计划干活先做好,在 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 音信。还应该有,我们还须要获得每种站点的时刻表消息,卫生间地点音信,无障碍电梯音讯以及出入口消息。这里是写了部分爬虫去官方网址爬取并做了部分数额管理,再度就不意气风发生龙活虎赘述。
require动态加载重视
pwa重构东京大巴线路图
2018/03/28 · JavaScript · PWA
初藳出处: Neal
事先平昔有在保险一个北京大巴线路图的 pwa,最重大的风味便是 “offline first”。可是由于代码都以经过原生的 js 去完毕,早先小编都不是很欢悦去用框架,不想具有其余框架的偏疼。可是到末代随着代码量的增添,代码的确变得混乱不堪,扩充新职能也变得更其困难。因而,花了周围多少个礼拜的时候对于使用实行了叁次完整的重构。网址访问地址:
数据源.splice(indexOfItem, 1, newValue)
部署
时下的配备方案是行使 create-react-app 的法定建议,通过 gh-pages 完成将 build 的打包文件上传到 gh-pages 分支上进而完毕陈设。
措施风度翩翩:component 和is协作使用
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
2、 通过Array.prototype.splice方法
咱俩在等级次序中,日常会用超多景观大概数额,大家得以把众多公共数据分离出来,放到二个指标中,前边我们能够监听这一个数额对象变化。进行数据保存照旧获得。
公家性质分离
我们得以行使require同步个性,在代码中动态加载依赖,比如上边echart主旨,我们得以点击切换的时候,动态加载!
import加载要放权底部,开首化的时候,能够把暗中同意宗旨用import加载进来!
具有应用到itemData之处都会扭转!
1、通过vue.set格局赋值
重构-动态组件的创办
vue数据更新, 视图未更新
c: {
handler: function (val, oldVal) { /* ... */ },
deep: true
},
// 该回调将会在侦听开始之后被立即调用
d: {
handler: function (val, oldVal) { /* ... */ },
immediate: true
},
3、改良数据的长度