JSFiddle - React, Tailwind, and code Playground

by nkovacs

HTML

<script src="https://rawgit.com/yyx990803/vue/master/dist/vue.js"></script>
<a href="#" v-on="click: navigate('page1')">Page 1</a>

<a href="#" v-on="click: navigate('page2')">Page 2</a>

<a href="#" v-on="click: logout">Log out</a>

<component is="{{view}}" v-transition="page" transition-mode="out-in" keep-alive></component>

CSS

.page-transition {
    transition: all .5s ease;
}
.page-enter {
    opacity: 0;
}
.page-leave {
    opacity: 0.1;
}

JavaScript

Vue.config.debug = true;

Vue.use(function(Vue, globalOptions) {

	// monkey patch component directive
	var componentDirective = Vue.directive('_component');

	componentDirective.originalTransition = componentDirective.transition;
	componentDirective.transition = function(target, cb) {
		if (!target.$authorized || target.$authorized()) {
			this.originalTransition(target, cb);
		} else {
			target.$dispatch('loginrequired');
		}
	};

	Vue.directive('_component', componentDirective);

	var vm = new Vue({
		data: {
			token: null,
			user: null
		}
	});

	Vue.authManager = {
		methods: {
			loginUser: function(token, user) {
				vm.token = token;
				vm.user = user;
			},
            logout: function() {
                vm.token = null;
                vm.user = null;
                this.$broadcast('logout');
            }
		}
	};

	// auth mixin
	Vue.auth = function(rules) {
		return {
			methods: {
				$authorized: function() {
					if (!rules) {
						return true;
					}

					if (vm.user) {
						return true;
					}

					return false;
				}
			},
            events: {
                logout: function() {
                    if (!this.$authorized()) {
                        this.$dispatch('loginrequired');
                    }
                }
            }
		};
	};
});

new Vue({
    el: 'body',
    mixins: [Vue.authManager],
    data: {
        view: null,
        loggedIn: false,
        viewAfterLogin: null
    },
    methods: {
        navigate: function(page) {
            this.view = page;
        }
    },
    events: {
        loginrequired: function() {
            this.viewAfterLogin = this.view;
            this.view = 'login';
        },
        loggedIn: function() {
            this.loggedIn = true;
            this.loginUser(true, true);
            this.view = this.viewAfterLogin;
        }
    }
});

Vue.component('page1', {
    template: "<div>page 1</div>",
    data: function () {},
    mixins: [Vue.auth(true)],
    methods: {},
   ...