如果人有選擇,真的只會選擇容易走的路或容易成為的自己嗎?不見得吧!?
有時候我們希望使用者在進入頁面時,會自動的將滑鼠停留在某個輸入框,例如登入頁面或是搜尋頁面,這部分在實做 Vue 的時候改怎麼處理呢?我們將以自定義 Vue 的全域指令 Vue.directive 來完成。
接著我們希望在某些輸入框輸入內容時樣式會不一樣,這點除了在樣式上可以辦到,也可以用自定義過濾器捯到一樣的效果。
如果希望頁面有時間戳的顯示,以往我們會以new Date()
會來取得當下的時間,但是所取到的卻不是我們希望的格式,這時會想到的處理方式是另外載入「處理時間」的套件,列如moment.js
來管理時間顯示的問題,但今年九月中moment.js
官網公布了不再維護的消息。其實替代方案 Vue 是做的到的,只要利用「自定義過濾器」的特性,就可辦到。
在前幾篇有提到,過濾器的功能是要對顯示的資料進行特定的格式化後再顯示,且過濾器並不會去改變原本的資料,而是產生一個新的對應的資料格式。
自定義過濾器可以定義為全域或是局部,我們今天實做的以全域為主,這樣的複用性比較高,但如果全域的自定義過氯氣和局部的同名,那麼會以就近為原則,優先權是局部的過濾器。
先來看一下Codepen的範例。
在輸入框的元素上,我們加上了v-focus
(自定義指令)和v-color
(自定義過濾器)的屬性。
Search:<input
type="text"
v-model="keywords"
@keyup.enter="search"
id="search"
v-focus
v-color="'blue'"
/>
我們所定義的指令名為focus
,關於自定義指令的說明可以看前幾天的Vue 自定義指令 Custom Directives
定義全域指令的語法為 Vue.directive('指令名',物件)
,可以用原生的focus()
掛載到 Vue 的 inserted hook 鉤子上,在以下的 hook 鉤子函式中,第一個參數永遠都是 el,表示被綁定了指令的那個元素,這個 el 參數是一個原生的 JS 物件。inserted hook 的時間點是當我們有插入值時,才會執行。
focus()
的 JS 原生寫法為 document.querySelector('#search').focus();
HTMLElement.focus() - Web API 接口參考 | MDN
Vue.directive('focus', {
bind: function (el) {
// 綁定 bind 時:每當指令綁定到元素上時,會立刻執行這個bind韓式,且只執行一次。
// 在元素剛被綁定的時候,還沒有插入到DOM中去,這時呼叫focus方法不會執行,因為一個元素只有插入(inserted)DOM之後才會有聚焦效果。
},
inserted: function (el) {
// 插入值時:inserted 表示元素插入到DOM中時會執行inserted 函式。(觸發一次)
// 和JS有關的操作,最好在inserted的階段中去執行,防止JS行為不生效。
el.focus();
},
});
由於我們希望是在新增產品時就增加顯示時間,所以我們會以new Date()
會來取得當下的時間,再用自定義過濾器來改變時間格式。
過濾器使用的語法為:
// 使用過濾器
<div>{{ 綁定的元素 | 自定義過濾器名稱 }}</div>
<div>{{ myData | filterName(arg) }}</div>
新增全域過濾器的語法為:Vue.filter('自定義過濾器名稱', callback 函式)
。
把年月份與時分秒一一取出處理,在放到各自代表的變數裡,確認時間格式皆為小寫,並回傳我們希望的格式。
// 全域時間過濾器
Vue.filter('showDateTime', (dateNow, pattern = '') => {
// 根據給的時間字串,得到特定的時間
let dateTime = new Date(dateNow);
// yyyy/mm/dd
let year = dateTime.getFullYear();
let month = (dateTime.getMonth() + 1).toString().padStart(2, '0');
let day = dateTime.getDate().toString().padStart(2, '0');
// 讓時間格式皆為小寫
if (pattern.toLowerCase() === 'dd.mm.yyyy') {
return `${day}.${month}.${year}`;
} else {
let hour = dateTime.getHours().toString().padStart(2, '0');
let minute = dateTime.getMinutes().toString().padStart(2, '0');
let second = dateTime.getSeconds().toString().padStart(2, '0');
return `${day}.${month}.${year} | ${hour}:${minute}:${second}`;
}
});
我們可以使用自定義過濾器來改變某元素的樣式,,一樣會使用到生命週期的鉤子bind
來綁定執行函式的時機。
// 自定義改變字體顏色
Vue.directive('color', {
bind: function (el, binding) {
console.log(binding.value);
console.log(binding.expression);
el.style.color = binding.value;
},
});
每日一句法文有益身心:C'est mignon ! --> say.瞇.扭! --> 好可愛喔。