本篇文章給大家?guī)砹藇ue中vuex的相關知識,Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式,希望對大家有幫助。
概念
????Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應用的所有組件的狀態(tài),并以相應的規(guī)則保證狀態(tài)以一種可預測的方式發(fā)生變化。
安裝
- HTML 中使用 script 標簽引入
<script src="vue.js"></script> <script src="vuex.js"></script>
- Vue項目中使用 npm 下載安裝(需要安裝 Node 環(huán)境)
// 下載 npm install vuex --save // 安裝 import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex)
Vuex 圖示
Vuex 和單純的全局對象有以下兩點不同:
-
Vuex 的狀態(tài)存儲是響應式的。當 Vue 組件從 store 中讀取狀態(tài)的時候,若 store 中的狀態(tài)發(fā)生變化,那么相應的組件也會相應地得到高效更新。
-
不能直接改變 store 中的狀態(tài)。改變 store 中的狀態(tài)的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態(tài)的變化,從而讓我們能夠實現(xiàn)一些工具幫助我們更好地了解我們的應用。
Store
????每一個 Vuex 應用的核心就是 store(倉庫)。“store” 基本上就是一個容器,它包含著你的應用中大部分的狀態(tài) (state)。
State
????驅動應用的數(shù)據(jù)源,用于保存所有組件的公共數(shù)據(jù).。
Getter
????可以將 getter 理解為 store 的計算屬性, getters 的返回值會根據(jù)它的依賴被緩存起來,且只有當它的依賴值發(fā)生了改變才會被重新計算。
Mutation
????mutations 對象中保存著更改數(shù)據(jù)的回調函數(shù),該函數(shù)名官方規(guī)定叫 type, 第一個參數(shù)是 state, 第二參數(shù)是payload, 也就是自定義的參數(shù)。mutation 必須是同步函數(shù)。mutations 對象里的方法需要使用 store.commit 調用
Action
????Action 提交的是 mutation 而不是直接變更狀態(tài)。action 可以包含任意異步操作。actions 對象里的方法需要使用 store.dispatch 調用。
????Action 函數(shù)接受一個與 store 實例具有相同方法和屬性的 context 對象,因此你可以調用 context.commit 提交一個 mutation,或者通過 context.state 和 context.getters 來獲取 state 和 getters。
Module
????由于使用單一狀態(tài)樹,應用的所有狀態(tài)會集中到一個比較大的對象。當應用變得非常復雜時,store 對象就有可能變得相當臃腫。為了解決以上問題,Vuex 允許我們將 store 分割成模塊(module)。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行同樣方式的分割。
HTML中 vuex 的使用
<body><p id="app"> <input type="button" value="+" @click="add"> {{this.$store.state.count}} <input type="button" value="-" @click="reduce"> {{this.$store.getters.synchro}} <input type="button" value="改變?yōu)?0" @click="changeNum"></p><script src="vue.js"></script><script src="vuex.js"></script><script> var store = new Vuex.Store({ state: { count: 0 }, getters: { synchro(state) { return state.count } }, mutations: { increment(state) { state.count++ }, inreduce(state) { state.count-- }, inchange(state, num) { state.count = num } }, actions: { change(context, num) { context.commit('inchange', num) } } }) new Vue({ el: '#app', store, methods: { add() { this.$store.commit('increment') }, reduce() { this.$store.commit('inreduce') }, changeNum() { this.$store.dispatch('change', 10) } } })</script></body>
Vue 項目中 vuex 的使用(兩種)
- 把 vuex 寫在 main.js 文件里
import Vue from 'vue'import App from './App'import router from './router'import Vuex from 'vuex'// 全局狀態(tài)管理Vue.use(Vuex)Vue.config.productionTip = falsevar store = new Vuex.Store({ state: { num: 0 }, mutations: { changeNum(state, num){ state.num += num } }})new Vue({ el: '#app', store, router, components: { App }, template: '<App/>'})
????在組件中調用
<template> <p> <input type="button" value="改變count的值" @click="change"> {{this.$store.state.count}} <p></template><script>export default { name: '', data () { return { } }, methods: { change() { this.$store.commit('changeNum', 10) } }}</script>
- 把 vuex 分離出來
????在 src 目錄下創(chuàng)建一個 vuex 目錄,新建 modules 目錄 和 index.js 文件 放到 vuex 目錄下
????在 main.js 文件里引入 vuex 目錄
import Vue from 'vue'import App from './App'import router from './router'import store from './vuex'Vue.config.productionTip = false/* eslint-disable no-new */new Vue({ el: '#app', store, router, components: { App }, template: '<App/>'})
????在 index.js 里寫上如下代碼
import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)let modules = {}const requireAllModules = require.context("./", true, /.js$/)requireAllModules.keys().forEach(key => { let module = requireAllModules(key).default if (module && module.name && module.namespaced) { modules[module.name] = module }})export default new Vuex.Store({ modules: modules, strict: process.env.NODE_ENV !== "production"})
????在 modules 目錄下 新建 city.js 文件,里面代碼如下
export default { name: "city", namespaced: true, state: { cityName: '', cityCode: '' }, getters: { getState(state) { return state }, getCityCode(state) { return state.cityCode } }, mutations: { changeCity(state, cityName) { state.cityName = cityName } }}
????在組件里設置值
<template> <p> <ul> <li v-for="item in city" @click="handChangeCity(item.name)"></li> </ul> </p></template><script>import { mapMutations } from 'vuex' // 引入vuexexport default { name: "city", data() { return { city: [ { id: 1, name: '北京' } { id: 2, name: '上海' } { id: 3, name: '廣州' } { id: 4, name: '深圳' } { id: 5, name: '廈門' } ] } }, methods: { // 修改 ...mapMutations({ changeCity: "city/changeCity" }), // 第一種寫法 handChangeCity(cityName) { this.changeCity(cityName) } // 第二種寫法 不需要使用 ...mapMutations handChangeCity(cityName) { this.$store.commit('city/changeCity', cityName); } }}</script>
????在另一個組件里使用
<template> <p> <p>{{getState.cityName}}</p> <p>{{getCityCode}}</p> </p></template><script>import { mapGetters} from 'vuex' // 引入vuexexport default { data() { return { } }, computed: { // 第一種使用方法 ...mapGetters({ getState: "city/getState" }) // 第二種使用方法 ...mapGetters('city', ['getState', 'getCityCode']) }}</script>