Vue + ElementUI 後臺管理系統項目心得(一)

最近參與了公司的 Vue + ElementUI 後臺管理系統開發,目前項目告一段落,正好作一個總結。javascript

本文件分三部分進行,其一是 JavaScript 部分,其二是 Vue 部分,最後是 ElementUI 部分。java

1、對JavaScript的理解

1. 如何複製一個Js對象?

在 C#,Java 等面向對象的高級語言中,能夠直接經過 '=' 賦值操做符複製一個對象,若是想定義一個指向對象的代理要用到指針定義,然而 Js 早期出於性能的考慮,默認將 '=' 賦值操做符用於定義一個指向對象的指針。數組

var a = { prop: 'val' }
var b = a
a.prop = 'nothing'
console.log(b.prop) // 'nothing'複製代碼

不管怎樣 「複製」,新對象老是指向原始對象,原始對象發生改變,新對象也天然改變。如何複製對象呢?咱們知道,對象能夠互相嵌套,即對象屬性能夠是另外一個對象,那麼經過普通的循環遍從來複制原對象的屬性到一個新對象中是沒法確保二者保持一致的,所以這種複製也被稱做 「淺拷貝」。相對的經過遞歸遍從來複制對象的方式也被稱做 「深拷貝」。函數

// 淺拷貝
function extendCopy(p) {
  var c = {};
  for (var i in p) { 
    c[i] = p[i];
  }
  c.uber = p;
  return c;
}複製代碼
// 深拷貝
function deepCopy(p, c) {
  var c = c || {};
  for (var i in p) {
    if (typeof p[i] === 'object') {
      c[i] = (p[i].constructor === Array) ? [] : {};
      deepCopy(p[i], c[i]); // 遞歸調用
    } else {
       c[i] = p[i];
    }
  }
  return c;
}複製代碼

固然,能夠在項目中引入函數庫(如 utils.js)來方便的引用這些擴展函數,不過咱們不得不想有沒有更簡潔的方式來實現呢?答案是確定的。性能

// utils.js
export const extendCopy(p) {...}
export const deepCopy(p, c) {...}複製代碼
// page.js
import {extendCopy, deepCopy} from utils.js
a = {...}
b = extendCopy(a)複製代碼

通常還能夠經過以下方式解決:ui

  • 經過 JSON 對象提供的 stringifyparse 方法組合使用的方式實現。
// 勉強也算一句話解決了,問題在於性能不理想。
var a = {}
var b = JSON.parse(JSON.stringify(a))複製代碼
  • 經過在函數中以返回值的形式生成新對象。
// 這種方式的缺點在於要以字面量的形式定義一個原始對象做爲模板。
a = function() { 
return { prop:"123" } 
}
b = a()
d = a()
b === d // false複製代碼
  • 經過 ES2015 中提供的 Object.assign() 方法來複制。
// 簡潔明瞭,性能良好的解決方案
var a = {}
var b = Object.assign({},a)複製代碼

經過上面的例子,咱們不可貴出一個結論:使用 Object.assign() 方法複製一個對象是比較理想的解決方案。spa

2. 如何判斷一個元素是否在集合中

早期的 Js 標準中並無實現相似 array.contains(item) 的方法,所以只能經過元素在集合中的索引判斷。(感謝 XiaozhongLiu 的提醒,ES7中已加入 Array.includes() 方法。)代理

// 傳統寫法
var isSelected = function(row) {
  return (selection || []).indexOf(row) > -1;
}

// ES7寫法,簡潔了許多
isSelected = selection.includes(row)複製代碼

3. 判斷一個變量是否爲非空對象

首先 null 的類型是對象,若是在控制檯輸入 typeof null 會返回 "object",事實上咱們要檢測一個非空數組,就要先排除 null 值的可能。指針

var isObject = function(obj) {
  return obj !== null && typeof obj === 'object'
}複製代碼

4. 如何查詢一個數組並返回元素的子集

這裏用到了數組的 filter 方法,此方法具備如下特色:code

  1. 須要傳入一個回調函數做爲參數,此函數應返回一個布爾值。
  2. filter 執行時會對數組中的每個元素執行一遍回調函數。
  3. filter 的返回值爲一個新數組,其成員爲原數組中返回值爲 true 的元素。
var users = allUsers.filter((user) => user.loged === true)複製代碼

5. 如何判斷一個對象沒有任何屬性

在 Js 中兩個空對象進行比較會有什麼結果呢?

var a = {}
a === {} // false複製代碼

在 Js 中對 object 類型的數據應用 「等於」 操做符時,比較的是兩個變量是否指向同一個引用,也就是說在內存中是否爲同一個地址。

而咱們期待的結果是比較兩個對象在邏輯上是否具備相同的屬性,空對象是一個特例,它們不具備任何屬性。

if (Object.keys(search).length !== 0) {
    args = Object.assign({}, args, search)
}複製代碼

這裏用到 Object.keys() 方法,獲取對象鍵的集合並判斷其長度是否爲 0 便可。

6. 如何使用循環刪除數組中的多個元素

for (let i = 0, let j = delIds.length - 1; i < j; i++) {
    allItems.splice(delIds[i], 0)
}複製代碼

如上,根據索引來循環刪除原始數組中的元素是否可行呢?若是咱們執行這段代碼是沒法獲得預期結果的。緣由在於,當前面的元素被刪除時,後面元素的索引起生了變化,繼續用刪除前的索引就沒法定位正確的元素,解決的方法有兩種:

  • 經過倒序循環,獲取被刪除元素的索引,從後向前遍歷刪除。
for (let i = delIds.length - 1; i > 0; i--) {
    allItems.splice(delIds[i], 0)
}複製代碼
  • 經過數組的兩個方法即 forEach 配合 indexOf 刪除,這種方法須要獲取被刪除元素自己,動態獲取它的索引。
delItems.forEach ((item) => {
    allItems.splice(allItems.indexOf(item), 0)
})複製代碼

(未完待續...)

相關文章
相關標籤/搜索