前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Thinking--Normalize思想在前端中的应用

Thinking--Normalize思想在前端中的应用

作者头像
奋飛
发布2019-08-14 18:01:17
3540
发布2019-08-14 18:01:17
举报
文章被收录于专栏:Super 前端Super 前端

Thinking系列,旨在利用10分钟的时间传达一种可落地的编程思想。

Normalize

标准化:Normalize

发组件过程中,为了提高组件的灵活性,我们通常需要支持多种传参格式,如何优雅的控制和组件内部解耦变得尤为重要!

示例: Vue的 clip-board 指令,支持两种传参方式。

  • 如果是字符串,则为要拷贝的文本内容
  • 如果是对象,对象中的text属性,为要拷贝的文本内容
代码语言:javascript
复制
<div v-clip-board="txt"></div>
<div v-clip-board="{text: 'txt', success, error}"></div>

传统写法

代码语言:javascript
复制
const _noop = function () { return {} }
const ClipBoard = require('clipboard')
export default {
  name: 'clip-board',
  hooks: {
    bind: function (el, binding, vnode) {
      const clipboard = new ClipBoard(el, {
        action () { return binding.arg === 'cut' ? 'cut' : 'copy' }
      })
      // 判断是否为对象,并解构对象属性
      if (typeof (binding.value) === 'object') { 
        let { success = _noop, error = _noop } = binding.value
        clipboard.on('success', e => { 
          success()
        })
        clipboard.on('error', e => {
          error()
        })
      }
      el._clipboard = clipboard
    },
    update (el, binding) {
      el._clipboard.text = function () {
        // 判断是否为对象,处理相关值
        return typeof (binding.value) === 'string' ? binding.value : binding.value.value
      }
    },
    unbind (el, binding) {
      el._clipboard.destroy()
      delete el._clipboard
    }
  }

如果增加第三种参数支持,如数组格式,该如何处理?bindupdate 方法中都需要增加判断分支。

Normalize后

代码语言:javascript
复制
const _noop = function () {}
// 集中化处理参数
const normalizeProps = function (param) {
  let obj = {
    text: '',
    action: param.arg ? param.arg : 'copy', 
    success: _noop,
    error: _noop
  }
  let type = Object.prototype.toString.call(param.value).match(/^\[object (.*)\]$/)[1].toLowerCase()
  switch (type) {
    case 'string':
      obj.text = param.value
      break
    case 'object':
      obj = Object.assign({}, obj, param.value)
      break
    default:
      break
  }
  return obj
}

const ClipBoard = require('clipboard')
export default {
  name: 'clip-board',
  hooks: {
    bind: function (el, binding, vnode) {
      let { action, success, error } = normalizeProps(binding)
      const clipboard = new ClipBoard(el, {
        action () { return action }
      })
      clipboard.on('success', e => {
        success()
      })
      clipboard.on('error', e => {
        error()
      })
      el._clipboard = clipboard
    },
    update (el, binding) {
      el._clipboard.text = function () {
        return normalizeProps(binding)['text']
      }
    },
    unbind (el, binding) {
      el._clipboard.destroy()
      delete el._clipboard
    }
  }
}

优势:

  1. 统一了判断入口,核心代码省掉了不必要的分支判断,简单明了;
  2. 后续需要增加其他格式属性时,核心代码无需修改,只需调整 normalize 函数。

哪里还有类似的场景出现?

以 Vue 中 Props 为例,进行说明 https://github.com/vuejs/vue/blob/dev/src/core/util/options.js#L298

代码语言:javascript
复制
props: ["propA"]
props: {
    propB: Object,
    propC: {
    	type: String
    }
}
normalize设计模式
normalize设计模式

延伸

外观设计模式:

外观设计模式.
外观设计模式.
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年06月02日,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Normalize
    • 哪里还有类似的场景出现?
      • 延伸
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档