vuex实际项目中的应用实例:
vuex 包含有五个基本的对象:
state:存储状态。也就是变量;
getters:派生状态。也就是set、get中的get,有两个可选参数:state、getters分别可以获取state中的变量和其他的getters。外部调用方式:store.getters.personInfo()。就和vue的computed差不多;
mutations:提交状态修改。也就是set、get中的set,这是vuex中唯一修改state的方式,但不支持异步操作。第一个参数默认是state。外部调用方式:store.commit('SET_AGE', 18)。和vue中的methods类似。
actions:和mutations类似。不过actions支持异步操作。第一个参数默认是和store具有相同参数属性的对象。外部调用方式:store.dispatch('nameAsyn')。
modules:store的子模块,内容就相当于是store的一个实例。调用方式和前面介绍的相似,只是要加上当前子模块名,如:store.a.getters.xxx()。
二: Vuex HelloWorld
2.1 Vuex安装
cnpm install vuex --save
1
显式使用Vuex插件,一般写在src/main.js中,或者写在其它js中然后再在main.js中引入
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
2.2 多组件共享全局状态示例
分别在Foo.vue和Bar.vue中改变全局属性count值,然后在App.vue中显示count修改后的值。
定义全局单例对象 src/store/store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state, payload) {
state.count += payload.step
},
decrement: state => state.count--,
}
})
定义一个全局实例对象(Vuex.Store):
该对象的状态(state)就是全局属性, 类似于组件的data,每个组件都可以访问和修改属性。
可变的(mutations)类似于组件中的methods, mutations中的每个方法称作为 mutation handler,用来修改state中的值,方法的参数可以有两个(state, payload) state表示全局的单例对象,payload(载荷)也就是参数,调用时可以传递参数,该参数是可选的。
使用Mutation时需遵守的一些规则:
最好提前在你的 store 中初始化好所有所需属性。
当需要在对象上添加新属性时,你应该使用 Vue.set(obj, ‘newProp’, 123), 或者以新对象替换老对象
Mutation 必须是同步函数
在src/main.js中导入store.js并作为Vue的选项
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/store'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
store,
router,
components: { App },
template: '<App/>'
})
将store作为Vue的选项,这样Vue会将store“注入”到每一个子组件中,也就是说每个组件都可以通过this.$store来访问全局单例对象store。
Foo.vue
<template>
<div>
Foo.vue <button @click="increment">+</button>
</div>
</template>
<script>
export default {
name: 'Foo',
methods: {
increment () {
this.$store.commit('increment', {
step: 10
})
}
}
}
</script>
调用store中的mutations方法只能通过提交的方式this.$store.commit('方法名', 负载参数)这一种形式来调用,而不能使用this.$store.方法名 这种普通的的 对象.方法() 方式直接调用。如果感觉这种方式麻烦,Vuex提供了一种将Mutations映射(map)为methods的方式, 然后在使用时直接调用method就会自动帮你commit。
mapMutations() 函数,它接收一个参数,参数类型可以是数组也可以是对象:
数组类型:当使用方法时方法名称和Mutation的名称一样时使用数组类型。
对象类型:当使用方法时方法名称不想和Mutation的名称一样,可以对method起一个新的名称
<template>
<div>
Foo.vue <button @click="add({step: 10})">+</button>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
name: 'Foo',
methods: {
// 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// 将 `this.incrementBy({step: 10})` 映射为 `this.$store.commit('incrementBy', {step: 10})`
...mapMutations(['increment', 'incrementBy']),
// 将Mutation(increment)映射为method(add)
...mapMutations({
add: 'increment'
})
}
}
</script>
注意:mapMutations只是将Mutations简单的映射为methods, 其中method的方法体只包含this.$store.commit(‘mutation’, payload)这一样代码,如果method还要处理其它业务逻辑的话,那么只能使用提交commit方式,而不能使用映射方式mapMutations。
Bar.vue
<template>
<div>
Bar.vue <button @click="decrement">-</button>
</div>
</template>
<script>
export default {
name: 'Bar',
methods: {
decrement () {
this.$store.commit('decrement')
}
}
}
</script>
App.vue
<template>
<div id="app">
App.vue {{count}}
<router-view name="foo"></router-view>
<router-view name="bar"></router-view>
</div>
</template>
<script>
export default {
name: 'App',
computed: {
count() {
return this.$store.state.count
}
}
}
</script>
可以通过{{ this.$store.state.count }}来获取count的值,也可以将this.$store.state.count这行代码包装到计算属性count中,这样获取值就方便点{{ count }}。
src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Foo from '../components/Foo'
import Bar from '../components/Bar'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
components: {
foo: Foo,
bar: Bar
}
}
]
})
为了在一个组件中使用多个兄弟组件,使用命名视图,将这些兄弟组件作为父组件的孩子组件。
2.3 actions
Action 类似于 mutation,Action用于分发(dispatch)mutation,而不直接修改状态。 Action 可以包含任意异步操作(如发送http请求)
action方法接收两个参数(context, payload),context为Context对象,context对象store实例具有相同方法和属性,所以context可以解构成var {state, dispatch, commit, getters} = context
src/store/store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state, payload) {
state.count += payload.step
},
decrement: state => state.count--,
},
actions: {
incrementAsync (context, payload) {
console.log(context.state)
console.log(context.getters)
// 延迟1秒执行
setTimeout(() => {
context.commit('increment', payload)
}, 1000)
}
}
})
Foo.vue
<template>
<div>
Foo.vue <button @click="increment">+</button>
</div>
</template>
<script>
export default {
name: 'Foo',
methods: {
increment () {
this.$store.dispatch('incrementAsync', { step: 10 })
}
}
}
</script>
原文链接:https://blog.csdn.net/sunlizhen/article/details/90231879