项目中我们总有不少公共方法要提取,在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>