Vuex:
安装:
npm install vuex --save
在模块中使用:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
开始,简单实现:
--store.js代码:
import Vue from 'vue'
import Vuex from 'vuex'
// 引用vuex
Vue.use(Vuex)
const state = {
count: 42
}
// mutations类似于事件,对状态进行更改,调用方式: $store.commit('add')
const mutations = {
add(state) {
state.count ++
},
reduce(state) {
state.count --
}
}
export default new Vuex.Store({
state,
mutations
})
--vue组件代码:vuex.vue
import Vue from 'vue'
import Vuex from 'vuex'
// 引用vuex
Vue.use(Vuex)
// 定义状态对象
const state = {
count: 42
}
// mutations类似于事件,对状态进行更改,调用方式: $store.commit('add')
const mutations = {
add(state) {
state.count ++
},
reduce(state) {
state.count --
}
}
export default new Vuex.Store({
state,
mutations
})
--main.js代码:
import Vue from 'vue'
import router from './router'
import vuex from './components/vuex.vue'
import store from './store/store'
//引入store.js文件和vuex.vue模板文件
new Vue({
el: '#app',
router,
store,
render: h => h(vuex),
})
在组件中访问状态对象:缩写 $store.state.count
可以在js中一次引入需要的状态对象,不用每次使用都需要 $store.state.count 的格式:
<template>
<div>
<h1>Hello Vuex</h1>
<p>{{ count }}</p>
<p>
<!-- 两个按钮分别调用mutations的add和reduce事件 -->
<button @click="$store.commit('add')">+</button>
<button @click="$store.commit('reduce')">-</button>
</p>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: mapState([
"count"
])
/* 如下三种方式均可 */
/*computed: {
count() {
return this.$store.state.count + 1
}
}*/
/* computed: mapState({
count:state => state.count
}) */
/* computed: mapState({
count: function(state) {
return state.count
}
}) */
}
</script>
组件触发状态mutations:缩写 $store.commit(‘reduce’)"
// 向mutations的事件中传入对象,并对对象和state进行操作
const mutations = {
add(state, obj) {
state.count += obj.number1
},
reduce(state) {
state.count --
}
}
--vue模板代码:需要引入mapMutations,缩写状态事件,
<template>
<div>
<h1>Hello Vuex</h1>
<p>{{ count }}</p>
<p>
<!-- 两个按钮分别调用mutations的add和reduce事件 -->
<!-- 传入add事件一个对象,每次点击add按钮,count加10 -->
<button @click="$store.commit('add', { number1: 10})">+</button>
<!-- 缩写状态事件 -->
<button @click="reduce">-</button>
</p>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
methods: mapMutations([
'add',
'reduce'
])
}
</script>
Getter:
类似于computed(计算属性),对state进行处理后返回。
这样每次我们调用state的时候,都会先经过getters处理后再返回,如下代码,我们点击加号和减号时,count值都会先加1000然后再执行加一或减一操作:
--store.js代码:
import Vue from 'vue'
import Vuex from 'vuex'
// 引用vuex
Vue.use(Vuex)
const state = {
count: 42
}
const getters = {
count: state => {
return state.count += 1000
}
/* 等同于如下代码: */
/* count: function(state) {
return state.count += 1000
} */
}
// mutations类似于事件,对状态进行更改,调用方式: $store.commit('add')
const mutations = {
add(state, obj) {
state.count += obj.number1
},
reduce(state) {
state.count --
}
}
export default new Vuex.Store({
state,
mutations,
getters
})
--vuex.vue代码:
<template>
<div>
<h1>Hello Vuex</h1>
<p>{{ count }}</p>
<p>
<button @click="add">+</button>
<!-- 缩写状态事件 -->
<button @click="reduce">-</button>
</p>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
methods: mapMutations([
'add',
'reduce'
]),
computed: {
count(){
return this.$store.getters.count
}
}
}
</script>
getters的map形式:
<script>
import { mapState, mapMutations, mapGetters } from 'vuex'
export default {
computed: {
/* mapState也可写成如下格式 */
...mapGetters([
"count"
])
}
}
</script>
--等价于如下代码:
<script>
import { mapState, mapMutations } from 'vuex'
export default {
computed: {
count(){
return this.$store.getters.count
}
}
}
</script>
Action:
类似mutation,Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit
提交一个 mutation,或者通过 context.state
和 context.getters
来获取 state 和 getters。
- mutation是同步状态
- action是异步状态
--点击‘addPlus’按钮,会先进行加一,再进行减一
---store.js代码:
import Vue from 'vue'
import Vuex from 'vuex'
// 引用vuex
Vue.use(Vuex)
const state = {
count: 42
}
const getters = {
count: state => {
return state.count += 0
}
}
// mutations类似于事件,对状态进行更改,调用方式: $store.commit('add')
const mutations = {
add(state, obj) {
state.count += obj.number1
},
reduce(state) {
state.count --
}
}
const actions = {
/* 异步操作,先进行add操作,两秒后进行reduce操作 */
addPlus (context) {
context.commit('add', { number1: 1});
setTimeout(() => {
context.commit('reduce')
}, 2000)
console.log('执行')
},
reducePlus ({commit}) {
commit('reduce')
}
}
export default new Vuex.Store({
state,
mutations,
getters,
actions
})
--vuex.vue:
<template>
<div>
<h1>Hello Vuex</h1>
<p>{{ count }}</p>
<p>
<!-- 两个按钮分别调用mutations的add和reduce事件 -->
<!-- 传入add事件一个对象,每次点击add按钮,count加10 -->
<button @click="$store.commit('add', { number1: 10})">+</button>
<!-- 缩写状态事件 -->
<button @click="reduce">-</button>
</p>
<button @click="addPlus">addPlus</button>
<button @click="reducePlus">reducePlus</button>
</div>
</template>
<script>
import { mapState, mapMutations, mapGetters, mapActions } from 'vuex'
export default {
methods: {
...mapMutations([
'add',
'reduce'
]),
...mapActions([
'addPlus'
]),
...mapActions([
'reducePlus'
])
},
computed: {
...mapState([
"count"
])
}
}
</script>
Module:
Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
--引用:
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
示例:
--将上述例子放置到module中:
--store.js代码:
import Vue from 'vue'
import Vuex from 'vuex'
// 引用vuex
Vue.use(Vuex)
const state = {
count: 42
}
const getters = {
count: state => {
return state.count += 0
}
}
// mutations类似于事件,对状态进行更改,调用方式: $store.commit('add')
const mutations = {
add(state, obj) {
state.count += obj.number1
},
reduce(state) {
state.count --
}
}
const actions = {
/* 异步操作,先进行add操作,两秒后进行reduce操作 */
addPlus (context) {
context.commit('add', { number1: 1});
setTimeout(() => {
context.commit('reduce')
}, 2000)
console.log('执行')
},
reducePlus ({commit}) {
commit('reduce')
}
}
const moduleA = {
state,
mutations,
getters,
actions
}
const moduleB = {
state: { countB: 30 }
}
export default new Vuex.Store({
modules: {
aModule: moduleA,
bModule: moduleB
}
})
--vuex.vue代码:引入state中的count和countB方式要修改为从相应的module中引入
<template>
<div>
<h1>Hello Vuex</h1>
<p>{{ $store.state.aModule.count }} -- {{ $store.state.bModule.countB }}</p>
<p>
<!-- 两个按钮分别调用mutations的add和reduce事件 -->
<!-- 传入add事件一个对象,每次点击add按钮,count加10 -->
<button @click="$store.commit('add', { number1: 10})">+</button>
<!-- 缩写状态事件 -->
<button @click="reduce">-</button>
</p>
<button @click="addPlus">addPlus</button>
<button @click="reducePlus">reducePlus</button>
</div>
</template>
<script>
import { mapState, mapMutations, mapGetters, mapActions } from 'vuex'
export default {
methods: {
...mapMutations([
'add',
'reduce'
]),
...mapActions([
'addPlus'
]),
...mapActions([
'reducePlus'
])
}
}
</script>