State 是 Vuex 的核心,存储应用的所有状态数据。理解如何定义和访问状态,是使用 Vuex 的第一步。
Vuex 使用单一状态树,一个对象包含全部应用状态:
const store = new Vuex.Store({
state: {
count: 0,
user: {
id: 1,
name: '张三',
email: 'zhangsan@example.com'
},
todos: [
{ id: 1, text: '学习 Vue', done: true },
{ id: 2, text: '学习 Vuex', done: false }
],
products: [],
cart: []
}
})
export default {
computed: {
count() {
return this.$store.state.count
},
user() {
return this.$store.state.user
}
}
}
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['count', 'user', 'todos'])
}
}
import { mapState } from 'vuex'
export default {
computed: {
...mapState({
count: state => state.count,
user: state => state.user,
myTodos: 'todos'
})
}
}
import { mapState } from 'vuex'
export default {
computed: {
...mapState({
currentCount: 'count',
currentUser: 'user'
})
}
}
state: {
count: 0,
message: 'Hello',
isActive: true
}
state: {
user: {
id: null,
name: '',
email: ''
},
settings: {
theme: 'light',
language: 'zh-CN'
}
}
state: {
todos: [],
products: [],
notifications: []
}
state: {
entities: {
users: {
byId: {
1: { id: 1, name: '张三' },
2: { id: 2, name: '李四' }
},
allIds: [1, 2]
},
posts: {
byId: {
1: { id: 1, title: '文章1', authorId: 1 },
2: { id: 2, title: '文章2', authorId: 2 }
},
allIds: [1, 2]
}
}
}
直接添加属性不会触发响应式更新
state.user.age = 25
应该使用 Vue.set 或对象展开:
Vue.set(state.user, 'age', 25)
state.user = { ...state.user, age: 25 }
Vue.delete(state.user, 'age')
state.user = {
...state.user,
age: undefined
}
state.todos.push(newTodo)
state.todos.pop()
state.todos.splice(index, 1)
state.todos = state.todos.filter(todo => !todo.done)
state: {
user: {
id: null,
name: '',
email: '',
avatar: '',
role: ''
},
token: null,
isLoggedIn: false
}
import { mapState } from 'vuex'
export default {
computed: {
...mapState('user', ['user', 'isLoggedIn']),
userName() {
return this.user.name || '游客'
},
isAdmin() {
return this.user.role === 'admin'
}
}
}
state: {
cart: {
items: [],
total: 0,
count: 0
}
}
import { mapState } from 'vuex'
export default {
computed: {
...mapState('cart', ['cart']),
cartItems() {
return this.cart.items
},
cartTotal() {
return this.cart.total
},
cartCount() {
return this.cart.count
},
hasItems() {
return this.cart.items.length > 0
}
}
}
state: {
pagination: {
page: 1,
pageSize: 10,
total: 0,
totalPages: 0
}
}
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['pagination']),
currentPage() {
return this.pagination.page
},
hasNextPage() {
return this.pagination.page < this.pagination.totalPages
},
hasPrevPage() {
return this.pagination.page > 1
}
}
}
state: {
loading: {
users: false,
products: false,
orders: false
}
}
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['loading']),
isLoading() {
return Object.values(this.loading).some(v => v)
}
}
}
const store = new Vuex.Store({
state: {
user: JSON.parse(localStorage.getItem('user')) || null,
token: localStorage.getItem('token') || null,
theme: localStorage.getItem('theme') || 'light'
}
})
const store = new Vuex.Store({
state: {
config: null
},
actions: {
async initApp({ commit }) {
const config = await api.getConfig()
commit('setConfig', config)
}
}
})
store.dispatch('initApp')
import createPersistedState from 'vuex-persistedstate'
const store = new Vuex.Store({
plugins: [
createPersistedState({
key: 'my-app',
paths: ['user', 'token', 'settings']
})
]
})
const store = new Vuex.Store({
state: {
user: null
},
mutations: {
setUser(state, user) {
state.user = user
localStorage.setItem('user', JSON.stringify(user))
},
clearUser(state) {
state.user = null
localStorage.removeItem('user')
}
}
})
export default {
computed: {
user() {
return this.$store.state.user
},
userName() {
return this.user?.name || '游客'
}
}
}
<template>
<div>
<p>用户名:{{ user.name }}</p>
<p>邮箱:{{ user.email }}</p>
<p>待办事项:{{ todos.length }} 项</p>
</div>
</template>
<template>
<div v-if="isLoggedIn">
欢迎,{{ user.name }}
</div>
<div v-else>
请先登录
</div>
</template>
State 要点: