[VUE]VUEX筆記

Vue綁定方式

v-model

v-model是專門用於input,select,textare等表單控件的綁定。它能夠渲染變量在dom上,同時控件的value改變時,對應變量也會作出改變。(在表單控件或者組件上建立雙向綁定)。vue

<input type="text" v-model="name">
  <textarea v-model="message" placeholder="add multiple lines"></textarea>
  <input type="checkbox" id="checkbox" v-model="checked">
  <input type="radio" id="one" value="One" v-model="picked">
  <select v-model="selected">
        <option disabled value>請選擇</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
  </select>

v-bind

動態地綁定一個或多個特性,或一個組件 prop 到表達式。就是把屬性變量化,class,style等能夠根據變量來改變。同時也是父組件往子組件傳值的方法。vuex

<img v-bind:src="imageSrc" :title="imageNum">

v-bind:能夠簡寫成:。例子中圖片的地址和title都是來自於vue實例裏的變量。dom

Vuex

vuex 是一個專門爲vue.js應用程序開發的狀態管理模式。
這個狀態咱們能夠理解爲在data中的屬性,須要共享給其餘組件使用的部分。
也就是說,是咱們須要共享的data,使用vuex進行統一集中式的管理。
vuex週期的大概流程是,在vue實例中調用store下的state後,想要改變state,要先經過store.commit(有異步操做要先dispath)來改變state,從而在vue頁面中渲染。
avatar異步

state

store裏的數據源庫(一個全局的data),可在全局調用$store.state訪問。
每當 state 變化的時候, 都會從新求取計算屬性,而且觸發更新相關聯的 DOM。
在store裏函數

state:{
    name:"張三"
}

vue實例this

<div>用戶名: {{$store.state.name}}</div>

引用vuex後,在項目任意vue實例裏均可以訪問到state的內容。spa

Getter

從 store 中的 state 中派生出一些狀態。(能夠認爲是對數據獲取以前的再次編譯, store 的計算屬性)。他並不會改變state自己。只有當它的依賴值發生了改變纔會被從新計算。(相似於vue實例的computed)
Getter 接受 state 做爲其第一個參數,能夠訪問store裏的state雙向綁定

getters: {
        doneTodos: state => {
            return state.todos.filter(todo => todo.done)
        }
     }

第二個參數是getters,能夠訪問到上下文的getters。localstorage

getters: {
        doneTodosCount: (state, getters) => {
            return getters.doneTodos.length
        }
    }

假如須要傳參,能夠經過方法訪問code

getters: {
         getTodoById: (state) => (id) => {
            return state.todos.find(todo => todo.id === id)
        }
    }

在vue實例中訪問getters

computed:{
    doneTodosCount () {
        return this.$store.getters.doneTodosCount
  }
}

mutation

mutation是更改 Vuex 的 store 中的狀態的惟一方法。須要用store.commit()觸發。
mutations:第一個參數是state,第二個參數是載荷(Payload)。即傳參,在大多數狀況下,載荷應該是一個對象。
很是重要的一點,mutation內必須是同步函數。

mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}

執行時store.commit()第一個參數是mutations的名稱(字符串),第二個是載荷對象。

store.commit('increment', {
  amount: 10
});

Action

Action是專門處理store異步操做的。
Action 提交的是 mutation,而不是直接變動狀態。
Action 經過store.dispatch()觸發。
actions第一個參數是context(上下文),第二個參數是載荷。

actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('increment')
    }, 1000)
  }
}

vue實例裏執行action。

store.dispatch('incrementAsync', {
  amount: 10
})

Module

因爲使用單一狀態樹,應用的全部狀態會集中到一個比較大的對象。當應用變得很是複雜時,store 對象就有可能變得至關臃腫。
module 能夠把store 分割成模塊(module)。每一個模塊擁有本身的 state、mutation、action、getter。
store.js

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

在vue實例裏訪問時

$store.state.a // -> moduleA 的狀態
$store.state.b // -> moduleB 的狀態

這種寫法下state會區分模塊,但mutation和action的調用時,寫法是同樣的。

$store.commit(「set」);
$store.dispath(「set」);

命名空間

假如不一樣的模塊裏有出現相同名稱的mutations,就會出現問題。爲了不,可使用命名空間。
在每一個模塊下添加namespaced: true。便可實現命名空間。

const moduleA = {
  namespaced: true,
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  namespaced: true,
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

在vue實例中調用時改成

$store.commit(「a/set」);
$store.dispath(「b/set」);

vuex和data

vuex是全局存在的,對於一些只在一個vue頁面(組件)中用到的信息,能夠只存在對於的頁面(組件)的data中。store中通常存放一些在多處會讀取或者改寫的信息,這樣能夠避免多層的父子傳值。通常常見的存放在store裏的有用戶信息,標籤信息等。這樣能夠在不一樣的地方操做標籤。
例子:在一個項目中有一個右鍵彈出菜單的組件。組件須要傳參,來決定傳入內容。
store裏

{
    state:{
        rightMenuData: [{
            name: '刷新此窗口',
            key: 'refresh'
        }, 
        {
            name: '關閉此窗口',
            key: 'close'
        }, {
            name: '關閉所有窗口',
            key: 'closeAll'
         }]
    }
}

vue頁面中

<right-menu
    :menuData="rightMenuData"
    :eventHandler="rightClickHandler"
    v-on:handleSelect="handleRightSelect"
></right-menu>

列子中的菜單內容存在store裏,在一個頁面裏調用了對應數據。但是實際上項目裏只要一個頁面須要用到這個數據。這種狀況能夠把數據只放到頁面data裏,避免store過於臃腫。

另外一個例子:
vue頁面中

mounted() {
    let user = global.myLocalStorage.getItem("user");
    if (user) {
      user = JSON.parse(user);
      this.sysUserName = user.name || "";
      this.sysUserAvatar = user.avatar || "agree.bee.png";
    }
    //...省略部分

這裏頁面中用到一個用戶信息,因爲本地保存的關係,用戶數據被存到localstorage裏。而後項目在各處拿用戶信息的時候會直接從localstorage裏拿。這種狀況,能夠考慮,在頁面打開時,只從localstorage拿一次數據,存在store裏。在項目運行的過程當中就能夠直接在store裏訪問用戶信息。

多個store運用

在一些大型應用中,有可能存在多個store的狀況,來保持自身的store不受影響。
例子:A實例下面有多個vue子頁面b,c,d。它們都須要有本身的store。則在內部Vue實例中new一個vuex.store,並存起來(不必定要存$store,能夠是其餘變量)。

beforeCreate(){
        this.$store = new Vuex.store({
            stata,
            mutations,
            actions
        })
    }

此時vue實例b,c,d中

this.$store

返回的應該是本身的store。
若是想要訪問A頁面原來的store,能夠用$root,訪問根部vue實例,因爲他的this.$store並無被重寫,因此指向的仍是原來全局的store。

this.$root.$store
相關文章
相關標籤/搜索