jsonForest

JsonTransfer

以昆侖三級聯動類目為例 對于后端返回的數據 我們可能需要對這些字段進行特殊的配置(如改名)等才能拿到我們可以直接使用的數據。除此之外,消息訂閱比較混亂。

我們期望的消息訂閱模式如下:
//  監聽 listen 事件
this.jsonTransfer.on("listen", value => {
    // 處理 value 值  value 為后端字符串經過特殊處理之后返回給我們需要的字符串
      this.resOptions = value;
    });


// 獲取后端數據  并觸發監聽事件
 axios.get(`${dataObj[value]}`).then(res => {
        //  拿到后端數據之后 觸發 listen 事件
        this.jsonTransfer.emit("listen", {
          returnKeys: ["cat_id", "cat_name", "depth", "rank"],
          keymap: {
            label: "cat_name",
            value: "cat_name",
            depth: "depth"
          },
          data: res.data.data[0]
        });
      });
我們將枯燥而繁瑣的數據格式轉換 類名轉換 提供了一個公共的方法取處理

react 和 vue 中使用的時候 掛載在全局對象上即可

class JsonForest {
  constructor () {
    this.eventList = []
    this.data = ''
    this.keymap = {
      name: 'cat_name',
      id: 'cat_id',
      depth: 'depth'
    }
    this.returnKeys = ['cat_id', 'cat_name', 'depth', 'rank']
    this.JsonTransfer = new JsonTransfer()
  }
  init (option) {
    this.option = this.checkParam(option) ? option : ''
    this.data = this.checkParam(option.data)
      ? JSON.parse(JSON.stringify(option.data))
      : ''
    this.keymap = this.checkParam(option.keymap) ? option.keymap : ''
    this.returnKeys = this.checkParam(option.returnKeys)
      ? option.returnKeys
      : ''
  }
  checkParam (param) {
    // 如果為空字符串、 空對象、空數組 以及 undefined null 等值的時候 返回 false 否則返回 true
    if (Object.prototype.toString.call(param) === '[object Array]') {
      return !!param.length
    } else if (Object.prototype.toString.call(param) === '[object Object]') {
      return !!Object.keys(param).length
    } else {
      return !!param
    }
  }
  validateLegal (returnKeys, keymap) {
    if (Object.prototype.toString.call(returnKeys) !== '[object Array]') {
      throw new Error('returnKeys字段,必須為數組')
    } else if (Object.prototype.toString.call(keymap) !== '[object Object]') {
      throw new Error('keymap字段,必須為對象')
    } else {
      return true
    }
  }
  emit (type, option) {
    let arr = this.eventList[type]
    if (!arr) {
      /**
       *  沒有 on 的時候 emit的兼容
       */
      arr = []
    }
    // 校驗 data 存在的情況下 returnKeys為數組  keymap為對象的合法性
    this.validateLegal(this.returnKeys, this.keymap)
    /**
     * 掛載參數  進行整體校驗 不符合規范的 轉化為空字符串
     */
    this.init(option)
    // option 不傳 或者 data 不傳  則可認為在執行訂閱和發布任務  不做 dom 轉化
    if (!this.option || !this.data) {
      arr.forEach((item, index) => {
        item()
      })
    } else {
      /**
       * 1. 檢驗 returnKeys  如果不對  給出報錯
       * 2. 檢驗 keymaps  如果映射的類名不對  給出報錯
       *
       */
      if (this.returnKeys) {
        this.data = this.JsonTransfer.getDataFormReturnKeys(this.data, this.returnKeys)
      }
      if (this.keymap) {
        this.data = this.JsonTransfer.replaceKeymap(this.data, this.keymap, this.returnKeys)
      }
      arr.forEach(item => {
        item(this.data, this.option)
      })
    }
  }
  on (type, callback) {
    if (!this.eventList[type]) {
      this.eventList[type] = []
    }
    this.eventList[type].push(callback)
  }
}

class JsonTransfer {
  getDataFormReturnKeys (data, returnKeys) {
    let result = {}
    if (Object.prototype.toString.call(data) === '[object Array]') {
      result = data.map(item => {
        return this.getDataFormReturnKeys(item, returnKeys)
      })
    } else if (Object.prototype.toString.call(data) === '[object Object]') {
      let prevKeys = Object.keys(data)
      returnKeys.forEach(item => {
        //  原先數據中存在的key 值   才會生效
        if (prevKeys.includes(item)) {
          result = Object.assign(result, {
            [item]: this.getDataFormReturnKeys(data[item], returnKeys)
          })
        }
      })
    } else {
      return data
    }
    return result
  }
  checkKeymapRepeat (keymap) {
    let arr = Object.values(keymap)
    let hash = {}
    for (let i = 0; i < arr.length; i++) {
      if (hash[arr[i]]) {
        return true
      }
      hash[arr[i]] = true
    }
    return false
  }
  replaceRepeatKeymap (data, keymap, returnKeys) {
    let result = {}
    if (Object.prototype.toString.call(data) === '[object Array]') {
      result = data.map(item => {
        return this.replaceRepeatKeymap(item, keymap, returnKeys)
      })
    } else if (Object.prototype.toString.call(data) === '[object Object]') {
      for (let key in keymap) {
        let dataKey = keymap[key]
        if (data.hasOwnProperty(dataKey)) {
          result = Object.assign(result, {
            [key]: this.replaceRepeatKeymap(data[dataKey], keymap, returnKeys)
          })
        }
      }
      // 補充returnKeys 遺留的 key 值
      let filterArr = returnKeys.filter((item) => {
        return !Object.values(keymap).includes(item)
      })
      if (filterArr.length) {
        filterArr.forEach((key) => {
          if (data.hasOwnProperty(key)) {
            result = Object.assign(result, {
              [key]: this.replaceRepeatKeymap(data[key], keymap, returnKeys)
            })
          }
        })
      }
    } else {
      return data
    }
    return result
  }
  replaceKeymap (data, keymap, returnKeys) {
    let str = JSON.stringify(data)
    /**
     * 1.   keymap 中存在相同的 value 值  (特殊情況)
     *  keymap: {
            label: "cat_name",
            value: "cat_name",
            depth: "depth"
          },
     * 2.   keymap 中的 value 值都不相同(正常情況)
     */
    if (this.checkKeymapRepeat(keymap)) {
      return this.replaceRepeatKeymap(data, keymap, returnKeys)
    } else {
      for (let key in keymap) {
        let chiledStr = keymap[key]
        str = str.replace(new RegExp(chiledStr, 'g'), key)
      }
      return JSON.parse(str)
    }
  }
}
export default JsonForest


使用說明
api 使用方法 說明
data 賦值數據 數據源 如果不傳 將不對數據做任何處理
returnKeys ['cat_id', 'cat_name', 'depth', 'rank'] 需要返回的字段,以數組的形式包圍
keymap {label: 'cat_name',
value: 'cat_name',}
映射改變的字段 ,以對象的形式包裹,支持1對1、1對多
使用
mounted () {
    this.jsonTransfer.on('listen', value => {
      console.log('111')
      console.log(value)
      this.resOptions = value
    })
  },
methods: {
    chooseValue (value) {
      console.log(value)
      axios.get(`${dataObj[value]}`).then(res => {
        console.log(this.jsonTransfer)
        this.jsonTransfer.emit('listen', {
          returnKeys: ['cat_id', 'cat_name', 'depth', 'rank'],
          keymap: {
            label: 'cat_name',
            value: 'cat_name',
            depth: 'depth'
          },
          data: res.data.data
        })
        console.log(res)
      })
    }
  }
測試案例

配置異步請求數據源 我使用本地 mock、改變一級類目 隨即可以看到二級類目數據發生改變

image.png
image.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容

  • Online payment to buy things is always a big headache. 網購...
    新活力英語教育閱讀 284評論 0 0
  • “懦夫,你就是個懦夫……” 沒等劉強說完,我就摁下了眼鏡上的掛機按鈕,他粗糲的聲音嘎然而止,感覺就像把一塊肥皂突然...
    不完美世界閱讀 367評論 0 2
  • 昨天總體來說,心情還可以,因為有些事好像得到了答案,而答案也沒有想象中那么糟,當我們放開,事情的發展其實也沒想象中...
    顏麗娜閱讀 158評論 1 1
  • “江南憶,最憶是杭州。山寺月中尋桂子,郡亭枕上看潮頭。何日更重游?”——白居易 提到江南,總繞不開...
    周穎_3286閱讀 543評論 3 6