## 常用的工具类方法

常用的工具类引入方式

```html
<script>
  import utils from 'swordpaas-ui/src/utils.js'
</script>
```

### 判断是否为空

`isEmpty(val)`方法，判断传入的值是否为空，返回值`boolean`。

```html
<template>
  <el-row class="flex-row" :gutter="20">
    <el-col :span="4"><cl-input v-model="val"></cl-input></el-col>
    <el-col :span="4">
      <el-button @click="isEmpty">判断是否为空</el-button>
    </el-col>
    <el-col :span="8"><div>{{name}}</div></el-col>
  </el-row>
</template>
<script>
  import utils from '../../src/utils'
  export default {
    data() {
      return {
        val: '',
        name: ''
      }
    },
    methods: {
      isEmpty() {
        this.name = utils.isEmpty(this.val)
      }
    }
  }
</script>
<style>
  .flex-row {
    display: flex;
    align-items: center;
  }
</style>
<!-- isEmpty.vue -->
```

### 生成随机 8 位字符

`getName()`方法，返回值`string`，获得一个随机产生的 8 位长度的字母数字组成的名称。

```html
<template>
  <el-row class="flex-row">
    <el-col :span="4"><el-button @click="getName">生成名称</el-button></el-col>
    <el-col :span="8"><div>{{name}}</div></el-col>
  </el-row>
</template>
<script>
  // import utils from '../../src/utils'
  export default {
    data() {
      return {
        name: ''
      }
    },
    methods: {
      getName() {
        this.name = utils.getName()
      }
    },
    mounted() {
      this.getName()
    }
  }
</script>
<style>
  .flex-row {
    display: flex;
    align-items: center;
  }
</style>
<!-- getName.vue -->
```

### 获取编辑权限

`getWriteable(permission)`，传入权限值，返回值`boolean`，判断`permission`权限是否对应可编辑状态。

```html
<template>
  <el-row class="flex-row" :gutter="20">
    <el-col :span="4">
      <el-select v-model="typePermission" placeholder="请选择">
        <el-option label="无权限" value="n"></el-option>
        <el-option label="只读" value="r"></el-option>
        <el-option label="编辑" value="w"></el-option>
        <el-option label="必填" value="b"></el-option>
      </el-select>
    </el-col>
    <el-col :span="4">
      <el-button @click="getWriteable">判断编辑权限</el-button>
    </el-col>
    <el-col :span="8"><div>{{result}}</div></el-col>
  </el-row>
</template>
<script>
  // import utils from '../../src/utils'
  export default {
    data() {
      return {
        typePermission: 'w',
        result: ''
      }
    },
    methods: {
      getWriteable() {
        this.result = utils.getWriteable(this.typePermission)
      }
    }
  }
</script>
<style>
  .flex-row {
    display: flex;
    align-items: center;
  }
</style>
<!-- getWriteable.vue -->
```

### 合并校验规则

`mergeValidate(rules, appendRules)`，返回值`string/object`，
在已有规则`rules`中追加新的规则`appendRules`，如果`rules`和`appendRules`均为字符串格式，合并后仍为字符串格式；如果其中一个为 Object 格式，合并后为 Object 格式。
`rules`和`appendRules`均支持多个校验规则的情况下完成合并，而且在旧规则和追加规则中均有某一个规则时，会以`appendRules`中的规则覆盖掉`rules`中的规则。

```html
<script>
  let rules = 'required'
  let appendRules = 'mobile'
  let ruleObj = { required: true, min: '2', max: '10' }
  utils.mergeValidate(rules, appendRules) // 返回值 required|mobile
  utils.mergeValidate(ruleObj, appendRules) // 返回值 {required: true, min: "2", max: "10", mobile: true}
</script>
```

### 移除校验规则

`reduceValidate(rules, reduceRules)`，返回值`string/object`，
从已有规则`rules`中移除`reduceRules`对应的规则，返回的规则与`rules`的格式一样。

```html
<script>
  let ruleStr = 'required|mobile|email'
  let ruleObj = { required: true, min: '2', max: '10' }
  utils.reduceValidate(ruleStr, 'required') // 返回值 mobile|email
  utils.reduceValidate(ruleObj, 'required') // 返回值 {min: "2", max: "10"}
</script>
```

### 规则字符串转对象

`validateString2Object(rule)`，返回值`object`，
将字符串格式的规则`rule`转换为对象格式。

```html
<script>
  let ruleStr = 'required|mobile|email'
  utils.validateString2Object(ruleStr) // 返回值 {required: true, mobile: true, email: true}
</script>
```

### 字符串分隔成数组

`stringSplit(str, sep)`，返回值`array`，
字符串 str 按照 sep 分割为数组，并清理掉数组结果中的空白项。

```html
<script>
  let ruleStr = 'required|mobile|email'
  utils.stringSplit(ruleStr, '|') // 返回值 ["required", "mobile", "email"]
</script>
```

### 根据权限添加校验规则

`addRequiredOrNot(permission, validate)`，返回值`string/object`，根据您`permission`权限信息来判断，当前`validate`中是否需要添加校验规则。是则返回添加了必填规则的校验规则表达式，否则返回原校验规则表达式。

```html
<script>
  let validate = 'mobile|email'
  let permissionEdit = 'w' // 编辑权限
  let permissionRequired = 'b' // 必填权限
  utils.addRequiredOrNot(permissionEdit, validate) // 返回值 mobile|email
  utils.addRequiredOrNot(permissionRequired, validate) // 返回值 required|mobile|email
</script>
```

### 日期格式化为 年月日时分秒

`formatDate(value)`，返回值`string`，按照`yyyy-MM-dd HH:mm:ss`的格式对`value`进行日期时间格式化，`value`的类型支持`Date`、时间戳、字符串等多种格式。

```html
<script>
  let date1 = new Date() // 日期格式 Mon May 31 2021 16:21:24 GMT+0800 (中国标准时间)
  let date2 = new Date().getTime() // 时间戳格式 1622449332833
  utils.formatDate(date1) // 返回值 2021-05-31 16:28:42
  utils.formatDate(date2) // 返回值 2021-05-31 16:28:42
</script>
```

### 日期格式化为 年月日

`formatDateYear(value)`，返回值`string`，按照`yyyy-MM-dd`的格式对`value`进行日期格式化，`value`的类型支持字符串格式的日期类型。

```html
<script>
  let date1 = new Date() // 日期格式 Mon May 31 2021 16:21:24 GMT+0800 (中国标准时间)
  let date2 = new Date().getTime() // 时间戳格式 1622449332833
  let date3 = '2021/05/31' // 字符串
  utils.formatDateYear(date1) // 返回值 2021-05-31
  utils.formatDateYear(date2) // 返回值 2021-05-31
  utils.formatDateYear(date3) // 返回值 2021-05-31
</script>
```

### 日期对比早晚

`dateIsBefore(dateOne, dateTwo, canEquals)`，返回值`boolean`，日期`dateOne`是否早于日期`dateTwo`，是则返回`true`，否则返回`false`。
另外参数`canEquals`表示两个日期能否不相等，该参数默认为`false`，表示不能相等，即日期`dateOne`等于`dateTwo`时返回`false`；反之如果该参数传入`true`时，日期`dateOne`等于`dateTwo`时返回`true`。

```html
<template>
  <div class="flex-row">
    <el-date-picker v-model="dateOne" placeholder="dateOne" class="margin-right"></el-date-picker>
    <el-date-picker v-model="dateTwo" placeholder="dateTwo" class="margin-right"></el-date-picker>
    <el-button @click="dateIsBefore" class="margin-right">对比日期</el-button>
    <div>{{result}}</div>
  </div>
</template>
<script>
  // import utils from '../../src/utils'
  export default {
    data() {
      return {
        dateOne: '',
        dateTwo: '',
        result: ''
      }
    },
    methods: {
      dateIsBefore() {
        this.result = utils.dateIsBefore(this.dateOne, this.dateTwo)
      }
    }
  }
</script>
<style>
  .flex-row {
    display: flex;
    align-items: center;
  }
  .margin-right {
    margin-right: 10px;
  }
</style>
<!-- dateIsBefore.vue -->
```

### 计算日期间隔长度

`dateCalc(startDate, endDate, op)`，返回值`number`，计算`startDate`和`endDate`之间相差几个`op`单位，参数格式需传入字符串，`op`的默认值为`day`，`op`的选项有：

- year

* month
* day
* hour
* minute
* second

```html
<template>
  <div class="flex-row">
    <el-date-picker v-model="dateOne" placeholder="dateOne" class="margin-right" value-format="yyyy-MM-dd"></el-date-picker>
    <el-date-picker v-model="dateTwo" placeholder="dateTwo" class="margin-right" value-format="yyyy-MM-dd"></el-date-picker>
    <el-button @click="dateCalc" class="margin-right">计算间隔</el-button>
    <div class="margin-right">{{result}}</div>
    <el-select v-model="op">
      <el-option label="年" value="year"></el-option>
      <el-option label="月" value="month"></el-option>
      <el-option label="日" value="day"></el-option>
      <el-option label="时" value="hour"></el-option>
      <el-option label="分" value="minute"></el-option>
      <el-option label="秒" value="second"></el-option>
    </el-select>
  </div>
</template>
<script>
  // import utils from '../../src/utils'
  export default {
    data() {
      return {
        dateOne: '2021-05-31',
        dateTwo: '2021-06-1',
        result: '',
        op: 'day'
      }
    },
    methods: {
      dateCalc() {
        this.result = utils.dateCalc(this.dateOne, this.dateTwo, this.op)
      }
    }
  }
</script>
<style>
  .flex-row {
    display: flex;
    align-items: center;
  }
  .margin-right {
    margin-right: 10px;
  }
</style>
<!-- dateCalc.vue -->
```

### 树形结构数组转换成平铺数组

`utils.nest2tile(arr,childrenKey,obtainChildren)`，返回值`Array` 。
childrenKey 默认值为 children，obtainChildren 如果为 true 返回值包含 children

```javascript
let arr = [
  {
    id: '1',
    parentId: '-1',
    name: '1',
    children: [
      {
        id: '2',
        parentId: '1',
        name: '1-2',
        children: [
          { id: '3', parentId: '2', name: '1-2-3' },
          { id: '4', parentId: '2', name: '1-2-4' }
        ]
      },
      {
        id: '5',
        parentId: '1',
        name: '1-5',
        children: [{ id: '6', parentId: '5', name: '1-5-6' }]
      }
    ]
  }
]
let arr2 = utils.nest2tile(arr, 'children')[
  // 返回值
  ({ id: '1', parentId: '-1', name: '1' },
  { id: '2', parentId: '1', name: '1-2' },
  { id: '3', parentId: '2', name: '1-2-3' },
  { id: '4', parentId: '2', name: '1-2-4' },
  { id: '5', parentId: '1', name: '1-5' },
  { id: '6', parentId: '5', name: '1-5-6' })
]
```

### 普通平铺数组转了树结构嵌套数组

`tile2nest(array, key, pKey, childrenKey)`，返回值`array`，将平铺结构的数组转换为嵌套结构的数组。参数说明：

- `array`为待转换的平铺结构数组

* `key`为数据的主键，默认为`id`
* `pKey`为数据中存放父级数据主键的 key，默认为`parentId`
* `childrenKey`为当数据转为嵌套结构后，子数据以什么 key 来存放，默认为`children`

```html
<script>
  let arr = [
    { id: '1', parentId: '-1', name: '1' },
    { id: '2', parentId: '1', name: '1-2' },
    { id: '3', parentId: '2', name: '1-2-3' },
    { id: '4', parentId: '2', name: '1-2-4' },
    { id: '5', parentId: '1', name: '1-5' },
    { id: '6', parentId: '5', name: '1-5-6' }
  ]
  let arr2 =
    utils.tile2nest(arr)[
      // 转换后结果 console.log(arr2)
      {
        id: '1',
        parentId: '-1',
        name: '1',
        children: [
          {
            id: '2',
            parentId: '1',
            name: '1-2',
            children: [
              { id: '3', parentId: '2', name: '1-2-3' },
              { id: '4', parentId: '2', name: '1-2-4' }
            ]
          },
          {
            id: '5',
            parentId: '1',
            name: '1-5',
            children: [{ id: '6', parentId: '5', name: '1-5-6' }]
          }
        ]
      }
    ]
</script>
```

### 获取控件所在表单对应的实例对象

`getOnlineFormInstance(instance)`，返回值`object`，通过控件的`vueComponent`实例获取控件所在的表单的`vueComponent`实例。

```html
methods: { getOnlineFormInstance() { utils.getOnlineFormInstance(this) } }
```

### 获取子表每一行所在的作用域元素及索引

`getSubScopeElAndIndex(element)`，返回值`{ vueComponent, integer }`，
根据子表对象中的某个 Dom 元素获取子表所对应的`vueComponent`对象及当前索引`index`。
因为是通过`data-subname`来确定是否为子表，以及通过`data-index`来记录索引，所以只当子表按照以下格式时，该方法才能返回正确的结果。

```html
<li v-for="(row, index) in data.sub" :key="index" :data-index="index" data-subname="data.sub">...</li>
```

### 在子表指定行中通过 v-model 表达式获取 input 对应的 vue 实例

`getSubInputScopeByModelExpression(subScopeEl, expression)`，返回值`vueComponent`。
根据当前子表`vueComponent`对象获取其中`expression`所对应的`vueComponent`实例。

<span style="color:#f00;font-weight:bold">特别注意：</span>
因为是通过`class="inputs"`来查找子表中的控件，所以只有表达式`expression`使用在 swordpaas-ui 的控件上时，才能正确的返回结果。
在如下的代码中，通过`utils.getSubInputScopeByModelExpression(subScopeEl, "row.name")`就可以获取到该行中`<cl-input />`所对应的`vueComponent`实例。

```html
<li v-for="(row, index) in data.sub" :key="index" :data-index="index" data-subname="data.sub">
  <div>
    <cl-input v-model="row.name" />
    ...
  </div>
</li>
```

### 校验指定实例中指定表单是否通过校验

`validateForm(instance, scopeName)`，返回值`promise`。

对当前`vueComponent`实例中作用域为`scopeName`的表单进行校验，校验通过则触发`promise`中的`resolve`，否则触发`reject`，在`reject`中返回了`errors.items`，即校验失败的所有元素。

使用示例如下：

```html
<template>
  <el-form :model="validateForm" label-width="80px" data-vv-scope="form1">
    <cl-form-item label="姓名">
      <cl-input v-model="validateForm.name" validate="required|min:2|max:4"></cl-input>
    </cl-form-item>
    <cl-form-item label="爱好">
      <cl-input v-model="validateForm.hobby" validate="required"></cl-input>
    </cl-form-item>
    <cl-form-item>
      <el-button type="primary" @click="onSubmit" :loading="loading"> 提交 </el-button>
      <el-button>取消</el-button>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        validateForm: {
          name: '',
          hobby: ''
        },
        loading: false
      }
    },
    methods: {
      onSubmit() {
        this.loading = true
        setTimeout(() => {
          utils
            .validateForm(this, 'form1')
            .then((r) => {
              this.$message.success(JSON.stringify(this.validateForm))
            })
            .catch((items) => {
              this.$message.error(`有${items.length}个字段未通过校验，无法提交表单。`)
            })
            .finally(() => {
              this.loading = false
            })
        }, 500)
      }
    }
  }
</script>
<!-- tools-validateForm.vue -->
```

### 获取指定 dom 元素的父级中具有指定属性的 dom 元素

`getParentElementByAttribute(element, attribute)`，传入 dom 元素和属性名称，返回值`HTMLElement`。

获取`element`的父级元素中，拥有指定属性`attribute`的`HTMLElement`对象。

### 从父级 dom 元素中获取指定属性的值

`getSomeAttributeFromParentElement(element, attribute)`，返回值`any`。

获取`element`的父级元素中，拥有指定属性`attribute`的`HTMLElement`对象中这个指定属性的值。

### 将子表属性路径转换为完整的属性路径，例如：item.name => data.sub[0].name

`getWholePathOfSub(subPath, mainPath, index)`，返回值`string`。

将子表属性路径转换为完整的属性路径，参数说明：

- `subPath`子表中的表达式，如：item.name, row.name 等

* `mainPath`子表在整体对象中的路径，例如:data.sub, data.children 等
* `index`为子表哪一条数据的索引。

例如：当调用该方法时传递的参数为`utils.getWholePathOfSub('item.name', 'data.sub', 0)`时,结果为`data.sub[0].name`。

### 通过路径取得对象中的属性

`getValueByPath(instance, path, subIndex)`，返回值`any`。

通过路径`path`获取实例`instance`中对应的值，如果是子表数据，需要传入`subIndex`指定索引。
使用 getValueByPath 方法获取 name，company

```html
<template>
  <el-form label-width="80px" v-form>
    <cl-form-item label="name">
      <cl-input v-model="name" validate="required" readonly></cl-input>
    </cl-form-item>
    <cl-form-item label="company">
      <cl-input v-model="company" validate="required" readonly></cl-input>
    </cl-form-item>
    <cl-form-item></cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        data: {
          user: {
            name: '张三',
            age: 23,
            experience: [
              { company: '设计院', start: '1999-07-28', end: '2000-09-18' },
              { company: '图灵', start: '2000-10-11', end: '2001-12-11' }
            ]
          }
        }
      }
    },
    computed: {
      name() {
        return utils.getValueByPath(this, 'data.user.name')
      },
      company() {
        return utils.getValueByPath(this, 'data.user.experience.company', 1)
      }
    }
  }
</script>
<!-- tools-getValueByPath.vue -->
```

### 通过路径设置对象中的属性

`setValueByPath(instance, path, value, subIndex)`，无返回值

设置`path`的值`value`到实例`instance`中，如果设置的值为子表数据，则需要传递`subIndex`作为索引。

使用示例如下：

```html
<template>
  <el-form label-width="80px" v-form>
    <cl-form-item label="默认数据">
      <div>{{data}}</div>
    </cl-form-item>
    <cl-form-item>
      <cl-input v-model="nameVal" placeholder="请输入姓名"></cl-input>
      <cl-input v-model="companyVal" placeholder="请输入公司"></cl-input>
      <el-button @click="setValueByPath">设置姓名和公司</el-button>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        nameVal: '',
        companyVal: '',
        data: {
          user: {
            name: '张三',
            age: 23,
            experience: [
              { company: '设计院', start: '1999-07-28', end: '2000-09-18' },
              { company: '图灵', start: '2000-10-11', end: '2001-12-11' }
            ]
          }
        }
      }
    },
    methods: {
      setValueByPath() {
        utils.setValueByPath(this, 'data.user.name', this.nameVal)
        utils.setValueByPath(this, 'data.user.experience.company', this.companyVal, 1)
      }
    }
  }
</script>
<!-- tools-setValueByPath.vue -->
```

### 将 JSON 字符串转换为对象或数组

`parseToJson(jsonStr, type)`，返回值`object/array`。

将字符串`jsonStr`转换为对象格式，`type`为默认为 1，可选值为

- `1`使用`JSON.parse(jsonStr)`的方式来解析

* `2`使用`eval()`的方式来解析
  在解析失败的情况下，系统会按照 type 从小到大的方式依次尝试解析。

### 数字转换成人名币大写

`convertCurrency(currencyDigits)`，返回值`string`。

```html
<template>
  <div class="flex-row">
    <cl-input v-model="money" placeholder="请输入金额" class="margin-right"></cl-input>
    <el-button @click="convertCurrency" class="margin-right"> 数字转人民币大写 </el-button>
    <div>{{result}}</div>
  </div>
</template>
<script>
  // import utils from '../../src/utils'
  export default {
    data() {
      return {
        money: '100',
        result: ''
      }
    },
    methods: {
      convertCurrency() {
        this.result = utils.convertCurrency(this.money)
      }
    },
    mounted() {
      this.convertCurrency()
    }
  }
</script>
<style>
  .flex-row {
    display: flex;
    align-items: center;
  }
  .margin-right {
    margin-right: 10px;
  }
</style>
<!-- tools-convertCurrency.vue -->
```

### 获取当前 url 中带的参数的某个值

`getUrlKey(name)`，返回值`string`

通过`name`获取页面 url 地址参数。

```html
// 如果当前url地址为localUrl let localUrl = "http://www.chenlongkeji.com?name=zhangsan&uid=111" // 那么下面返回值为 zhangsan
utils.getUrlKey('name')
```

### 调整数组中指定元素位置上移或下移

`arrayMove(ary, part, direct)`，返回值`array`。

将数组`ary`中的指定部分`part`按照方向`direct`调整顺序，将调整顺序后的数组返回。`direct`的可选值有`up`和`down`，默认值为`down`。

```javascript
let arr1 = ['test1', 'test2', 'test3']
let arr2 = utils.arrayMove(arr1, ['test2'], 'up')
console.log(arr2) // 打印值为 ['test2', 'test1', 'test3']
```

### 子组件通过 config 属性获取父组件中传入的路径的值

`getValueByConfigKey(instance, config, key)`，返回值`any`。

通过配置中指定的`key`所对应的属性路径在当前表单中获取对应的值，支持通过`data.main.name`或者是 `item.name`来分别获取主表数据及子表数据的情况。当然，对于子表要求子表具有`data-subname`属性。

示例代码如下，在组件`my-role-selector`中，通过`utils.getValueByConfigKey(this, config, "id")`就能获取到`data.xxb.roleId`的值。

```javascript
<my-role-selector
    v-model="data.xxb.roles"
    permission="w"
    :config="{id:'data.xxb.roleId',code: 'data.xxb.roleCode'}"
    placeholder="请选择" />
```

### 子组件通过 config 设置父组件中传入的路径的值

`setValueByConfigKey(instance, config, key, value)`，无返回值。

通过配置中指定的`key`来设置值到对应的属性路径上，支持设置主表数据`data.main.name`或设置子表数据`item.name`。当然，对于子表要求子表具有`data-subname`属性。

示例代码如下，在组件`my-role-selector`中，通过`utils.setValueByConfigKey(this, config, "id")`就能将当前组件中`id`的值设置给`data.xxb.roleId`。

```javascript
<my-role-selector
    v-model="data.xxb.roles"
    permission="w"
    :config="{id:'data.xxb.roleId',code: 'data.xxb.roleCode'}"
    placeholder="请选择" />
```

### 判断两个对象是否相同

`objectEquals(obj1, obj2, props)`，返回值`boolean`。

判断对象`obj1`和对象`obj2`是否相等，深度对比两个对象的所有属性值（如果属性为对象会继续深度对比）。当传入了`props`属性数组时，只会对传入的属性进行对比。

```javascript
let obj1 = { name: '张三', age: 30, id: '111' }
let obj2 = { name: '张三', age: 30, id: '222' }
utils.objectEquals(obj1, obj2) // 返回值 false
utils.objectEquals(obj1, obj2, ['name', 'age']) // 返回值 true
```

### 判断两个数组是否相同

`arrayEquals(ary1, ary2)`，返回值`boolean`

深度对比两个数组`ary1`,`ary2`，包括数组中的对象也会进行深度对比。

```javascript
let arr1 = [{ name: '张三', age: 30, id: '111' }]
let arr2 = [{ name: '张三', age: 30, id: '222' }]
utils.arrayEquals(arr1, arr2) // 返回值 false
```

### 去掉字符串中空格

`trimEachLine(text)`，返回值`string`。

以第一行文本的缩进空格数为基准，后续的每一行都去掉这个基准所对应的空格。

```javascript
let text = `第一行
            第二行
            第三行
            第四行`
console.log(text)
// 打印值格式
第一行
第二行
第三行
第四行
console.log(utils.trimEachLine(text))
// 打印值格式
第一行
第二行
第三行
第四行
```

### 文本转哈希编码

`hashCode(text)`，返回值`string`，获取文本所对应的哈希编码。

```javascript
let text = '赵钱孙李'
utils.hashCode(text) // 返回值 1116153329
```

### 删除数组中指定项

`Array.prototype.remove(item)`，无返回值。

【数组原型方法】在数组中移除指定项`item`。

```javascript
let arr = ['test1', 'test2', 'test3']
arr.remove('test2')
console.log(arr) // 打印值为 ['test1', 'test3']
```

### 数组去重

`Array.prototype.unique(arg)`，返回值`array`。

【数组原型方法】对数组进行去重，如果传入了`arg`参数，则会对数组中的对象的`arg`属性进行判定，如果该属性相等则认为这两个对象相同。

```javascript
let arr = [
  { name: '张三', id: '11' },
  { name: '张三', id: '11' },
  { name: '李四', id: '22' }
]
let arr2 = arr.unique('id')
console.log(arr2) // 打印值为 [{name: '张三', id: '11'}, {name: '李四', id: '22'}]
```

### 去除数组中空字符串选项

`Array.prototype.trim()`，返回值`array`。

去除数组中的空字符串选项。

```javascript
let arr = ['test1', 'test2', '', 'test3', '']
let arr2 = arr.trim()
console.log(arr2) // 打印值为 ['test1', 'test2', 'test3']
```

### 数组格式转对象格式并分组

`Array.prototype.groupByKey(key)`，返回值`object`。

将数组中的所有对象按照`key`进行分组，并以`key`为对象 key，以子数组为 value 构建为对象返回。

```javascript
let arr = [{ name: '张三' }, { name: '李四' }]
let obj = arr.groupByKey('name')
console.log(obj)
// 打印值为 {"张三":[{"name":"张三"}],"李四":[{"name":"李四"}]}
```

### 数组对象抽取指定 key 的值，组成新数组

`Array.prototype.extractByKey(key)`，返回值`Array`。

将数组对象中的某一个属性值单独抽取出来成为一个新的数组，示例：
[{id:'1',name:'苹果'},{id:'2',name:'香蕉'}].extractByKey("id") ==> ['1','2']。

### 日期格式化

`Date.prototype.format(format)`，返回值`string`。

- 日期格式：
- yyyy，yy 年份
- MM 大写表示月份
- dd 表示日期
- hh 表示小时
- mm 表示分钟
- ss 表示秒
- q 表示季度
- 实例如下：
- var now = new Date();
- var nowStr = now.format("yyyy-MM-dd hh:mm:ss");

```javascript
let now = new Date()
let nowStr1 = now.format('yyyy-MM-dd hh:mm:ss') // 返回值 2021-06-02 10:06:00
let nowStr2 = now.format('yyyy/MM/dd q') // 返回值 2021/06/02 2
```

## 方法一览表

| 方法名                                                    | 说明                                                                                      | 参数/参数格式                                                                                                                                                                     | 返回值格式      |
| :-------------------------------------------------------- | :---------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------- |
| isEmpty(val)                                              | 判断一个值是否为空                                                                        | val:需要判断的任意值,any                                                                                                                                                          | boolean         |
| getName()                                                 | 获取随机名称                                                                              | —                                                                                                                                                                                 | string          |
| getWriteable(permission)                                  | 判断控件是否可编辑                                                                        | permission 当前权限，string                                                                                                                                                       | boolean         |
| mergeValidate(rules, appendRules)                         | 融合校验规则                                                                              | rules:现有规则, string/object；appendRules:新增的规则,string/object                                                                                                               | string / object |
| reduceValidate(rules, reduceRules)                        | 移除校验规则                                                                              | rules 现有规则，string/object; reduceRules 删除的规则, string/object                                                                                                              | string / object |
| validateString2Object(rule)                               | 字符串校验规则转对象                                                                      | rule 字符串规则, string                                                                                                                                                           | object          |
| stringSplit(str, sep)                                     | 字符串分割为数组                                                                          | str: 需要分割的字符串，string, sep: 分隔符，string                                                                                                                                | array           |
| addRequiredOrNot(permission, validate)                    | 判断控件是否要添加必填校验                                                                | permission:当前权限,string，validate：当前校验规则，string/object                                                                                                                 | string/object   |
| formatDate(value)                                         | 日期格式化为 年月日时分秒                                                                 | value: 日期，`Date`、时间戳、字符串                                                                                                                                               | string          |
| formatDateYear(value)                                     | 日期格式化为 年月日                                                                       | value: 日期，`Date`、时间戳、字符串                                                                                                                                               | string          |
| dateIsBefore(dateOne, dateTwo, canEquals)                 | 判断日期 1 是否早于日期 2                                                                 | dateOne: 日期 1，`Date`、时间戳、字符串；dateTwo: 日期 2，`Date`、时间戳、字符串                                                                                                  | boolean         |
| dateCalc(startDate, endDate, op)                          | 计算日期间隔长度                                                                          | startDate,开始日期，string;结束日期，string;op:间隔单位，string,可选值 year、month、day、hour、minute、second                                                                     | string          |
| nest2tile(arr,childrenKey,obtainChildren)                 | 树形结构数组转换成平铺数组                                                                | arr: 需转换的数组，array; childrenKey: 代表子节点集合的 key 值，默认 children，string；obtainChildren：平铺数组中是否包含子节点集合，默认为 false 不包含，为 true 时包含，boolean | array           |
| tile2nest(array, key, pKey, childrenKey)                  | 普通平铺数组转了树结构嵌套数组                                                            | array: 转换的数组，array;key: 标识 key,string;pKey: 代表父关系的 key,string;childrenKey:代表子节点集合的 key, string,默认为 children                                              | array           |
| getOnlineFormInstance(instance)                           | 获取表单的 VueComponent 实例                                                              | instance: 当前 vue 实例，object                                                                                                                                                   | object          |
| getSubScopeElAndIndex(element)                            | 获取子表的 VueComponent 实例及当前行索引                                                  | element: dom 元素，dom                                                                                                                                                            | object          |
| getSubInputScopeByModelExpression(subScopeEl, expression) | 根据子表 VueComponent 实例获取表达式所对应的 VueComponent 实例                            | subScopeEl: 子节点 dom 元素，dom;expression:v-model 绑定的表达式，string                                                                                                          | object          |
| validateForm(instance, scopeName)                         | 校验指定作用域的表单                                                                      | instance:当前 vue 实例，object; scopeName: 表单名称，string                                                                                                                       | promise         |
| getParentElementByAttribute(element, attribute)           | 获取上级元素中有指定属性的元素                                                            | element: dom 元素；attribute: 属性名,string                                                                                                                                       | HTMLElement     |
| getSomeAttributeFromParentElement(element, attribute)     | 获取上级元素中指定属性的值                                                                | element: dom 元素；attribute: 属性名,string                                                                                                                                       | any             |
| getWholePathOfSub(subPath, mainPath, index)               | 将子表属性路径转换为完整的属性路径                                                        | subPath:子表中的表达式，如：item.name, row.name 等,string;mainPath:子表在整体对象中的路径，例如:data.sub, data.children 等,string; index:为子表哪一条数据的索引,number            | string          |
| getValueByPath(instance, path, subIndex)                  | 获取路径所对应的值                                                                        | instance:当前 vue 实例，object; path: 值在实例中的路径，string;subIndex:如果是子表数据，需要传入`subIndex`指定索引，number                                                        | any             |
| setValueByPath(instance, path, value, subIndex)           | 根据路径设置值                                                                            | instance:当前 vue 实例，object;path: 值在实例中的路径，string;value: 新值，any；subIndex:如果是子表数据，需要传入`subIndex`指定索引，number                                       | —               |
| parseToJson(jsonStr, type)                                | 字符串解析为 JSON 对象                                                                    | jsonStr: 字符串，string;type: 可选值 1，2，number，1 是使用 JSON.parse(jsonStr)的方式来解析，2 是使用 eval()的方式来解析                                                          | object          |
| convertCurrency(currencyDigits)                           | 数字转人民币大写                                                                          | currencyDigits: 金额数值，number                                                                                                                                                  | string          |
| getUrlKey(name)                                           | 获取 URL 地址中指定参数的值                                                               | name: 参数 key 值，string                                                                                                                                                         | string          |
| arrayMove(ary, part, direct)                              | 将数组中的一个或多个元素调整顺序                                                          | ary: 原数组，array;part: 需要移动部分，array，direct:移动方向，string，可选值 up 和 down，默认 down                                                                               | array           |
| getValueByConfigKey(instance, config, key)                | 通过配置来获取对应的值                                                                    | instance:当前 vue 实例，object; config:外部传入的配置信息，object；key: 需要获取 config 中的值的 key, string                                                                      | any             |
| setValueByConfigKey(instance, config, key, value)         | 通过配置来设置对应的值                                                                    | instance:当前 vue 实例，object; config:外部传入的配置信息，object；key: 需要修改的 config 中的值的 key, string；value:新值，any                                                   | —               |
| objectEquals(obj1, obj2, props)                           | 深度对比两个对象是否相等                                                                  | obj1: 对象 1，object;obj2:对象 2，object;props: 选填，如果传入了就只校验 props 中的属性是否相等，array                                                                            | boolean         |
| arrayEquals(ary1, ary2)                                   | 深度对比两个数组是否相等                                                                  | ary1: 数组 1，array; ary2:数组 2，array                                                                                                                                           | boolean         |
| trimEachLine(text)                                        | 对大文本进行缩进处理                                                                      | text: 需要处理的文本，string                                                                                                                                                      | string          |
| hashCode(text)                                            | 获取大文本的哈希编码                                                                      | text: 需要处理的文本，string                                                                                                                                                      | string          |
| Array.prototype.remove(item)                              | 数组中移除指定项                                                                          | item: 需移除的选项，string/number                                                                                                                                                 | —               |
| Array.prototype.unique(arg)                               | 数组去重                                                                                  | arg: 非必传，如果传入了`arg`参数，则会对数组中的对象的`arg`属性进行判定，如果该属性相等则认为这两个对象相同，string                                                               | array           |
| Array.prototype.trim()                                    | 数组去除空白项                                                                            | —                                                                                                                                                                                 | array           |
| Array.prototype.groupByKey(key)                           | 将数组中的所有对象按照`key`进行分组，并以`key`为对象 key，以子数组为 value 构建为对象返回 | key: 分组属性的 key 值，string                                                                                                                                                    | object          |
| Array.prototype.extractByKey(key)                         | 数组抽取指定属性的值成为一个新的数组                                                      | key: 指定属性的 key 值，string                                                                                                                                                    | array           |
| Date.prototype.format(format)                             | 日期格式化                                                                                | format: 格式模板， yyyy、yy 年份， MM 大写表示月份，dd 表示日期， hh 表示小时，mm 表示分钟，ss 表示秒，q 表示季度，string                                                         | string          |
