Story: Actually, FOR a long time, I wanted to learn the details of VUex and VUE components through a simple project, so I wrote a very simple and rough case to deepen my memory in my spare time. The case involves vuex  localstorage  Login to interceptEtc.



Vuex modular use:

Install vuex and set up the structure of the VUex file

npm install vuex --saveCopy the code

Create a store folder in the SRC folder and create index.js type.js and modules

Use constants instead of mustation event types;

The global.js and user.js files in the modules folder are the modularization files I defined respectively representing the account center and the global VUex module. Each module has its own state actions getters mutations;

Index. js mounts store as follows

-- -- -- -- -- -- -- -- -- -- -- -- -- - index. Jsimport Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import global from './modules/global'

Vue.use(Vuex)

const store = new Vuex.Store({
 modules: {
  user,
  global
 }
})

export default store;Copy the code

New vuex.store ({}) creates a Vuex instance. Normally, it needs to be injected into the Vue instance. Store is a core method of Vuex, which literally means “repository.” Vuex Store is responsive. When the Vue component reads the state from the Store (state option), if the state in the Store is updated, it will timely respond to other components (similar to two-way data binding) and cannot directly change the state of the Store. The only way to change the state of the Store is, Explicitly submit the changes option

The js as follows

-------------------------type.js
/** * * @authors Your Name ([email protected]) * @date 2018-08-27 19:46:08 * @version $Id$ */

/ * * / user users
export const IS_LOGIN      = 'IS_LOGIN'             // Set user information


/ * global global * /

export const GLOBAL_BGCOLOR = 'GLOBAL_BGCOLOR'        // Set the theme color


Copy the code

User. Js as follows

-----------------------------user.js
/** * * @authors Your Name ([email protected]) * @date 2018-08-27 19:55:37 * @version $Id$ */
import * as types from '.. /type'
import ajax from '@/fetch/index'

const state = {
 isLogin: false

}

const actions = {
 isLogin({ commit },res) {
  commit(types.IS_LOGIN, res)
 }
}

const getters = {
 isLogin: state= > state.isLogin,
}

const mutations = {
    [types.IS_LOGIN](state, res) {
        state.isLogin = res.isLogin
    }
}

export default {
 state,
 actions,
 getters,
 mutations
}Copy the code

Global. Js as follows

---------------global.js
/** * * @authors Your Name ([email protected]) * @date 2018-08-28 17:54:40 * @version $Id$ */

/* Universal configuration */
import * as types from '.. /type'
import {Local} from '@/storage'
const state = {
 bgColor:  Local.get('bgColor') | |"blue"
}

const actions = {
 setbgColor({commit},color) {
  commit(types.GLOBAL_BGCOLOR,color)
 }
}


const getters = {
 bgColor: state= > state.bgColor
}


const mutations = {
 [types.GLOBAL_BGCOLOR](state, color) {
        state.bgColor = color
        Local.set('bgColor',color)
    }
}


export default {
    state,
    actions,
    getters,
    mutations
}Copy the code

Import the index.js file under store in main.js and register

--------------------main.js
import Vue from 'vue'
import App from './App'
import router from './router/permission'
import store from './store'
Vue.config.productionTip = false

/* Global component */
import commonComponents from './common-components.js'
Vue.use(commonComponents)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})Copy the code

Hello. Vue as follows

<template> <div> <button type="button" style="margin-top: 20px" @click="getLogin"> </button><br >< button type="button" style="background:#f60; margin-top: 20px; color:#fff;" @click="setTheme('orange')"> </button><br/> <button type="button" style="background:#2577e3; margin-top: 20px; color:#fff;" </button><br/> <router-link tag="div" to="/user"> <button type="button" style="margin-top: </button> </router-link> </div> </template> <script> import Ajax from '@/fetch/index' import {Cookie} from '@/storage/index' import { mapState, mapGetters ,mapActions,mapMutations} from 'vuex' export default { data() { return { } }, mounted() { }, methods: { getLogin() { console.log(this.isLogin) //console.log(this.$store.getters.isLogin) }, setTheme(color) { this.$store.dispatch('setbgColor',color) //console.log(this.$store.getters.bgColor) } }, created() { const _this = this; ajax.get('apis/register/wap/member/check',{}) .then(function(res) { _this.$store.dispatch('isLogin',{"isLogin": res.data.result.isLogin}) }) }, computed: { ... mapGetters([ 'isLogin' ]) } } </script> <style> button { border: none; width: 120px; height: 40px; cursor: pointer; outline: none; } .button { display:inline-block; background:#f60; margin-top: 20px; color:#fff; height:40px; width:120px; text-decoration: none; line-height: 40px; text-align: center; } </style>Copy the code

Note: this.$store.dispatch(‘setbgColor’,color) means to distribute actions or through the helper function mapActions as follows

methods: { ... mapActions({setTheme: "setbgColor"})}Copy the code

The color parameter will be passed by default

Likewise this.$store.getters. IsLogin can be accessed via the helper function mapGetters as follows

computed: { ... mapGetters(['isLogin'])}Copy the code

Here we map this.isLogin to this.$store.getters. IsLogin via the helper function as follows

methods: {
    getLogin() { console.log(this.isLogin) <! Console. log(this).$store.getters.isLogin)
    }
}

Copy the code


Knowledge:

Page through localStorage to achieve the skin function

Create a storage folder in the SRC directory to encapsulate localStrorage and cookies

-------------------------------index.js
const ls = window.localStorage;
export const Local = {
    get(key) {
        if (key) return JSON.parse(ls.getItem(key))
        return null
    },
    set(key, val) {
        const setting = arguments[0]
        if (Object.prototype.toString.call(setting).slice(8.- 1) = = ='Object') {
            for (const i in setting) {
                ls.setItem(i, JSON.stringify(setting[i]))
            }
        } else {
            ls.setItem(key, JSON.stringify(val))
        }
    },
    remove(key) {
        ls.removeItem(key)
    },
    clear() {
        ls.clear()
    }
}

Copy the code

Complete the TOAST component and component management

--------------------Toast/index.vue

<template>
	<transition name="fade">
		<div class="toast-wrap" v-show="show">
			<span>{{msg}}</span>
		</div>
	</transition>
</template>

<script>
	export default {
		data() {
			return {
				msg: "",
				show: true
			}
		},
		methods: {

		}
	}

</script>


<style>
 	.fade-enter-active, .fade-leave-active {
		transition: opacity .3s;
	}
	.fade-enter, .fade-leave {
	 	opacity: 0;
	}
	.toast-wrap {
		position: fixed;
		max-width: 80%;
		left: 50%;
		top:50%;
		padding: 20px;
		border-radius: 10px;
		text-align: center;
		transform: translate3d(-50%,-50%,0);
		color: #fff;Background: RGBA (0, 0, 0, 0.7); font-size: 14px; } </style>Copy the code

----------------------------------Toast/index.js
/** * * @authors Your Name ([email protected]) * @date 2018-08-30 14:26:05 * @version $Id$ */

import Vue from 'vue'
import ToastComponent from './index.vue'

let initComponent = null;
let timer = null;

const merge = ($data, option) = > {
    for ( let prop in option) {
        if ($data.hasOwnProperty(prop)) {
            $data[prop] = option[[prop]]
        }
    }
};

/* Constructor */
let ToastConstructor = Vue.extend(ToastComponent);


const Toast = (option = {}) = > {
	if(initComponent) {
		initComponent.show = true
		if (timer) {
	    	clearInterval(timer)
	    }
	    initComponent.$el.removeEventListener('transitionend', initComponent.destroyeInitComponent)
	}else {
		/* Create a component with new */
	    initComponent = new ToastConstructor({
	    	el: document.createElement('div')});// If div is not mounted, you can initComponent.$mount();
	    if(typeofoption ! = ='object') {
			initComponent.msg = option;
		}else {
			merge(initComponent.$data, option)
		}
		document.querySelector(option.container || 'body').appendChild(initComponent.$el);
	    
	    
	}
	Vue.nextTick((a)= > {
		initComponent.show = true
		timer = setTimeout((a)= > {
			initComponent.close()
		},2000)})return new Promise((resolve,reject) = > {
		resolve()
	})
}

ToastConstructor.prototype.close = function() {
	this.show = false;
	this.$el.addEventListener('transitionend'.this.destroyeInitComponent.bind(this))}/* Destroy the component */
ToastConstructor.prototype.destroyeInitComponent  = function() {
	initComponent = null;
	this.$destroy(true)
	this.$el.removeEventListener('transitionend'.this.destroyeInitComponent)
  	this.$el.parentNode.removeChild(this.$el)
}
export default ToastCopy the code


The new common – components. Js

----------------------------------common-components.js
/**
 * 
 * @authors Your Name ([email protected])
 * @date    2018-08-30 14:19:20
 * @version $Id$
 */

import Toast from '@/components/Toast'


const install = Vue => {
	//Vue.prototype.$toast = Toast
	Vue.$toast = Toast;
	Vue.prototype.$toast = Vue.$toast
}

export default installCopy the code

It is referenced in main.js

/* Global components */ import commonComponents from'./common-components.js'
Vue.use(commonComponents) Copy the code

Call the toast

                               Vue.prototype.$toast("Please log in first.")
				.then(() => {
					console.log('callback')})Copy the code

Log in to intercept

Create a new permission.js under the router

/**
 * 
 * @authors Your Name ([email protected])
 * @date    2018-08-29 15:05:17
 * @version $Id$
 */
import store from '.. /store'
import Vue from 'vue'
import { router } from './index'

router.beforeEach((to, from, next) => {
	if(to.meta.login) {
		if(store.state.user.isLogin == "1") 
			next()
		else {
			Vue.prototype.$toast("Please log in first.")
				.then(() => {
					console.log('callback')})return}}else if(to.meta.page) {
		next()
	}
	
})

router.afterEach((to, from) => {
	document.title = to.name
})

export default routerCopy the code

Axios encapsulation

/** * * @authors Your Name ([email protected]) * @date 2018-08-28 10:04:37 * @version $Id$ */

import axios from 'axios';
import qs from 'qs'

axios.defaults.withCredentials = true 
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';

// When the HTTP request interceptor is sent
axios.interceptors.request.use(config= > {
    return config
}, err => {
    return Promise.reject(err)
})

// HTTP response interceptor corresponding
axios.interceptors.response.use(response= > {
    console.log(response.data.result)
    return response
}, err => Promise.resolve(err.response))


const get =  function (url, params) {
    return new Promise((resolve, reject) = > {
    	axios({
    		method: "GET",
    		url,
    		params
    	}).then(function(res){ resolve(res); })})}const post =  function (url, params) {
    return new Promise((resolve, reject) = > {
    	axios({
    		method: "POST",
    		url,
    		params
    	}).then(function(res){ resolve(res); })})}export default {
	get,
	post
}

Copy the code