浅谈vue项目重构技术大旨和总括,项目总结

pwa重构香岛大巴线路图

2018/03/28 · JavaScript
· PWA

原稿出处:
Neal   

前边一向有在维护一个香岛客车线路图的 pwa,最首要的特色就是 “offline
first”。可是出于代码都是透过原生的 js
去贯彻,以前我都不是很欣赏去用框架,不想拥有其余框架的偏好。不过到末代随着代码量的扩展,代码的确变得混乱不堪,拓展新功效也变得更为困难。由此,花了濒临八个礼拜的时候对于使用举办了三回完整的重构。网站访问地址:

前言

浅谈vue项目重构技术宗旨和统计,vue技术要点

前言

方今太忙了,博客好久没有革新了。明日忙里偷闲,不难总计一下以来vue项目重构的局地技艺要旨。

vue数据更新, 视图未更新

以此题目大家常常会遭遇,一般是vue数据赋值的时候,vue数据变化了,不过视图没有更新。那些不算是项目重构的技能中央,也和大家分享一下vue2.0平时的解决方案吧!

化解方案如下:

1、通过vue.set格局赋值

Vue.set(数据源, key, newValue)

2、 通过Array.prototype.splice方法

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

3、修改数据的尺寸

数据源.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加载进来!

以上就是本文的全体内容,希望对大家的求学抱有协助,也意在我们多多帮助帮客之家。

前言
方今太忙了,博客好久没有创新了。前日忙里偷闲,简单总括一下以来vue项目重构的一…

事情扩张,IOS和安卓都有成型的本子,所以要做一个对应的位移端H5版的机票订,买票应用,入口是微信公众号,当然少不了jssdk的施用,以及balabala的授权处理等。最初是考虑用React+Redux+Webpack,前后端完全分离,但考虑到人手不足,前后端暂时做不了完全分开,然后还有对React也不熟知,项目时间等问题,然后就被Boss否了。
终极用了更谙习的Vue+Vuex+Webpack。主要仍旧因为更轻,API尤其协调,上手速度更快,加上社团里有人熟知,可以即时开工。比较遗憾的是因为各类缘由前后端分离还不是很绝望,前端用的是jsp模板加js渲染页面。好处是首屏数据足以停放script标签里面直出,在进度条读完的时候页面就可见渲染出来了,进步首屏渲染时间。可是调试的时候极度劳神,因为尚未Node做中间层,每趟都要在本地完整地跑个服务器,不然拿不到多少。
Vue,Vuex,Vue-router,Webpack这几个不理解的同室就去看看文档。MV*框架用好了实在是极大地解放生产力,更加是页面的互相非常复杂的时候。

准备

未雨绸缪工作先做好,在 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项目重构的一对技巧中央。

品类进度中蒙受的坑

1.
蒙受的率先个的坑就是transition。首页有一个滑行的banner,我是向来用css3的transition协作js定时改变transform已毕的。
滑动在chrome中效仿没问题,ios中没问题,但是安卓中就平昔不滑动,百思不得其解。开首还认为是包容性问题,搞了长久才察觉须要在css中先扩充一个transform:
translateX(0)
,像下边一样,不然事后再经过js更改transform是无可怎么样在安卓中触发transition的。
123456

.slide-wp{ transform: translateX(0); -webkit-transform: translateX(0);
transition: transform 1.5s ease; -webkit-transition: transform 1.5s
ease;}

世家驾驭,transition的功用是令CSS的属性值在听之任之的时光间隔内平滑地连接。
之所以个人算计,在安卓中,当没有开头值时,translateX
的转移没有被平整地联网,就是说transition并不知道translateX
是从什么地点开端接入的,所以也就从未平滑之说,也就从未有过动画了。

2.
第四个就是ES6。既然用了Webpack,当然就要合作Bebel用上ES6呀。写的时候照旧很爽的。let
,const
,模块,箭头函数,字符串模版,对象属性简写,解构等等…但帅可是3秒,在chrome上模仿地跑一点题材都未曾,一到运动端就径直白屏,页面都尚未渲染出来。
排查了许久,才发现是某些增加运算符…
浅谈vue项目重构技术大旨和总括,项目总结。,某些解构和for…of…
循环的题材。因为那一个ES6的特色(其实不指那么些)在Bebel中改换是要用到[Symbol.iterator]接口的。如上边那样。转码前:
12

const [a, b, c, d, e] = ‘hello’;console.log(a, b, c, d,
e);//’h’,’e’,’l’,’l’,’o’

转码后:
123456789101112131415

‘use strict’;var _slicedToArray = (function () { function
sliceIterator(arr, i) { var _arr = []; var _n = true; var _d =
false; var _e = undefined; try { for (var _i =
arrSymbol.iterator, _s; !(_n
= (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i
&& _arr.length === i) break; } } catch (err) { _d = true; _e = err; }
finally { try { if (!_n && _i[‘return’])
_i’return’; } finally { if
(_d) throw _e; } } return _arr; } return function (arr, i) { if
(Array.isArray(arr)) { return arr; } else if (Symbol.iterator in
Object(arr)) { return sliceIterator(arr, i); } else { throw new
TypeError(‘Invalid attempt to destructure non-iterable instance’); } };
})();var _hello = ‘hello’;var _hello2 = _slicedToArray(_hello,
5);var a = _hello2[0];var b = _hello2[1];var c = _hello2[2];var
d = _hello2[3];var e = _hello2[4];console.log(a, b, c, d,
e);//’h’,’e’,’l’,’l’,’o’

首先行先表明的_slicedToArray函数用到了[Symbol.iterator]接口,然则浏览器对那一个接口的支撑还很有限,更加是移动端,唯有Firefox
Mobile36本子以上才支撑,其余清一色挂掉。
如下图所示:

亚洲必赢官网 1

博客图片

由此说ES6虽好,但真要用到实在项目中的话,还不可能太激进,有些特性经过Bebel转码后性能上可能还会怀有下滑,所以照旧应该合理地接纳ES6。如若是团结折腾倒无所谓,Symbol,Class,Generator,Promise那几个就不管炫技吧。

3.
第一个坑就是Vue使用的题目。如其身为坑,依然不如说是我自身还不够熟稔Vue。先看一下合法证实:
受 ES5 的限定,Vue.js 不可能检测到对象属性的增加或删除。因为 Vue.js
在早先化实例时将性能转为 getter/setter,所以属性必须在 data 对象上才能让
Vue.js 转换它,才能让它是响应的。

马上亟需在props传来的少数对象数据中加进一个是不是可视属性,用来控制一个与其关系的弹出框。伸张后点击视图上某些反馈都并未,但是用console.log
打印出来发现值的确的有转移的。
也就是说,数码的变化不可以触发视图更新。原因就是如下面所说,因为那些特性是自家后来加上的,不可能被Vuejs检测到。那时候需求利用$set(key,
value)这个API。
话说里面的语法需求留意下,第三个参数key
是一个字符串,是一个keypath
,假如假设你的数量是如此:
123456789101112

data(){ visitors : [{ “id”: 1, … }, { “id”: 2, … }, { “id”: 3, …
}],}

你需求在某次操作后为visitiors
里面的各类对象增添一个show
性能,则须要那样写:
12345

let str;for (let i = 0 , len = this.visitors.length ; i < len; i++) {
str = “visitors[” + i + “].show”; this.$set(str,true);}

事先确实被那东西搞了很久,明明数据变动了,视图却不更新。个人感觉新手刚使用Vue时很难发现这些题材。也怪自己对Vue,对ES5的getter/setter
的明亮还不够呢。

4.
第五个是IOS上的滚动问题。在好几浏览器下,例如微信内嵌浏览器,手指在显示屏上滑动时,页面会进入momentum
scrolling(弹性滚动)。那时候会甘休所有的事件响应DOM操作引起的页面渲染,onscroll事件不会触发,CSS3动画,gif那一个也不会动,一直到滑动截止。
因为急需onscroll事件来实施懒加载等操作,不过在IOS中是要等到滑动甘休后才能实施的,用户体验不佳。当时google了很久,最后得出的下结论是,并从未怎么很好的解决方案。所以暂时只好在IOS上首次加载越多资源了。
贴一个在segmentfault上的答案吧,很好地统计了那一个题材。(戳这里)

5.
首个仍旧IOS上CSS3动画的问题,前几天才蒙受的。在对img或者安装了background-image的DOM元素设置CSS动画时,动画在刚进去页面的时候有可能不被触发,要求滑动一下显示屏动画才动,安卓下则尚未问题。
刚初始还认为是没有安装开始值的题目,但感觉不应有会是这么的。后来在stackoverflow上找到通晓决办法(戳这里)。给动画加个0.1s秒的延时
12

animation: slide 1.5s 0.1s linear infinite;webkit-animation: slide 1.5s
0.1s linear infinite;

原因大概是如若Safari和IOS的微信内置浏览器在加载资源,或者举办哪些内部渲染操作时现身了短短的中止(英文是hiccups),则不会接触动画,必要滑动一下页面来重新触发。所以给动画加个0.1s延时确保资源加载成功后,问题得以化解。

有关Vue的组件化
先上个@xufei大大的博客,里面有多关于组件化的小说,都是满满的干货。
其实组件化是一个很巨大的话题,我那等小白的认识还格外显浅,不过既然在品种中用到了组件化,也就谈谈自己的意见吧。
Vue的组件化需求卓殊Webpack+vue-loader 或者 Browserify + vueify
来构建。一个.vue文件一个零件,上手了写起来是分外高速的,但是对此新手或者即将花点时间去熟识工具了。
此前在看了@xufei的博客加上自己的工程进行后,表示分外赞成他的传道:
成千成万人会把复用作为组件化的首先须求,但实际上,在UI层,复用的市值远远比不上分治。

亚洲必赢官网,专门是对于.vue那种样式的组件化来说,想做到复用往往要求形成内部贯彻高度抽象,并对外暴光很多接口,而复用的地点也并不是不少。很多时候,花那么多日子去贯彻一个零部件复用,还不如新建一个零部件,复制部分代码,重新进行内部贯彻来得更快。
要精通一个.vue文件里面除了<template>
、<style>
,还有<script>
。前两者用于落到实处组件的体制展现,对于许多地点来说,可能只是有所些许出入,但<script>
内部的东西则是意味着着组件的里边逻辑完毕,这几个逻辑往往有着很大的两样。

亚洲必赢官网 2

图1

亚洲必赢官网 3

图2

如上面的图1,图2。从体制上看,分化的地点只是是图2的种种常用乘机人多了一个复选框勾选,就如能够经过某个标记来预订是或不是出现勾选框来达到组件复用。
但实在,因为那多少个零件所身处的事体页面的不等而留存着较大的其中逻辑落成差别。
像图1,是在本人的板块里面的。里面唯有是一个司乘人士体现和乘客新闻编辑的职能,相对相比独立。而图2则是在订单确认页面里面的,除了游客浮现和乘客音讯编辑外,还有接纳乘客的功力。点了封存后会与订单状态暴发互动,而且订单状态的变更还会反过来影响着这个乘客音讯的景况,远比图1里头的繁杂。
只要强行抽象中集体部分,对外揭示各类API来令该零件可复用,除了落到实处资金和有限扶助资金高外,其复用得到的价值也不高。还不如写多一个零部件,复制其样式部分,重新完毕内部逻辑来得实在。而且将三个零部件放在不一致的板块内,互相独立,也方便管理和护卫。
那怎么的机件才符合复用?我个人觉得,唯有很少内部逻辑的展现型组件才符合复用。像导航栏,弹出层,加载动画那个。而任何的局地组件往往只在两三页面存在复用价值,是还是不是抽象分离出来,就要看个人选用了。

关于Vuex
Vuex 之于 vue,就一定于 Redux 之于
React。它是一套数据管理架构已毕,用于解决在巨型前端选用时数据流动,数据管理等题材。
因为零部件一旦多起来,差异组件之间的通信和数码流动会变得这几个麻烦及难以追踪,特别是在子组件向同级子组件通讯时,你恐怕须求先$dispatch到父组件,再$broadcast给子组件,整个事件流至极繁杂,也很难调试。
Vuex就是用来化解那个题目标。更具象的证实可以看文档,我就可是多叙述了。我就说一下我对Vuex的一部分明亮。
Vuex里面的数据流是单向的,似乎官方说的那样:
用户在组件中的输入操作触发 action 调用;
Actions 通过分发 mutations 来修改 store 实例的场馆;
Store 实例的气象变化反过来又经过 getters 被组件获知。

亚洲必赢官网 4

vuex

同时为了有限支撑数据是单向流动,并且是可监控和可预测的,除了在mutation
handlers 外,其余地点不容许直接改动 store 里面的 state。
个人觉得store就是一个类数据库的东西,处于整个应用的最下面,每个组件之间共享数据,并透过actions来对数码进行操作。在如此的知晓下,我更倾向于把mutations类比为查询语句,即只在mutations里面进行增删查改,筛选,排序等局地简练的逻辑操作,也切合是一道函数的牢笼。就像是这么
12345678910111213141516171819202122232425

const mutations = { //设置常用乘机人列表 SET_PSGLIST(state, psgList){
state.psgList = psgList; }, //扩大在订单中的乘客 ADD_ORDERPSG(state,
orderPsg){ for (let i = 0,len = state.orderPsgList.length; i < len;
i++) { if (state.orderPsgList[i].id == orderPsg.id) {
state.orderPsgList[i] = orderPsg; return; } }
state.orderPsgList.push(orderPsg); }, //删除在订单中的乘客REMOVE_ORDERPSG(state, orderPsg){ for (let i = 0,len =
state.orderPsgList.length; i < len; i++) { if
(state.orderPsgList[i].id == orderPsg.id) {
state.orderPsgList.splice(i,1) return; } } }}

更扑朔迷离的逻辑则写进actions中。例如我要在action中先异步获取常用乘机人数据,并起始化:
12345678910111213141516171819202122232425262728293031

//actionexport const iniPsgList = ({ dispatch }, uid) =>{ let data =
{ uid: uid, } $.ajax({ url: “../passenger/list”, data: data,
success(data){ let jsonData = JSON.parse(data); let psgs =
jsonData.data.passengers; dispatch(‘SET_PSGLIST’, psgs); }, error(){
console.log(‘获取常用乘机人列表音讯错误’); } }) }//组件中调用import {
iniPsgList } from ‘./actions’const vm = new Vue({ created(){
this.iniPsgList(uid); }, vuex: { getters: { … }, actions: iniPsgList,
}})

或者,为了令actions完结得更其通用,你一点一滴能够给种种mutation对应写一个action,每个action就只是分发该mutation,不做任何额外的工作。然后再在组件中引入这么些actions。那样其实就一定于在组件中触发mutations,从而收缩action那一个流程。
123456789

function makeAction(type , data){ return ({ dispath }, data) => {
dispatch( type , data) }}export const setPsgList =
makeAction(‘SET_PSGLIST’, psgList)export const addOrderPsg =
makeAction(‘ADD_ORDERPSG’, orderPsg)export const removeOrderPsg =
makeAction(‘REMOVE_ORDERPSG’, orderPsg)

那儿发轫化常用乘机人列表,则是这么写。
1234567891011121314151617181920212223242526

//组件中调用import { setPsgList } from ‘./actions’const vm = new Vue({
created(){ let data = { uid: uid, } $.ajax({ url: “../passenger/list”,
data: data, success: (data) = > { let jsonData = JSON.parse(data);
let psgs = jsonData.data.passengers; this.setPsgList(psgs); }, error(){
console.log(‘获取常用乘机人列表音讯错误’); } }) }, vuex: { getters: {
… }, actions: setPsgList, }})

互相的不一样就仅是把异步等局地更复杂的逻辑放在action中要么放在组件内部逻辑中。前者的action更有针对性,更具有唯一性;后者的action仅仅就是一个触发mutation的效果,而组件则与越多的逻辑耦合。
什么人优什么人劣很难说清,和个体喜欢、业务逻辑等有较大关系。我在项目中应用的是后一种用法,因为我个人更爱好在组件完毕更加多的内部逻辑,方便未来针对改组件的调节和保险,免得还要在action中摸索一遍。
莫名其妙地扯了这么多,其实都是局地总计与综合。

设计

数量准备好未来,就是应用的筹划了。首先,对组件举行几次拆分:

vue数据更新, 视图未更新

零件结构

将全部地图知道成一个 Map 组件,再将其分为 4 个小器件:

亚洲必赢官网 5

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

那是一个光景的零件划分,里面可能带有更加多的其他元素,比如 InfoCard 就有
InfoCard => 提姆eSheet => 提姆(Tim)esheetTable 那样的嵌套。

本条题目我们平常会遇见,一般是vue数据赋值的时候,vue数据变动了,但是视图没有立异。这一个不到底项目重构的技巧中央,也和豪门享受一下vue2.0平日的解决方案吗!

零件通讯和情景管理

地面开发的最大的困难应该就是这一块的始最终。本来出于组件的层级并不算更加复杂,所以自己并不打算上
Redux
那连串型的大局状态管理库。主要组件之间的通讯就是父子通讯和兄弟组件通信。父子组件通讯相比较简单,父组件的
state 即为子组件的
props,能够通过那几个完成父子组件通讯。兄弟组件略为复杂性,兄弟组件通过共享父组件的意况来展开通信。要是那样的场景,我点击站点,希望可以弹出音讯提示窗,那就是
Station 组件和 InfoCard 组件之间的通讯,通过 Map 组件来开展共享。点击
Station 组件触发事件,通过回调更新 Map 组件状态的换代,同时也完结了
InfoCard
组件的更新。同时为了完成,点击任何区域就可以关闭音讯提示窗,我们对 Map
组件进行监听,监听事件的冒泡来已毕高效的倒闭,当然为了幸免有些不须要的冒泡,还要求在一部分事件处理中梗阻事件冒泡。

亚洲必赢官网 6

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);
  }
}

亚洲必赢官网 7

这么我们就可以创制一个巡回向右移动的卡通片,提示用户向右滑动。布署之后察觉性能分立马降到
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、修改数据的长短

结语

亚洲必赢官网 8

花了多少个礼拜的时刻落成了项目标完整的重构,从这一年来的 commit
记录可以见到2月份发狂 commit
了一波,紧倘使率先个礼拜二消费了二日的光阴修改了众多代码,被更加 InfoCard
的事态切换搞了很久,后边就是指向性能做了部分优化。进度很痛楚,一度可疑自己的
coding 能力。可是最后照旧有以下感悟:

  • 世界上没有最好的语言,最好的框架,只有最合适的
  • 最优雅的完毕都不是不难的,都是一个个试出来的

说到底一个冷笑话:

青春问禅师:“请问大师,我写的程序为何没有拿走预期的出口?”
禅师答到:“年轻人,那是因为你的先后只会按您怎么写的实践,不会按您怎么想的举办啊……”

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

 

1 赞 收藏
评论

亚洲必赢官网 9

数据源.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基于百度地图组件重构笔记分享
网站地图xml地图