二、配置檔案
阿新 • • 發佈:2020-11-30
自定義指令
自定義focus
const focus = {
inserted: function(el){
el.focus();
}
}
export default focus;
<input type="text" v-focus />
自定義test
import Vue from 'vue' import App from './App.vue' import focus from './directive/focus/index.js' Vue.config.productionTip = false Vue.directive('focus',focus); Vue.directive('test',{ // bind: 只調用一次,指令第一次繫結到元素時呼叫,用這個鉤子函式可以定義一個在繫結時執行一次的初始化動作. // inserted: 被繫結元素插入父節點時呼叫(父節點存在即可呼叫,不必存在於 document 中) . // update: 被繫結元素所在的模板更新時呼叫,而不論繫結值是否變化。 // 通過比較更新前後update: 被繫結元素所在的模板更新時呼叫,而不論繫結值是否變化。 // 通過比較更新前後的繫結值,可以忽略不必要的模板更新。 // componentUpdated: 被繫結元素所在模板完成一次更新週期時呼叫. // unbind: 只調用一次,指令與元素解綁時呼叫 。 bind:function(el, binding, vnode){ debugger // el 指令所繫結的元素,可以用來直接操作 DOM. el var keys = [] for(var i in vnode){ keys.push(i) } // name: 指令名,不包括 v-字首。 // value: 指令的繫結值,例如 v-my-directive=1+ 1”, value的值是2. // oldValue: 指令繫結的前一個值,僅在 update 和 componentUpdated 鉤子中可用.無論 // 值是否改變都可用 。 // expression 繫結值的字串形式。例如v-my-directive="1+ 1”,expression的值是”1+1”. // arg 傳給指令的引數。例如 v-my-directive:foo, arg 的值是 foo. // modifiers 一個包含修飾符的物件 。 例如 v-my-directive.foo.bar,修飾符物件 modifiers的值是{ foo: true, bar: true }。 // vnode Vue 編譯生成的虛擬節點 // oldVnode 上一個虛擬節點僅在 update 和 componentUpdated 鉤子中可用 el.innerHTML = 'name:' + binding.name + '<br>' + 'value:' + binding.value + '<br>' + 'expression:' + binding.expression + '<br>' + 'argument:' + binding.arg + '<br>' + 'modifiers:' + JSON.stringify(binding.modifiers) + '<br>' + 'vnode keys:' + keys.join(', ') } }); new Vue({ render: h => h(App), }).$mount('#app')
v-test 使用
<template>
<div id="parent">
<div v-test:msg.a.b="message"></div>
</div>
</template>
<script>
export default{
name: 'directive',
data(){
return{
message: 'some text'
}
}
}
</script>
點選外部關閉的下拉選單
<template> <div> <div class="main" v-clickoutside="handleClose"> <button @click="show =! show">下拉</button> <div class="dropdown" v-show="show"> <p>點選外部關閉的下拉選單</p> </div> </div> </div> </template> <script> export default{ data(){ return{ show:false } }, methods:{ handleClose(){ this.show = false } } } </script> <style> .main{ width: 120px; } button{ display: block; width: 100%; color: #fff; background-color: #39f; border: 0; padding: 6px; text-align: center; border-radius: 4px; cursor: pointer; outline: none; position: relative; } button:active{ top: 1px; left: 1px; } .dropdown{ width: 100%; height: 150px; margin: 5px 0; background-color: #fff; border-radius: 4px; box-shadow: 0 1px 6px rgba(0,0,0,.2); } </style>
Vue.directive('clickoutside',{ bind:function(el, binding, vnode){ function documentHandler(e){ if(el.contains(e.target)){ return false; } if(binding.expression){ // 執行表示式 binding.value(e) } } //在自定義指令中,不能再用 this.xxx 的形式在上下文中宣告一個變數, //所以用了 el.__vueClickOutside__ 引用了 docurnentHandler el.__vueClickOutside__ = documentHandler; document.addEventListener('click',documentHandler) }, unbind:function(el,binding){ document.removeEventListener('click',el.__vueClickOutside__) //如果不移除, 當元件或元素銷燬時,它仍然存在於記憶體中 delete el.__vueClickOutside__; } })
實時時間轉換指令
var Time = {
//獲取當前時間戳
getUnix() {
var date = new Date();
return date.getTime();
},
//獲取今天 0 點 0分 0秒的時間戳
getTodayUnix() {
var date = new Date();
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
date.setMilliseconds(0)
return date.getTime();
},
//獲取今年 1月 1 日 0點 0分 0秒的時間戳
getUYearUnix() {
var date = new Date();
date.setMonth(0);
date.setDate(1);
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
date.setMilliseconds(0)
return date.getTime();
},
//獲取標準年月日
getLastDate(time) {
var date = new Date(time);
var month =
date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
var day =
date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
return date.getFullYear() + '-' + month + '-' + day;
},
//轉換時間
getFormatTime(timestamp) {
var now = this.getUnix()
var today = this.getTodayUnix()
var year = this.getUYearUnix();
var timer = (now - timestamp) / 1000;
var tip = '';
if (timer <= 0) {
tip = '剛剛'
} else if (Math.floor(timer / 60) <= 0) {
tip = '剛剛'
} else if (timer < 3600) {
tip = Math.floor(timer / 60) + '分鐘前';
} else if (timer >= 3600 && (timestamp - today >= 0)) {
tip = Math.floor(timer / 3600) + '小時前';
} else if (timer / 86400 <= 31) {
tip = Math.ceil(timer / 86400) + '天前';
} else {
tip = this.getLastDate(timestamp);
}
return tip;
}
}
export default Time
Vue.directive('time',{
bind: function(el, binding){
el.innerHTML = Time.getFormatTime(binding.value)
el.__timeout__ = setInterval(function(){
el.innerHTML = Time.getFormatTime(binding.value)
}, 60000);
},
unbind: function(el){
clearInterval(el.__timeout__);
delete el.__timeout__;
}
})
<div v-time="timeNow"></div>
<div v-time="timeBefore"></div>
<div v-time="timeBefore2"></div>
data(){
return{
timeNow:(new Date()).getTime(),
timeBefore: 1606800579180,
timeBefore2: 1488930695721
}
}