Vuex的多種寫(xiě)法

  1. 官方推薦:

    src/vuex/getters.js:

    const getters = {
      //這里還可以有第二個(gè)參數(shù)getters览芳,用來(lái)獲取getters里面的其他getters
      friend: (state) => {
        return state.data.friends.filter(x => x._id === state.activeId)[0];
      },
      ......
    };
    
    export default getters;
    

    src/vuex/mutations.js:

    const mutations = {
      getData: (state, data) => {
        state.data = data;
        ......
      },
    };
    
    export default mutations;
    

    src/vuex/actions.js

    import axios from 'axios';
    const actions = {
      // 這里結(jié)構(gòu)里面不止有commit,也可以有dispatch等鸿竖,這個(gè)也是最常用的沧竟;當(dāng)然也有state、getters
      getAllData: async ({commit}) => {
        let self = {};
        let friends = [];
        await axios.get('../../static/mockdata.json').then(response => {
          self = response.data.self;
          friends = response.data.friend;
          console.log(response.data);
        }, response => {
          console.log("error");
        });
        commit('getData', {
          self, friends
        })
      },
    };
    
    export default actions;
    

    src/vuex/store.js:

    import Vue from 'vue';
    import Vuex from 'vuex';
    import mutations from "./mutations";
    import getters from "./getters";
    import actions from "./actions";
    
    Vue.use(Vuex);
    
    let state = {
        data: { 
             self: {}, 
             friends: [] 
        },
        ......
    };
    
    export default new Vuex.Store({
      state,
      mutations,
      actions,
      getters
    })
    
  2. Vuex多模塊寫(xiě)法:

    src/store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    import { $fetch } from '../plugins/fetch'
    import router from '../router'
    
    import maps from './maps'
    import posts from './posts'
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
      strict: process.env.NODE_ENV !== 'production',
    
      state () {
        return {
          user: null,
        }
      },
    
      getters: {
        user: state => state.user,
    
        userPicture: (state, getters) => {
          const user = getters.user
          if (user) {
            const photos = user.profile.photos
            if (photos.length !== 0) {
              return photos[0].value
            }
          }
        },
      },
    
      mutations: {
        user: (state, user) => {
          state.user = user
        },
      },
    
      actions: {
        async init ({ dispatch }) {
          await dispatch('login')
        },
    
        async login ({ commit, dispatch }) {
          try {
            const user = await $fetch('user')
            console.log('user', user)
            commit('user', user)
    
            if (user) {
              // Redirect to the wanted route or home
              router.replace(router.currentRoute.params.wantedRoute || { name: 'home' })
    
              dispatch('logged-in')
            }
          } catch (e) {
            console.warn(e)
          }
        },
    
        logout ({ commit, dispatch }) {
          commit('user', null)
    
          $fetch('logout')
    
          // If the route is private
          // We go to the login screen
          if (router.currentRoute.matched.some(r => r.meta.private)) {
            router.replace({ name: 'login', params: {
              wantedRoute: router.currentRoute.fullPath,
            }})
          }
        },
      },
    
      // 引入其他的store
      modules: {
        posts,
      },
    })
    
    export default store
    

    src/store/posts.js

    import { $fetch } from '../plugins/fetch'
    
    let fetchPostsUid = 0
    
    export default {
      namespaced: true,
    
      state () {
        return {
          // New post being created
          draft: null,
          // Bounds of the last fetching
          // To prevent refetching
          mapBounds: null,
          // Posts fetched in those map bounds
          posts: [],
          // ID of the selected post
          selectedPostId: null,
          // Fetched details for the selected post
          selectedPostDetails: null,
        }
      },
    
      getters: {
        draft: state => state.draft,
        posts: state => state.posts,
        // The id field on posts is '_id' (MongoDB style)
        selectedPost: state => state.posts.find(p => p._id === state.selectedPostId),
        selectedPostDetails: state => state.selectedPostDetails,
        // The draft has more priority than the selected post
        currentPost: (state, getters) => state.draft || getters.selectedPost,
      },
    
      mutations: {
        addPost (state, value) {
          state.posts.push(value)
        },
    
        addComment (state, { post, comment }) {
          post.comments.push(comment)
        },
    
        draft (state, value) {
          state.draft = value
        },
    
        likePost (state, { post, userId }) {
          const index = post.likes.indexOf(userId)
          if (index !== -1) {
            post.likes.splice(index, 1)
          } else {
            post.likes.push(userId)
          }
        },
    
        posts (state, { posts, mapBounds }) {
          state.posts = posts
          state.mapBounds = mapBounds
        },
    
        selectedPostId (state, value) {
          state.selectedPostId = value
        },
    
        selectedPostDetails (state, value) {
          state.selectedPostDetails = value
        },
    
        updateDraft (state, value) {
          Object.assign(state.draft, value)
        },
      },
    
      actions: {
        clearDraft ({ commit }) {
          commit('draft', null)
        },
    
        createDraft ({ commit }) {
          // Default values
          commit('draft', {
            title: '',
            content: '',
            position: null,
            placeId: null,
          })
        },
    
        async createPost ({ commit, dispatch }, draft) {
          const data = {
            ...draft,
            // We need to get the object form
            position: draft.position.toJSON(),
          }
    
          // Request
          const result = await $fetch('posts/new', {
            method: 'POST',
            body: JSON.stringify(data),
          })
          dispatch('clearDraft')
    
          // Update the posts list
          commit('addPost', result)
          dispatch('selectPost', result._id)
        },
    
        async fetchPosts ({ commit, state }, { mapBounds, force }) {
          let oldBounds = state.mapBounds
          if (force || !oldBounds || !oldBounds.equals(mapBounds)) {
            const requestId = ++fetchPostsUid
    
            // Request
            const ne = mapBounds.getNorthEast()
            const sw = mapBounds.getSouthWest()
            const query = `posts?ne=${
              encodeURIComponent(ne.toUrlValue())
            }&sw=${
              encodeURIComponent(sw.toUrlValue())
            }`
            const posts = await $fetch(query)
    
            // We abort if we started another query
            if (requestId === fetchPostsUid) {
              commit('posts', {
                posts,
                mapBounds,
              })
            }
          }
        },
    
        async likePost ({ commit, rootGetters }, post) {
          const userId = rootGetters.user._id
          commit('likePost', {
            post,
            userId,
          })
          await $fetch(`posts/${post._id}/like`, {
            method: 'POST',
          })
        },
    
        'logged-in': {
          handler ({ dispatch, state }) {
            if (state.mapBounds) {
              dispatch('fetchPosts', {
                mapBounds: state.mapBounds,
                force: true,
              })
            }
            if (state.selectedPostId) {
              dispatch('selectPost', state.selectedPostId)
            }
          },
          root: true,
        },
    
        // 這樣寫(xiě)的話dispatch('logout')不僅可以觸發(fā)index.js中的logout缚忧,也可以觸發(fā)這里的logout悟泵,也就是狀       // 態(tài)提升
        logout: {
          handler ({ commit }) {
            commit('posts', {
              posts: [],
              mapBounds: null,
            })
          },
          root: true,
        },
    
        async selectPost ({ commit, getters }, id) {
          commit('selectedPostDetails', null)
          commit('selectedPostId', id)
          const details = await $fetch(`posts/${id}`)
          commit('selectedPostDetails', details)
        },
    
        async sendComment({ commit, rootGetters }, { post, comment }) {
          const user = rootGetters.user
          commit('addComment', {
            post,
            comment: {
              ...comment,
              date: new Date(),
              user_id: user._id,
              author: user,
            },
          })
    
          await $fetch(`posts/${post._id}/comment`, {
            method: 'POST',
            body: JSON.stringify(comment),
          })
        },
    
        setDraftLocation ({ dispatch, getters }, { position, placeId }) {
          if (!getters.draft) {
            dispatch('createDraft')
          }
          dispatch('updateDraft', {
            position,
            placeId,
          })
        },
    
        unselectPost ({ commit }) {
          commit('selectedPostId', null)
        },
    
        updateDraft ({ dispatch, commit, getters }, draft) {
          commit('updateDraft', draft)
        },
      },
    }
    

    在 .vue 中使用(推薦):

    <script>
    import { createNamespacedHelpers } from 'vuex'
    
    // Vuex mappers
    // posts module
    const {
      mapGetters: postsGetters,
      mapActions: postsActions,
    } = createNamespacedHelpers('posts')
    
    export default {
      computed: {
        ...postsGetters([
          'draft',
          'posts',
          'currentPost',
        ]),
    
        mapOptions () {
          return {
            fullscreenControl: false,
          }
        },
      },
    
      methods: {
        ...postsActions([
          'selectPost',
          'setDraftLocation',
        ]),
    
        onIdle () {
          this.setBounds(this.$refs.map.getBounds())
        },
    
        onMapClick (event) {
          this.setDraftLocation({
            position: event.latLng,
            placeId: event.placeId,
          })
        },
      },
    }
    </script>
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市闪水,隨后出現(xiàn)的幾起案子糕非,更是在濱河造成了極大的恐慌,老刑警劉巖球榆,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朽肥,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡持钉,警方通過(guò)查閱死者的電腦和手機(jī)衡招,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)每强,“玉大人始腾,你說(shuō)我怎么就攤上這事】罩矗” “怎么了窘茁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)脆烟。 經(jīng)常有香客問(wèn)我山林,道長(zhǎng),這世上最難降的妖魔是什么邢羔? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任驼抹,我火速辦了婚禮,結(jié)果婚禮上拜鹤,老公的妹妹穿的比我還像新娘框冀。我一直安慰自己,他們只是感情好敏簿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開(kāi)白布明也。 她就那樣靜靜地躺著宣虾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪温数。 梳的紋絲不亂的頭發(fā)上绣硝,一...
    開(kāi)封第一講書(shū)人閱讀 51,215評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音撑刺,去河邊找鬼鹉胖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛够傍,可吹牛的內(nèi)容都是我干的甫菠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼冕屯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼寂诱!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起安聘,我...
    開(kāi)封第一講書(shū)人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤刹衫,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后搞挣,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體带迟,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年囱桨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了仓犬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡舍肠,死狀恐怖搀继,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情翠语,我是刑警寧澤叽躯,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站肌括,受9級(jí)特大地震影響点骑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜谍夭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一黑滴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧紧索,春花似錦袁辈、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)尾膊。三九已至,卻和暖如春荞彼,著一層夾襖步出監(jiān)牢的瞬間冈敛,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工卿泽, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人滋觉。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓签夭,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親椎侠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子第租,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354