// Rather than having to pass data via a components heirarchy // (passing data from the parents to children) we initialise an empty // vue component that allows us access to the event system when needed. var $eventBus = new Vue(); // Home Slider Component Vue.component('home-slider', { template: '
', data: function() { return { // The current slide to be shown... activeSlide: 0, interval: null, } }, // Called after the instance has been mounted... mounted: function() { var $this = this; $this.nextSlide(); $this.interval = setInterval(function() { $this.nextSlide(); }, 4000); $eventBus.$on('activeSlide', function (activeSlide) { $this.activeSlide = activeSlide; }); $eventBus.$on('clickSlide', function (activeSlide) { $this.reInitInterval(); $eventBus.$emit('activeSlide', activeSlide); }); }, // Essentially variables that can hold logic... computed: { slideCount: function() { return $('.home-slide').length; } }, methods: { nextSlide: function() { if(this.activeSlide == this.slideCount) { this.activeSlide = 1; } else { this.activeSlide++; } $eventBus.$emit('activeSlide', this.activeSlide); }, reInitInterval: function() { var $this = this; clearInterval($this.interval); $this.interval = setInterval(function() { $this.nextSlide(); }, 4000); } } }); // Home Slide Component Vue.component('home-slide', { template: '
', props: ['id', 'image', 'imageAlt'], data: function() { return { activeSlide: 0 } }, mounted: function() { var $this = this; $eventBus.$on('activeSlide', function (activeSlide) { $this.activeSlide = activeSlide; }); } }); // Home Slide Button Component Vue.component('home-slide-button', { template: '
{{ title }}
{{ text }}
', props: ['id', 'title', 'text'], data: function() { return { activeSlide: 0 } }, computed: { active: function() { return this.activeSlide == this.id; } }, mounted: function() { var $this = this; $eventBus.$on('activeSlide', function (activeSlide) { $this.activeSlide = activeSlide; }); }, methods: { handleClick: function() { if(this.activeSlide != this.id) { $eventBus.$emit('clickSlide', this.id); } } } }); Vue.component('progress-bar', { props: ['activeSlide', 'id'], watch: { activeSlide: function() { if(this.activeSlide == this.id) { $(this.$refs.bar).stop().animate({ width: '0%' }, 0); $(this.$refs.bar).stop().animate({ width: '100%' }, 4000); } else if(this.activeSlide > this.id) { $(this.$refs.bar).stop().animate({ width: '100%' }, 0); } else { $(this.$refs.bar).stop().animate({ width: '0%' }, 0); } } }, template: '
' }); Vue.component('emblem', { props: ['title', 'text', 'modifierClass'], template: '
{{ title }}
{{ text }}
', /*
{{ title }}
{{ text }}
*/ }); Vue.component('feature-panel', { template: '
', data: function() { return { slideCount: 3, activeSlide: 1, timer: null } }, mounted: function() { var $this = this; this.startRotation(); $eventBus.$on('featuredPanel.activeSlide', function (activeSlide) { $this.stopRotation(); $this.activeSlide = activeSlide; }); }, methods: { startRotation: function() { this.timer = setInterval(this.next, 3000); }, next: function() { if(this.activeSlide == this.slideCount) { this.activeSlide = 1; return true; } this.activeSlide++; }, stopRotation: function() { clearTimeout(this.timer); this.timer = null; }, } }); Vue.component('feature-panel-slide', { template: '
', props: ['id', 'image', 'activeSlide'], mounted: function() { // Preload images... var image = new Image(); image.src = this.image }, computed: { active: function() { return this.id == this.activeSlide; } } }); Vue.component('feature-panel-button', { template: '
{{title}}
{{text}}
', props: ['id', 'text', 'title', 'activeSlide', 'image'], computed: { active: function() { return this.id == this.activeSlide; } }, methods: { handleButtonClick: function() { $eventBus.$emit('featuredPanel.activeSlide', this.id); } } }); // Root Instance... var app = new Vue({ el: '#app', });