2017年8月10日(為什么記得這么清楚~),加入了易鑫铝阐,之前公司是做p2p薯演,屬于c端項目贸诚,當時項目的框架是公司自己開發(fā)的前端框架耻姥,后面在項目優(yōu)化的過程中销钝,我們單獨引入了vue.js,出于開發(fā)成本考慮琐簇,項目全部改造成vue全家桶項目成本太高(vue+vue-router+vuex+axios+es6+sass)蒸健,沒有這個時間成本去替換。在使用vue的過程中婉商,真的喜歡上了這個框架似忧,入門簡單,易用丈秩,還便于與第三方庫或既有項目整合盯捌,數(shù)據(jù)驅(qū)動的模式,讓我們不用頻繁的去處理dom癣籽,而是關(guān)注與數(shù)據(jù)的處理挽唉。
一 淘車拍app的開發(fā)(h5)
來到易鑫之后,當時前端人手比較少筷狼,大家都在leader的帶領(lǐng)下做c2b后臺的開發(fā)瓶籽,淘車拍app根據(jù)實際情況采用的混合app開發(fā),h5項目我采用的是vue全家桶埂材。
由于項目是b端的塑顺,想比c端業(yè)務(wù)場景更加復雜,在項目開發(fā)主要難點有:
1.各個組件數(shù)據(jù)的共享
傳參的方法對于多層嵌套的組件將會非常繁瑣俏险,并且對于兄弟組件間的狀態(tài)傳遞無能為力严拒。而且也會導致代碼難以維護
解決方法:采用vuex進行狀態(tài)管理,把所有事件和狀態(tài)存儲在store對象中竖独,在組件中通過計算屬性獲得事件裤唠,因此就有了實時性。
Vuex 是一個專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式莹痢。它采用集中式存儲管理應(yīng)用的所有組件的狀態(tài)种蘸,并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預測的方式發(fā)生變化墓赴。每一個 Vuex 應(yīng)用的核心就是 store(倉庫)『讲t!眘tore” 基本上就是一個容器诫硕,它包含著應(yīng)用中大部分的狀態(tài)(state)。Vuex 的狀態(tài)存儲是響應(yīng)式的刊侯。當 Vue 組件從 store 中讀取狀態(tài)的時候章办,若 store 中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會相應(yīng)地得到高效更新滨彻。你不能直接改變 store 中的狀態(tài)藕届。改變 store 中的狀態(tài)的唯一途徑就是顯式地提交(commit) mutations。這樣使得我們可以方便地跟蹤每一個狀態(tài)的變化疮绷。
經(jīng)澈采啵看到小伙伴們?yōu)槭裁从胿ux,什么時候使用vux冬骚?
引用 Redux 的作者 Dan Abramov 的話說就是: Flux 架構(gòu)就像眼鏡:您自會知道什么時候需要它。
vux官方文檔地址:vuex
vue調(diào)試神器vue-devtools:vue-devtools
2.項目結(jié)構(gòu)復雜
由于我們的業(yè)務(wù)涉及c2b業(yè)務(wù)以及車商工具業(yè)務(wù)懂算,項目結(jié)構(gòu)比較復雜只冻。
解決辦法:在項目中,我們將組件和頁面计技,router以及api喜德,按照業(yè)務(wù)模塊化開發(fā)。降低耦合垮媒,提高模塊的維護性舍悯。
eg:api模塊化
import base from './base';
import common from './common';
import auction from './auction';
import sales from './sales';
import overhaul from './overhaul';
import purchase from './purchase';
import assess from './assess';
import inventory from './inventory';
export default {
...base,
...common,
...auction,
...sales,
...overhaul,
...purchase,
...assess,
...inventory,
};
技術(shù)棧
1、Vue全家桶(vue2睡雇、vue-router萌衬、vuex) 快速開發(fā)SPA神器
2、Axios vue作者推薦的數(shù)據(jù)請求方案
3它抱、ES6 全面過度es6的寫法 趨勢
4秕豫、Webpack2,vue-cli 腳手架已經(jīng)配置好了
5、flex布局 對于移動端可以放心大膽的使用
6观蓄、移動端屏幕適配 采用手淘的flexible+rem方案
二混移、es6語法
1.兩種新的聲明變量的方法
①let,用法類似于var侮穿,但是所聲明的變量歌径,只在let命令所在的代碼塊內(nèi)有效。
特點1.塊級作用域亲茅。2.不存在變量提升回铛。3.不允許重復聲明
②const金矛,const聲明一個只讀的常量。一旦聲明勺届,常量的值就不能改變驶俊。const一旦聲明變量,就必須立即初始化免姿,不能留到以后賦值饼酿。只在聲明所在的塊級作用域內(nèi)有效。
2.變量的解構(gòu)賦值
解構(gòu)賦值允許你使用類似數(shù)組或?qū)ο笞置媪康恼Z法將數(shù)組和對象的屬性賦給各種變量胚膊。這種賦值語法極度簡潔故俐,同時還比傳統(tǒng)的屬性訪問方法更為清晰
①數(shù)組的解構(gòu)賦值
數(shù)組的元素是按次序排列的,變量的取值由它的位置決定
let [a, b, c] = [1, 2, 3]
a // 1
b // 2
c // 3
let [head, ...tail] = [1, 2, 3, 4]
head // 1
tail // [2, 3, 4]
*默認值
let [foo = true] = [];
foo // true
eg:
//返回一個數(shù)組
function example(){
return [1,2,3];
}
let [a,b,c]=example();
②對象的結(jié)構(gòu)賦值
對象的屬性沒有次序紊婉,變量必須與屬性同名药版,才能取到正確的值
let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
*默認值
var {x = 3} = {};
x // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
eg:
*將現(xiàn)有對象的方法,賦值到某個變量喻犁。
//將Math對象的對數(shù)槽片、正弦、余弦三個方法肢础,賦值到對應(yīng)的變量上
let { log, sin, cos } = Math
// 返回一個對象
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
*提取json數(shù)據(jù)
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]
③字符串的解構(gòu)賦值
const [a, b, c, d, e] = 'hzzly'
a // "h"
b // "z"
c // "z"
d // "l"
e // "y"
④函數(shù)參數(shù)的解構(gòu)賦值
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
3.函數(shù)的擴展
①函數(shù)參數(shù)的默認值
*參數(shù)變量是默認聲明的还栓,所以不能用let或const再次聲明
*通常情況下,定義了默認值的參數(shù)传轰,應(yīng)該是函數(shù)的尾參數(shù)
function log(x, y = 'World') {
console.log(x, y);
}
log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello
②與解構(gòu)賦值默認值結(jié)合使用
function foo({x, y = 5}) {
console.log(x, y);
}
foo({}) // undefined, 5
foo({x: 1}) // 1, 5
foo({x: 1, y: 2}) // 1, 2
foo() // TypeError: Cannot read property 'x' of undefined
③reset參數(shù)
ES6 引入 rest 參數(shù)(形式為“…變量名”)剩盒,用于獲取函數(shù)的多余參數(shù),這樣就不需要使用arguments對象了慨蛙。rest 參數(shù)搭配的變量是一個數(shù)組辽聊,該變量將多余的參數(shù)放入數(shù)組中。
rest 參數(shù)之后不能再有其他參數(shù)(即只能是最后一個參數(shù))期贫,否則會報錯
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10
function push(array, ...items) {
items.forEach(function(item) {
array.push(item);
console.log(item);
});
}
var a = [];
push(a, 1, 2, 3)
④擴展運算符(…)
*它好比 rest 參數(shù)的逆運算跟匆,將一個數(shù)組轉(zhuǎn)為用逗號分隔的參數(shù)序列。
*擴展運算符內(nèi)部調(diào)用的是數(shù)據(jù)結(jié)構(gòu)的Iterator接口
console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]
function push(array, ...items) {
array.push(...items);
}
function add(x, y) {
return x + y;
}
let numbers = [4, 38];
add(...numbers) // 42
eg:
*替代數(shù)組的apply方法
// ES5的寫法
Math.max.apply(null, [14, 3, 77])
// ES6的寫法
Math.max(...[14, 3, 77])
// 等同于
Math.max(14, 3, 77);
*合并數(shù)組
// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]
var arr1 = ['a', 'b'];
var arr2 = ['c'];
var arr3 = ['d', 'e'];
// ES5的合并數(shù)組
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6的合并數(shù)組
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
與解構(gòu)賦值結(jié)合
const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest // [2, 3, 4, 5]
const [first, ...rest] = [];
first // undefined
rest // []:
const [first, ...rest] = ["foo"];
first // "foo"
rest // []
⑤箭頭函數(shù)
一 箭頭函數(shù)可以讓this指向固定化唯灵,這種特性很有利于封裝回調(diào)函數(shù)
(1)函數(shù)體內(nèi)的this對象贾铝,就是定義時所在的對象,而不是使用時所在的對象埠帕。
(2)不可以當作構(gòu)造函數(shù)垢揩,也就是說,不可以使用new命令敛瓷,否則會拋出一個錯誤叁巨。
(3)不可以使用arguments對象,該對象在函數(shù)體內(nèi)不存在呐籽。如果要用锋勺,可以用Rest參數(shù)代替蚀瘸。
(4)不可以使用yield命令,因此箭頭函數(shù)不能用作Generator函數(shù)庶橱。
var f = () => 5;
// 等同于
var f = function () { return 5 };
var f = v => v;
//等同于:
var f = function(v) {
return v;
};
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
*箭頭函數(shù)簡化回調(diào)函數(shù)
// 正常函數(shù)寫法
[1,2,3].map(function (x) {
return x * x;
});
// 箭頭函數(shù)寫法
[1,2,3].map(x => x * x);
*箭頭函數(shù)可以讓setTimeout里面的this贮勃,綁定定義時所在的作用域,而不是指向運行時所在的作用域
function Timer() {
this.s1 = 0;
this.s2 = 0;
// 箭頭函數(shù)
setInterval(() => this.s1++, 1000);
// 普通函數(shù)
setInterval(function () {
this.s2++;
}, 1000);
}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3
// s2: 0
*因為所有的內(nèi)層函數(shù)都是箭頭函數(shù)苏章,都沒有自己的this寂嘉,它們的this其實都是最外層foo函數(shù)的this
function foo() {
return () => {
return () => {
return () => {
console.log('id:', this.id);
};
};
};
}
var f = foo.call({id: 1});
var t1 = f.call({id: 2})()(); // id: 1
var t2 = f().call({id: 3})(); // id: 1
var t3 = f()().call({id: 4}); // id: 1