1. Website
Official Website: vuex.vuejs.org/#what-is-a-…
2. Install
npm install vuex@next --save
3. Introduction
3.0 Element
-
State : 提供唯一的公共数据源,所有共享的数据统一放到store的state进行储存,相似与data
-
Mutation : 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
-
Action : Action和Mutation相似,一般不用Mutation 异步操作,若要进行异步操作,使用Action
-
Getter : 类似于vue中的computed,进行缓存,对于Store中的数据进行加工处理形成新的数据
-
Modules : 当遇见大型项目时,数据量大,store就会显得很臃肿,为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
3.0.1 Constructure
vue2-demo
├── public/ # static files
│ ├── index.html # 入口文件
│ └── favicon.ico # title icon (可以多個,切換路由titile也切換)
├── src/ # project root
│ ├── assets/ # images, icons, etc.靜態資源
│ ├── api/ # 封裝http
│ ├── components/ # common components - 客製化頁面
│ ├── layouts/ # layout containers -header, footer,sidebar, etc.
│ ├── scss/ # scss styles
│ ├── config/ # 封裝http
│ │ └── httpConfig.ts # axios
│ ├── store/ # 全局狀態管理
│ │ ├── state.js # 響應式數據
│ │ ├── actions.js # 動態修改state的值
│ │ ├── getters.js # 對state中的數據進行加工並形成新數據
│ │ ├── mutations.js # 靜態修改state的值
│ │ ├── modules/ # 如果是大項目,進行切分
│ │ └── index.js # 將前面所有js導入vuex
│ ├── i18n/ # 多語言切換
│ │ ├── locales/ # 多語言切換
│ │ │ ├── en.ts # 中文
│ │ │ ├── zh.ts # 英文
│ │ │ └── xxx.ts # 其他文
│ │ └── index.ts # I18N切換
│ ├── router/ # routes config
│ ├── views/pages # Route apge,路由導航的頁面
│ │ ├── dashboard # 儀錶盤頁面
│ │ ├── login # 登錄頁面、註冊頁面
│ │ └── .... # etc..
│ ├── App.vue # 三個標籤 template /script /style
│ └── main.js # 加載所有組件,掛載都index.html
├── package.json # dependency
└── vue.config.js # project config,install plugin,proxy
3.1 State
1.聲明全局變量
export const state = {
loading: false,
token: false,
login: false,
smallDevice: false,
userProfile: {
username: "",
password: "",
address: "",
phone: "",
age: 0
},
redirectUrl: "",
result: []
2.使用
<p>{{$store.state.userProfile.username}}</p>
<p>{{$store.state.userProfile.password}}</p>
this.$store.state.userProfile.address
import {mapState} from "vuex";
<p>{{username + password + address}}</p>
computed: {
...mapState(["username","password","address"])
}
3.2 Mutation(Synchronous)
1.聲明
export const mutations = {
addAge(state, num) {
state.userProfile.age += state.userProfile.age + num
},
reduce(state) {
state.userProfile.age --
},
someMutation (state) {
api.callAsyncMethod(() => {
state.count++
})
}
}
2.使用
methods:{
//加法
btn(){
this.$store.commit("addAge",10)
}
//减法
btn1(){
this.$store.commit("reduce")
}
}
import { mapMutations } from 'vuex'
export default {
methods: {
// 多個.
...mapMutations([
'addAge', // map `this.addAge(num)` to `this.$store.commit('addAge',num)`
'reduce', // map `this.reduce()` to `this.$store.commit('reduce')`
]),
// 別名.
...mapMutations({
add: 'increment' // map `this.add()` to `this.$store.commit('increment')`
}),
btn(){
this.addAge(10)
}
btn1(){
this.reduce()
}
}
}
3.3 Action(Asynchronous)
1.Simple
const store = createStore({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
//可以简写下面的形式
actions: {
increment ({ commit }) {
commit('increment')
}
}
})
2.大项目分开写
export const setToken = ({ commit }, token) => {
commit("setToken", token)
}
export const setLogin = ({ commit }, login) => {
commit("setLogin", login)
}
export const setUserProfile = ({ commit }, userProfile) => {
commit("setUserProfile", userProfile)
}
export const setRedirectUrl = ({ commit }, redirectUrl) => {
commit("setRedirectUrl", redirectUrl)
}
3.使用
store.dispatch('increment')
4.也可以设定变数
function.js定义变数,然后调用方法时使用变数
export const TOKEN = "TOKEN"
export const LOGIN = "LOGIN"
3.4 Getter
1.Simple
const store = createStore({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos (state) {
return state.todos.filter(todo => todo.done)
}
//getters也可以做参数传递
doneTodosCount (state, getters) {
return getters.doneTodos.length
}
}
})
2.大項目
export const getLoading = (state) => state.loading
export const getToken = (state) => state.token
export const getLogin = (state) => state.login
export const getUserProfile = (state) => state.userProfile
export const getRedirectUrl = (state) => state.redirectUrl
3.使用
store.getters.doneTodos
store.getters.doneTodosCount
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// mix the getters into computed with object spread operator
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
}
3.5 Modules
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = createStore({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> `moduleA`'s state
store.state.b // -> `moduleB`'s state
3.6 index.js import
/src/store/index.js
import Vue from "vue"
import Vuex from "vuex"
import * as getters from "./getters.js"
import * as actions from "./actions.js"
import * as state from "./state.js"
import * as mutations from "./mutations.js"
// modules
import xxxModules from "./modules/xxxModule"
Vue.use(Vuex)
export default new Vuex.Store({
state,
actions,
mutations,
getters,
modules: {
xxxModules,
}
})
/src/main.js
import App from "@/App"
import store from "@/store/index"
import router from "@/config/router"
import i18n from "@/config/lang"
new Vue({
router,
store,
i18n,
render: (h) => h(App),
}).$mount("#app")