1. 程式人生 > 實用技巧 >二、配置檔案

二、配置檔案

自定義指令

自定義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
	  }
  }