Vueschool - directives

by joplomacedo

HTML

<div id="app">
  <p v-show="show" v-clicked-outside="clickedOutside" v-switching-color:crazy.underline="colors">I will be color</p>
</div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}

Vue

Vue.directive('clicked-outside', {
	bind( el, binding ) {
		const cb = binding.value;
		
		el.listener = function ( e ) {
			if ( el !== e.target && !el.contains(e.target) ) {
				cb();
			}
		};
		
		document.body.addEventListener('click', el.listener);
	},
	
	unbind() {
		document.body.removeEventListener('click', el.listener);
	}
});

Vue.directive('switching-color', {
	bind ( el, binding ) {
		const colors = binding.value;

		const speed = {
			slow: 2000,
			normal: 1000,
			fast: 500,
			crazy: 100
		}[binding.arg];


		let i = 0;

		function switchColor() {
			el.style.color = colors[i++];
		}

		if ( binding.modifiers.underline ) {
			el.style.textDecoration = 'underline';
		}

		el._interval = setInterval( () => {
		console.log('switch');
			switchColor();
			if ( i == colors.length ) {
				i = -1;
			}
		}, speed);

		switchColor();
	},
	
	unbind( el ) {
		clearInterval(el._interval);
	}
})

new Vue({
  el: "#app",
  data: {
	colors: ['purple', 'orange', 'red'],
	show: true
  },
  methods: {
	clickedOutside() {
		this.show = false;
	}
  },
  
  created() {

  }
})