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在瀏覽器切換爲移動端模式下訪問效果更佳

相關文章
相關標籤/搜索