vuex在重构Cnode项目中的运用

写在文章前:

在初版初步实现cnode的基本功能后,原本是用本地存储的存储用户登陆成功返回的用户的基本信息,用于后面的回复功能,查看信息等操做须要的用户基本信息的数据。可是总的来讲感受本地储存的方案不太理想(我的想法),因此想引入vuex来存储用户信息,还有一些跨组件的状态和数据。html

什么是vuex,干嘛用的?

简单的介绍一下我理解的vuex是什么东西,由于咱们知道vue的组件子父之间是能够同过props实现数据的单向和双向传递,可是咱们可能常常遇到的业务场景是一个组件的状态发生改变须要在另外一个与他不相关的组件进行响应,这个时候若是咱们没作全局变量就没办法搞了,因此说vuex总的来讲就是一个全局的状态管理。(我是这么认为的)vue

建议阅读文档

关于vuex的基本用法请参见中文APInode

在项目中使用vuex

如今直接上手实现一个功能把登陆成功的用户信息保存在vuex中,这个功能是基于你看过文档并初步了解了vuex,知道state,mutation這些基本概念,因为API的文档中的例子只是个简单的demo,因此我写了这个功能更贴切一个项目中实际的场景。(这里就不介绍那些基础概念了,由于API确定介绍得比我详细)git

1.初始化

创建一个文件 store.js代码以下。state定义须要状态的参数变量,mutation(状态变动)用于改变state的状态,注意vuex中是不能直接改变state中的状态的,必定要借助于mutation的事件分发。mutation的方法能够第一个参数必定是state,后面也能够选择带参,两种本例子下面都有定义。github

"use strict";
import Vue from 'vue'
import Vuex from 'vuex';
Vue.use(Vuex);
const state = {
     // 页面打开默认设置登陆状态为否
     isLogin : false,
     // 保存登陆信息
     userInfo : {
          'loginname' : '',
          'avatar' : '',
          'id' : '',
          'accesstoken' : ''
     }
}
const mutations = {
     // 设置登陆
     ISLOGIN (state) {
          state.isLogin = true;
     },
     // 设置登陆用户信息
     SETUSERINFO (state, name, avatar, id, accesstoken) {
          state.userInfo.loginname = name;
          console.log(state.userInfo.loginname);
          state.userInfo.avatar = avatar;
          state.userInfo.id = id;
          state.userInfo.accesstoken = accesstoken;
     }
}
export default new Vuex.Store({
     state,
     mutations
})

2.设置state状态

创建一个action.js代码以下,用于用户分发mutation的事件。可能有些人会疑惑为何要多写这个文件来分发mutation的事件,是应为咱们的mutation必须是同步执行,若是在mutation中进行回调,根本就没法肯定到底何时能执行那个回调函数。而在action中进行事件的分发就能够进行异步操做。vuex

/**
  *修改用户登陆状态为已经登陆
**/
export const isLogin = ({dispatch}) => {
     dispatch('ISLOGIN');
}
/**
  *设置用户的登陆信息
  *参数 name用户名 avatar用户头像 id用户id accesstoken用户登陆标识
**/
export const setUserInfo = ({dispatch}, name, avatar, id, accesstoken) => {
     dispatch('SETUSERINFO', name, avatar, id, accesstoken);
}

3.获取state状态

创建一个getters.js代码以下,用户用户获取state中的状态。api

//获取用户的登陆状态
export const getLoginState = (state) => {
     return state.isLogin;
}
//获取登陆用户的信息
export const getUserInfo = (state) => {
     return state.userInfo;
}

4.在组件中调用vuex

这里注意一点在子父组件中调用vuex区别的一点是父组件必定要定义store:store,子组件随意。浏览器

import store from '../vuex/store';
import nvHeader from '../components/header.vue';
import {isLogin, setUserInfo} from '../vuex/actions';
export default {
          data : function(){
               return {
                    strToken : ''
               }
          },
          methods : {
               login : function() {
                    let rqdata = {
                         'accesstoken' : this.strToken
                    }

                    $.post('https://cnodejs.org/api/v1/accesstoken', rqdata, (data) => {
                         if(data){
                              // 登入成功改变isLogin的状态为true
                              this.userLogin();
                              console.log(this.userLoginState);
                              this.setUserInfo(data.loginname, data.avatar_url, data.id, this.strToken)
                              window.history.back();
                         }else{
                              // 失败
                         }
                    })
               }
          },
          components : {
               'nv-header' : nvHeader
          },
          store : store,
          vuex : {
               actions : {
                    userLogin : isLogin,
                    setUserInfo : setUserInfo
               }
          }
     }

咱们在login.vue这个组件中调用了子组件header.vue这个组件,在header.vue组件中又调用了menu.vue这个组件,而在menu这个组件中有一块用户信息是咱们登陆了才会去显示当前登陆用户的基本信息,这就要从store中去获取状态啦,而咱们以前登陆成功应景对store的状态进行了更新,menu.vue中应该自动响应,把用户信息展现出来异步

<template>
     <div class="meun" :class="{'showMeun':showm}">
          <div class="user_info" v-if="userLoginState">
               <div class="avatar">
                    <img :src="user_avatar" alt="">
               </div>
               <div class="name">
                    <p v-text="user_name"></p>
               </div>
          </div>
          <ul>
               <li v-link="{name:'home'}">首页</li>
               <li v-link="{name : 'search'}">搜索</li>
               <li v-link="{name : 'login'}" v-if="!userLoginState">登陆</li>
               <li v-if="userLoginState">未读消息</li>
               <li v-if="userLoginState">设置</li>
               <li v-link="{name : 'about'}">关于</li>
          </ul>
     </div>
</template>
<script>
     import store from '../vuex/store';
     import {getLoginState, getUserInfo} from '../vuex/getters';
     export default {
          props : ['showm'],
          data : function() {
               return {
                    user_name : this.getUserInfo.loginname || '',
                    user_avatar : this.getUserInfo.avatar || ''
               }
          },
          vuex : {
               getters : {
                    userLoginState : getLoginState,
                    getUserInfo :  getUserInfo
               }
          }
     }
</script>

结束语:

ok,这个登陆显示用户信息的基本功能就实现了。固然还有许多的地方能够用到vuex,好比说在本项目的弹窗组件也用到了vuex,来根据具体情境显示对应的提示文本。本人重构的Cnode项目也在逐渐的完善,若是以为本篇文章对你有收获能够star支持一下,谢谢!函数

github源码

线上demo访问地址

tip:线上demo在浏览器切换为移动端模式下访问效果更佳

相关文章
相关标签/搜索