成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Vue_Vuex

animabear / 841人閱讀

摘要:定義調(diào)用更改的中的狀態(tài)的唯一方法是提交中的非常類(lèi)似于事件每個(gè)都有一個(gè)字符串的事件類(lèi)型和一個(gè)回調(diào)函數(shù),參數(shù)。注意點(diǎn)必須是同步函數(shù)原因當(dāng)觸發(fā)的時(shí)候,回調(diào)函數(shù)還沒(méi)有被調(diào)用。實(shí)質(zhì)上任何在回調(diào)函數(shù)中進(jìn)行的狀態(tài)的改變都是不可追蹤的。

Vuex

集中式狀態(tài)管理

使用時(shí)機(jī):
每一個(gè)組件都擁有當(dāng)前應(yīng)用狀態(tài)的一部分,整個(gè)應(yīng)用的狀態(tài)是分散在各個(gè)角落的。然而經(jīng)常會(huì)需要把把狀態(tài)的一部分共享給多個(gè)組件。

Vuex:一個(gè)專(zhuān)門(mén)為Vue.js 應(yīng)用設(shè)計(jì)的狀態(tài)管理架構(gòu).

狀態(tài)管理:統(tǒng)一管理和維護(hù)各個(gè)vue組件的可變化狀態(tài)(可以理解成vue組件里的某些data數(shù)據(jù),全局變量)

出現(xiàn)背景:

追蹤自定義事件NaN,這個(gè)事件由那個(gè)組件觸發(fā)的,誰(shuí)在監(jiān)聽(tīng)它。

業(yè)務(wù)邏輯遍布各個(gè)組件,導(dǎo)致各種意想不到的問(wèn)題。

由于要顯式的分發(fā)和監(jiān)聽(tīng),父組件和子組件強(qiáng)耦合

Vuex 核心概念:

狀態(tài)樹(shù):包含所有應(yīng)用層級(jí)狀態(tài)。意味著,每個(gè)應(yīng)用將僅僅包含一個(gè)store實(shí)例。單狀態(tài)樹(shù)能夠直接定位任意特定的狀態(tài)片段。

Getters:在Vue組件內(nèi)部獲取stroe中狀態(tài)/數(shù)據(jù)的函數(shù)

Mutations:通過(guò)事件回調(diào)函數(shù)來(lái)修改store中的狀態(tài)的變化.

Actions:在組件內(nèi)部使用函數(shù),分發(fā)mutations事件的函數(shù).

為什么需要有action

每一個(gè)web應(yīng)用都至少對(duì)應(yīng)一個(gè)數(shù)據(jù)結(jié)構(gòu),而導(dǎo)致這個(gè)數(shù)據(jù)結(jié)構(gòu)狀態(tài)更新的來(lái)源很豐富;光是用戶對(duì)view的操作(dom事件)就有幾十種,此外還有ajax獲取數(shù)據(jù)、路由/hash狀態(tài)變化的記錄和跟蹤。

來(lái)源豐富不是最可怕的,更可怕的是每個(gè)來(lái)源提供的數(shù)據(jù)結(jié)構(gòu)并不統(tǒng)一。DOM事件還好,前端可以自主控制與設(shè)計(jì);ajax獲取的數(shù)據(jù),其結(jié)構(gòu)常常是服務(wù)端開(kāi)發(fā)人員說(shuō)了算,面對(duì)業(yè)務(wù)場(chǎng)景跟前端并不相同,往往會(huì)為了自己的便利,給出在前端看來(lái)很隨意的數(shù)據(jù)結(jié)構(gòu)。

web應(yīng)對(duì)中所有的數(shù)據(jù)與狀態(tài)的變化,幾乎都來(lái)自[事件],DOM事件,AJAX成功或失敗事件,路由change事件,setTimeout定時(shí)器事件,以及自定義事件。任意時(shí)間都可能產(chǎn)生需要合并全局?jǐn)?shù)據(jù)對(duì)象里的新數(shù)據(jù)或者線索。

是event響應(yīng)函數(shù)里主動(dòng)調(diào)用了action函數(shù),并且傳入它需要的數(shù)據(jù)。

action 作用:

action 是專(zhuān)門(mén)用來(lái)被component調(diào)用的函數(shù)

action函數(shù)能夠通過(guò)分發(fā)相應(yīng)的mutation函數(shù), 來(lái)觸發(fā)對(duì)stroe的更新

action 可以先從HTTP后端 或 store 中讀取其它數(shù)據(jù)之后再分發(fā)更新事件

Vuex把狀態(tài)分為:

組件本地狀態(tài)

僅在一個(gè)組件內(nèi)使用的狀態(tài)(data字段)應(yīng)用層級(jí)狀態(tài)(應(yīng)用級(jí)的狀態(tài)不屬于任何特定的組件,但每一個(gè)組件仍然可以監(jiān)視其變化從而響應(yīng)式的更新DOM)
組件內(nèi)部使用的狀態(tài),通過(guò)配置選項(xiàng)傳入Vue組件內(nèi)部的意思。

應(yīng)用級(jí)別狀態(tài)

多個(gè)組件共用的狀態(tài)
同時(shí)被多個(gè)組件共享的狀態(tài)層級(jí)

簡(jiǎn)單使用

Vuex 應(yīng)用的核心是store(倉(cāng)庫(kù))理解成項(xiàng)目中使用的數(shù)據(jù)的集合。 包含著大部分的狀態(tài)(即state)

Vuex和單純的全局對(duì)象:

Vuex的狀態(tài)存儲(chǔ)是響應(yīng)式的。當(dāng)Vue組件從store中讀取狀態(tài)的時(shí)候,若store中的狀態(tài)發(fā)生變化。

不能截至改變store中的狀態(tài)。改變store中的狀態(tài)的唯一途徑就是顯示地分發(fā) 狀態(tài)變更事件

作用:方便的跟蹤每一個(gè)狀態(tài)的變化。

vuex 把應(yīng)用的數(shù)據(jù)和修改的數(shù)據(jù)的方法,放在了一個(gè) sotre 對(duì)象里面統(tǒng)一管理,對(duì)數(shù)據(jù)的獲取和操作則分別通過(guò) vm新增的配置屬性 vuexgettersactions 來(lái)進(jìn)行

整個(gè)APP的數(shù)據(jù)就是存放在state對(duì)象里,隨取隨用.

定義一個(gè)mutations對(duì)象??梢园?b>mutations理解為“用于改變state狀態(tài)的一系列方法”

在vuex的概念里,state僅能通過(guò)mutations修改。
好處:能夠更直觀清晰的集中管理應(yīng)用的狀態(tài)。

數(shù)據(jù)流動(dòng)是單向

組件可以調(diào)用actions

Actions是用來(lái)分發(fā) mutations

只有mutations可以修改狀態(tài)

store是反應(yīng)式(狀態(tài)的變化會(huì)在組件內(nèi)部得到反映)

sotre只需要在最頂層的組件聲明一次

在入口文件加入:

var store = new Vuex.Store({
    state: {
        a: false,
        money: 0    
    },
    mutations: {
        increment( state ) {
            store.state.a;
        }
    }
});

組件中使用:

computed: {
    a: function() {
        return store.state.a;
    }
}

使用Vuex遵守規(guī)則:

應(yīng)用層級(jí)的狀態(tài)應(yīng)該幾種到單個(gè)sotre對(duì)象中。

提交mutation是更改狀態(tài)的唯一方法,并且這個(gè)過(guò)程是同步的。

異步邏輯都應(yīng)該封裝到action里面。

State

單一狀態(tài)樹(shù)

Vuex 使用 單一狀態(tài)樹(shù)。 使用一個(gè)對(duì)象包含全部的應(yīng)用層級(jí)狀態(tài)(數(shù)據(jù))。把它作為一個(gè)唯一數(shù)據(jù)源提供方存在(全局變量)。
每個(gè)應(yīng)用程序僅僅包含一個(gè)store實(shí)例。單狀態(tài)數(shù)能夠直接定位任意特定的狀態(tài)片段,在調(diào)試過(guò)程中能夠輕易的獲取整個(gè)當(dāng)前應(yīng)用狀態(tài)。(單狀態(tài)樹(shù)和模塊化并不沖突)

Vuex 中數(shù)據(jù)都是單向的,Vue組件只能從 store獲取。

如何在Vue組件中獲得Vuex狀態(tài)

由于 Vuex 的狀態(tài)存儲(chǔ)是響應(yīng)式的,從 store 實(shí)例中 讀取狀態(tài)在計(jì)算屬性computed 中返回某個(gè)狀態(tài)。

    new Vue({
        el: ".app",
        computed: {
            count: function () {
                return stroe.state.count;
            }
        }
    });

store.state特性:

每當(dāng)store.state.count變化的時(shí)候,都會(huì)重新求取計(jì)算屬性,并且觸發(fā)更新相關(guān)的DOM。

導(dǎo)致組件過(guò)度依賴(lài)全局狀態(tài)單例。

每個(gè)模塊化的組件中,需要頻繁導(dǎo)入,并且在測(cè)試組件時(shí)需要模擬狀態(tài)。

組件仍然保有局部狀態(tài)

使用Vuex并不意味著需要將所有的狀態(tài)放入Vuex。
優(yōu)點(diǎn):把所有狀態(tài)放入Vuex會(huì)是的狀態(tài)變化更顯式和易調(diào)試。
缺點(diǎn):代碼變得冗長(zhǎng)和不直觀。

如果有些狀態(tài)嚴(yán)格屬于單個(gè)組件,最好還是作為組件的局部狀態(tài)。

Getters

需要對(duì)數(shù)據(jù)進(jìn)行第二次加工處理,全局函數(shù)處理,可以在 store中定義getters(可以認(rèn)為store的計(jì)算屬性)。

定義

const store = new Vue({
    state: {
        list: [{id: 1, text: "a"}, {id: 2, text: "b"}]
    },
    getters: {
        done: state => {
            return state.todos.filter(todo => todo.done);
        }    
    }
});

調(diào)用

store.getters.lenCount
Mutations

更改Vuex的store中的狀態(tài)的唯一方法是提交 mutation.
Vuex中的mutations非常類(lèi)似于事件:每個(gè)mutations都有一個(gè)字符串的 事件類(lèi)型(type) 和 一個(gè)回調(diào)函數(shù)(handler),參數(shù):state。

定義

const store = new Vue.store({
    state: {
        a: 0
    },
    mutations: {
        heade( state ) {
            state.a += 10;
        }
    }
});

調(diào)用

sotre.commit("heade");

傳入多個(gè)參數(shù)(提交載荷Payload) 多數(shù)情況下,另外的參數(shù),會(huì)是對(duì)象。

// 定義
mutations: {
    heade( state, n ) {
        state.a += n;
    }
}

// 調(diào)用
store.commit("heade", 100);

Mutations 需遵守 Vue 的響應(yīng)規(guī)則

Vuex中的store中的狀態(tài)是響應(yīng)式的,變更狀態(tài)時(shí),監(jiān)聽(tīng)狀態(tài)的Vue組件也會(huì)自動(dòng)更新。
注意:

最好提前在sotre中出初始化好所有所需屬性。

當(dāng)需要在對(duì)象上添加新屬性時(shí),應(yīng)該使用Vue.set(obj, "newProp", 123) 或者 以新對(duì)象替換老對(duì)象。

使用常量替代Mutation事件類(lèi)型

使用常量替代mutation事件類(lèi)型在各種 Flux 實(shí)現(xiàn)中常見(jiàn)模式.
結(jié)果:可以使linter之類(lèi)的工具發(fā)揮作用,同時(shí)把這些常量放在多帶帶的文件中可以讓代碼合作者對(duì)這個(gè)app包含的mutation清晰明了。

// mutation-types.js
export const FETCH_MOVIE_BY_ID = "FETCH_MOVIE_BY_ID";

// store.js
import Vuex form "vuex";
import {FETCH_MOVIE_BY_ID} from "./mutations-types.js";

const store = new Vuex.Store({
    state: {},
    mutations: {
        ["FETCH_MOVIE_BY_ID"]( state ) {
            // mutate state
        }
    }
});

mutation注意點(diǎn):
mutation必須是同步函數(shù)
原因:當(dāng)mutation觸發(fā)的時(shí)候,回調(diào)函數(shù)還沒(méi)有被調(diào)用。 實(shí)質(zhì)上任何在回調(diào)函數(shù)中進(jìn)行的狀態(tài)的改變都是不可追蹤的。

在組件中提交Mutations

定義:

increment: function( context ) {
    context.a += 10;
}

使用方式:

// 方式1
store.commit("increment"); // this.$store.commit("xxx")

// 方式2
methods: {
    mapMutations(["increment"]) // // 映射 this.increment() 為 this.$store.commit("increment")
}
Actions

Actions類(lèi)似于mutations,不同點(diǎn):

Actions 提交的是mutation,而不是直接變更狀態(tài)。

Actinos 可以包含任意異步操作。

 store = new Vuex.Store({
    state: {
        a: 0
    },
    mutations: {
        add() {
            state.a += 10;
        }
    },
    actions: {
        add( context ) {
            context.commit("add");
        }
    }
});

Action 函數(shù)參數(shù):store實(shí)例具有相同的方法和屬性的context對(duì)象。
可以調(diào)用context.commit(); 執(zhí)行一個(gè)mutation。 或者通過(guò)context.state 和 context.getters 來(lái)獲取 state和 getters。

分發(fā)Action

Action通過(guò)store.dispatch方法觸發(fā).

store.dispatch();

Action 能夠支持載荷方式和對(duì)象方式進(jìn)行分發(fā).

// 以載荷形式分發(fā)
store.dispatch("add", {
  amount: 10
})

// 以對(duì)象形式分發(fā)
store.dispatch({
  type: "add",
  amount: 10
})

在組件中分發(fā)Action

定義:

increment: function( context ) {
    context.a += 10;
}

使用方式:

// 方式1
store.dispatch("increment"); // this.$store.dispatch("xxx")

// 方式2
methods: {
    mapActions(["increment"]) // // 映射 this.increment() 為 this.$store.commit("increment")
}

組合Actions

Action 通常是異步,如何知道action 什么時(shí)候結(jié)束。如何組合多個(gè)action,以處理更加復(fù)雜的異步流程?

store.dispatch的返回的是被處罰的action函數(shù)的返回值,因?yàn)?,可以在action中返回Promise

actions: {
    actionA({commit}) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                commit("someMutation");
                resolve();
            }, 1000)
        })
    },
    actionB({dispatch}) {
        return dispatch("actionA").then(()=>{
            commit("someOhterMutation");
        })
    }
}

一個(gè)sotre.dispatch()在不同模塊中可以出發(fā)多個(gè)action函數(shù)。在當(dāng)前情況下,只有當(dāng)所有觸發(fā)函數(shù)完成后,返回的Promise才會(huì)執(zhí)行。

案例:

import * as types from "../types";
import {fetchMoviesByType, fetchSearchMovies, fetchMovieById} from "../api";

const state = {
  movies: [],
  movieList: {
    title: "",
    total: 0,
    subjects: [],
  },
  busy: false,
  movie: {},
};

const actions = {
  [types.FETCH_MOVIES](context,payload){
    fetchMoviesByType(payload.type, payload.start, payload.count)
        .then(data=>{
          data.type = payload.type;
          return context.commit([types.FETCH_MOVIES], data)
        });
  },

  [types.FETCH_MOVIE_LIST](context,payload){
    fetchMoviesByType(payload.type, payload.start)
        .then(data=>context.commit([types.FETCH_MOVIE_LIST], data));
  },

  [types.FETCH_MOVIE_BY_ID](context, id){
    fetchMovieById(id)
        .then(data => context.commit([types.FETCH_MOVIE_BY_ID], data));
  },

  [types.SET_INFINITE_BUSY](context, data){
    context.commit([types.SET_INFINITE_BUSY], data);
  },

  [types.CLEAN_MOVIE](context){
    context.commit(types.CLEAN_MOVIE);
  },

  [types.CLEAN_MOVIES](context){
    context.commit([types.CLEAN_MOVIES])
  },

  [types.CLEAN_MOVIE_LIST](context){
    context.commit([types.CLEAN_MOVIE_LIST])
  }
};

const mutations = {
  [types.FETCH_MOVIES](state, list){
    state.movies.push(list);
  },

  [types.FETCH_MOVIE_LIST](state, list){
    state.movieList.title = list.title;
    state.movieList.total = list.total;
    state.movieList.subjects = state.movieList.subjects.concat(list.subjects);
    if(state.movieList.subjects.length < state.movieList.total){
      state.busy = false;
    }
  },

  [types.FETCH_MOVIE_BY_ID](state, movie){
    state.movie = movie;
  },

  [types.SET_INFINITE_BUSY](state, data){
    state.busy = data;
  },

  [types.CLEAN_MOVIE](state){
    state.movie = {};
  },

  [types.CLEAN_MOVIES](state){
    state.movies = [];
  },

  [types.CLEAN_MOVIE_LIST](state){
    state.movieList = {};
  }
};


export default {
  state,
  mutations,
  actions
}
`api.js` 發(fā)送ajax  // 定義ajax事件

`modules/movie.js` 中寫(xiě) state,mutations,actions //  action 中執(zhí)行ajax定義事件, 回調(diào)函數(shù)中執(zhí)行mutations中定義的事件

`mutations` 定義事件, 第一個(gè)參數(shù)是`context`,當(dāng)前定義的store

`types.js` 定義常量替代mutation事件類(lèi)型
// src/components/header.vue
// 從vuex拿數(shù)據(jù),然后渲染到頁(yè)面上
// 如果需要修改可以調(diào)用setTitle
import { setTitle } from "../vuex/actions";

export default {
    vuex: {
        // 獲取vuex狀態(tài)數(shù)據(jù)
        getters: {
            title: state => state.title,
            info: ({index}) => index.info
        },
        // 狀態(tài)變更事件
        actions: {
            setTitle
        }
    }
}
Modules

場(chǎng)景:使用單一狀態(tài)數(shù),導(dǎo)致應(yīng)用的所有狀態(tài)集中到一個(gè)很大的對(duì)象。但是,當(dāng)應(yīng)用變得很大時(shí),sotre對(duì)象會(huì)變得難以維護(hù)。

Vuex允許將sotre分割到模塊(module),每個(gè)模塊擁有自己的state,mutation,action,getters.

import Vuex from "vuex"
import Vue from "vue"
import movie from "./modules/movie"

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    movie
  }
});
Store配置項(xiàng)
new Vuex.Store({
    state: {},  // 初始狀態(tài)
    
    actions: {}, // 執(zhí)行 mutation,異步.
    
    getters: {}, // 全局方法,二次加工數(shù)據(jù)
    
    mutations: {} // Store 與外界交互的入口
    
});

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/87920.html

相關(guān)文章

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<