場景:

過濾器實現場景

有一段時間沒寫代碼了,有點手寫,於是上網找了一份很簡單的vue項目,看到過濾器,挺有意思的,記錄一下。通過axios從AIP取到的數據:

last_reply_at: "2019-05-09T13:41:56.443Z"

如上圖,總不能直接顯示吧,如果能顯示幾秒前、幾分鐘前、幾小時前、幾天前,那也是滿滿的逼格啊。這也算是挺常見的需求。先來看看Vue官網怎麼說的:

在 JavaScript 表達式的尾部,由「管道」符號指示:

<!-- 在雙花括弧中 -->
{{ message | capitalize }}

<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>

你可以在一個組件的選項中定義本地的過濾器:

filters: {
capitalize: function (value) {
if (!value) return
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}

或者在創建 Vue 實例之前全局定義過濾器:

Vue.filter(capitalize, function (value) {
if (!value) return
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})

new Vue({
// ...
})

已經寫得挺詳細了,那我們可以在代碼中這樣寫:main.js注局全局過濾器,也可以在組件中註冊,不過這算是一個很公用的過濾器,為了方便我註冊成全局過濾器。

new Vue({
el: #app,
router,
template: <App/>,
components: { App }
})

Vue.filter(formatDate, function(str) {
if (!str) return Object.keys(filters).forEach((key) => { Vue.filter(key, filters[key][key]) })
var date = new Date(str)
var time = new Date().getTime() - date.getTime() //現在的時間-傳入的時間 = 相差的時間(單位 = 毫秒)
if (time < 0) {
return
} else if ((time / 1000 < 30)) {
return 剛剛
} else if (time / 1000 < 60) {
return parseInt((time / 1000)) + 秒前
} else if ((time / 60000) < 60) {
return parseInt((time / 60000)) + 分鐘前
} else if ((time / 3600000) < 24) {
return parseInt(time / 3600000) + 小時前
} else if ((time / 86400000) < 31) {
return parseInt(time / 86400000) + 天前
} else if ((time / 2592000000) < 12) {
return parseInt(time / 2592000000) + 月前
} else {
return parseInt(time / 31536000000) + 年前
}
}
)

思路是時間字元串轉化成時間毫秒,與當前時間相減。得出時間差。

組件中調用也很簡單:

<span class="last_reply">
{{ post.last_reply_at | formatDate}}
</span>

注意了,我們把過濾器寫在main.js中,萬一項目大一,有多個過濾器,那main.js豈不是一堆代碼,為了項目模塊化,最好是有專門的目錄來統一存放這些過濾器。接下來創建一個filters目錄。

過濾器目錄

data_format.js

export const formatDate = (str) => {
if (!str) return
var date = new Date(str)
var time = new Date().getTime() - date.getTime() //現在的時間-傳入的時間 = 相差的時間(單位 = 毫秒)
if (time < 0) {
return
} else if ((time / 1000 < 30)) {
return 剛剛
} else if (time / 1000 < 60) {
return parseInt((time / 1000)) + 秒前
} else if ((time / 60000) < 60) {
return parseInt((time / 60000)) + 分鐘前
} else if ((time / 3600000) < 24) {
return parseInt(time / 3600000) + 小時前
} else if ((time / 86400000) < 31) {
return parseInt(time / 86400000) + 天前
} else if ((time / 2592000000) < 12) {
return parseInt(time / 2592000000) + 月前
} else {
return parseInt(time / 31536000000) + 年前
}

index.js,用來統一導出過濾器

const formatDate = require(./data_format)
module.exports = {
formatDate
}

main.js

new Vue({
el: #app,
router,
template: <App/>,
components: { App }
})

Object.keys(filters).forEach((key) => { Vue.filter(key, filters[key][key]) })

OK,實現,問題不大

推薦閱讀:

相關文章