vue项目中公共方法的配置和调用

项目中我们总有不少公共方法要提取,在Vue中具体大致可采用三种形式来实现。

一、过滤器

通常直接在实例模版中使用,用于处理数据格式。
注⚠️:我在webpack中配置过路径别名,以下代码中的 @ 都是src文件夹的别名

把处理格式的函数都写在src/filters/index.js里,每个方法都单独export。过滤器函数都必须有返回值

// src/filters/index.js

/**
 * 把时间处理成所需格式的字符串
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime(time, cFormat) {
  if(!time) {
    return ''
  }
  if (arguments.length === 0) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
      time = parseInt(time)
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    return value.toString().padStart(2, '0')
  })
  return time_str
}

/** 截取字数长度, 常用
  * @param {string} text
  * @param {number} length
*/
export function textFilter(text, length){
  let shortText = text
  const len = length ? length : 20
  if (text && text.length > len) {
    shortText = text.substring(0, len) + '...'
  }
  return shortText
}

在 src/main.js 注册过滤器

import * as filters from './filters' 
// 注册全局公共过滤器
Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
})

3.在实例模版中使用

<template>
  <div class="app-container">
    <el-table-column label="发布日期" align="center" sortable="custom" prop="created_time">
      <template slot-scope="scope">
        {{ scope.row.created_time | parseTime('{y}-{m}-{d}') }}
      </template>
    </el-table-column>
    <el-table-column label="详情" align="center">
      <template slot-scope="scope">
        {{ scope.row.detail | textFilter(10) }}
      </template>
    </el-table-column>
  </div>
</template>

二、在实例 import 公共方法

在 src/utils/index.js 单独导出这些具名函数

/**
 * 把标准时间转换成时间戳
 * 传入标准时间
 */
export function timestamp(date) {
  let myDate = date ? new Date(date) : new Date()
  return Date.parse(myDate) / 1000
}

/**
 * 时间戳转换成把标准时间
 * 传入时间戳
 */
export function standardTime(timestamp) {
  let time = timestamp.toString() + '000'
  return new Date(parseInt(time))
}

2.在实例中导入需要的方法并使用

import { timestamp, standardTime } from '@/utils'

export default {
  filters: {
    statusFilter(time) { // 在局部过滤器中使用
      let status = time > timestamp() ? 'success' : 'info'
      return status
    }
  },
  computed: {
    nowTime() {  // 在计算属性中使用
      return timestamp()
    }
  },
  methods: {
    handleEdit(id) { // 在实例方法中使用
      ...
      this.newTrade.validTime = standardTime(this.newTrade.validTime)
    },
  }
}

三、全局方法

像二那样每次要使用都要在实例里面import一遍,如果是使用率比较高的方法,我们还是挂载到全局比较方便。比如经常要用到的删除和批量删除数据。

// src/utils/common.js

import {
  Message,
  MessageBox,
} from 'element-ui'

/**
 * 删除数据
 * @id {(string)} 多个id用 , 分隔
 * @deleteFun {Function} 删除数据调用的Api方法
 * @callback {Function} 删除成功的回调
 * @returns {null}
 */
export const deleteById = (id, deleteFun, callback) => {
  MessageBox.confirm('是否要永久删除该信息', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warn'
  })
    .then(() => {
      deleteFun(id).then(res => {
        Message({ type: 'success', message: res.message })
        callback()
      })
    })
    .catch(() => {
      Message({ type: 'info', message: '已取消删除' })
    })
}

/**
 * 批量删除数据
 * ...
 */
export const multipleDelete = (multiData, deleteFun, callback) => {
  ...
}

/**
 * el-table列数据筛选
 * 可直接在组件模版调用
*/
export const filterChange = (filters, target) => {
  Object.assign(target.queryInfo, filters)
  target.fetchData('new')
}

/**
 * el-table列数据排序
 * 可直接在组件模版调用
*/
export const sortChange = (sortInfo, target) => {
  let order = sortInfo.order
  order === 'ascending' ? (order = 1) : (order = -1)
  target.queryInfo.sortJson = {}
  target.queryInfo.sortJson[sortInfo.prop] = order
  target.queryInfo.sort = JSON.stringify(target.queryInfo.sortJson)
  target.fetchData('new')
}

在 main.js 整体导入包含所有方法(变量)的模块(这里我们给它定义了 commonApi 的别名),然后挂载在 Vue.prototype上

// src/main.js
import * as commonApi from '@/utils/common'
Vue.prototype.commonApi = commonApi

在实例里方法里调用

import { deleteFossil } from '@/api/fossil'
methods: {
  fetchData(param) { ... },
  handleDelete(id) {
    this.commonApi.deleteById(id, deleteFossil, this.fetchData)
  },
}

如果该全局方法,没有像上述deleteById一样有引用非实例方法的参数(deleteFossil是外部导入的请求方法),也可以直接在template里调用,如下:

因为模版中直接调用的方法,vue会自动给我们加上this

<template>
  <div class="app-container">
    <el-table
      v-loading="listLoading"
      :data="list"
      element-loading-text="Loading"
      border
      fit
      highlight-current-row
      :empty-text="emptyText"
      @selection-change="handleSelectionChange"
      @filter-change="filters => commonApi.filterChange(filters, this)"
      @sort-change="sortInfo => commonApi.sortChange(sortInfo, this)"
    >
      ...
    </el-table>
  </div>
</template>
上一篇:Vue基础——过滤器(全局过滤器和局部过滤器)


下一篇:Vue中filters使用data的数据