前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >jsonForest

jsonForest

作者头像
念念不忘
发布2019-05-08 11:09:33
4270
发布2019-05-08 11:09:33
举报
文章被收录于专栏:那些年我们学过的前端

JsonTransfer

以昆仑三级联动类目为例 对于后端返回的数据 我们可能需要对这些字段进行特殊的配置(如改名)等才能拿到我们可以直接使用的数据。除此之外,消息订阅比较混乱。

我们期望的消息订阅模式如下:
代码语言:javascript
复制
//  监听 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 中使用的时候 挂载在全局对象上即可

代码语言:javascript
复制
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']
  }
  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
    }
  }
  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]: data[item]
          })
        }
      })
    } 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) {
    let result = {}
    if (Object.prototype.toString.call(data) === '[object Array]') {
      result = data.map(item => {
        return this.replaceRepeatKeymap(item, keymap)
      })
    } 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]: data[dataKey]
          })
        }
      }
    } else {
      return data
    }
    return result
  }
  replaceKeymap (data, keymap) {
    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)
    } else {
      for (let key in keymap) {
        let chiledStr = keymap[key]
        str = str.replace(new RegExp(chiledStr, 'g'), key)
      }
      return JSON.parse(str)
    }
  }
  emit (type, option) {
    let arr = this.eventList[type]
    if (!arr) {
      /**
       *  没有 on 的时候 emit的兼容
       */
      arr = []
    }
    /**
     * 挂载参数  进行整体校验
     */
    this.init(option)
    // option 不传 或者 data 不传  则可认为在执行订阅和发布任务  不做 dom 转化
    if (!this.option || !this.data) {
      arr.forEach((item, index) => {
        item()
      })
    } else {
      /**
       * 1. 检验 returnKeys  如果不对  给出报错
       * 2. 检验 keymaps  如果映射的类名不对    给出报错
       *
       */
      // 校验 data 存在的情况下 returnKeys为数组  keymap为对象的合法性
      this.validateLegal(this.returnKeys, this.keymap)
      if (this.returnKeys) {
        this.data = this.getDataFormReturnKeys(this.data, this.returnKeys)
      }
      if (this.keymap) {
        this.data = this.replaceKeymap(this.data, this.keymap)
      }
      arr.forEach((item) => {
        item(this.data, this.option)
      })
    }
  }
  on (type, callback) {
    if (!this.eventList[type]) {
      this.eventList[type] = []
    }
    this.eventList[type].push(callback)
  }
}

export default JsonForest
使用说明

api

使用方法

说明

data

赋值数据

数据源 如果不传 将不对数据做任何处理

returnKeys

['cat_id', 'cat_name', 'depth', 'rank']

需要返回的字段,以数组的形式包围

keymap

{label: 'cat_name',value: 'cat_name',}

映射改变的字段 ,以对象的形式包裹,支持1对1、1对多

使用
代码语言:javascript
复制
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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.04.23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JsonTransfer
    • 我们期望的消息订阅模式如下:
      • 我们将枯燥而繁琐的数据格式转换 类名转换 提供了一个公共的方法取处理
        • 使用说明
          • 使用
            • 测试案例
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档