Vuex
1.1 安装
npm install vuex --save
1.2 使用
1.2.1 初始化
store/index.js
import vue from 'vue'
import vuex from 'vuex'
vue.use(vuex)
const store=new vuex.Store({
state:{
name:'foo'
}
})
export default store
1.2.2 挂载到Vue实例上
main.js
import store from "./store"; //引入
new Vue({
el: '#app',
store, //es6写法
router,
render: h => h(App)
})
1.2.3 简单使用
<h1>{{$store.state.name}}</h1> //foo
1.3 State
管理全局状态
1.3.1 基本使用
store/index.js
const store=new vuex.Store({
state:{
age:18
}
})
xxx.vue
<h1>{{$store.state.age}}</h1> //18
1.3.2 mapState
xxx.vue
<h2>{{globalAge}}</h2>
-----------------------------
import {mapState} from 'vuex'
computed:{
...mapState({
globalAge:(state)=>state.age //globalAge是自定义得到名字
})
},
1.4 Mutation
修改同步状态,这是更改state的唯一方式,调用store.commit()来实现更改state
1.4.1 基本使用
store/index.js
const store=new vuex.Store({
state:{
name:'foo'
},
mutations:{
changeName (state) { //创建一个函数,供commit调用
state.name="bar"
}
}
})
xxx.vue
<template>
<div class="indexContainer">
<h1>hello</h1>
<h1>{{$store.state.name}}</h1>
<button @click="change">改变name</button>
</div>
</template>
<script>
export default {
name: "index",
data () {
return {}
},
methods:{
change () {
//调用commit(),改变state,changeName需要和mutations定义的函数名一致
this.$store.commit('changeName')
}
}
}
</script>
1.4.2 参数
mutations接受2个参数(state,payload)
state是当前vuex对象的state
payload是当前方法被调用时接收传递的参数
store/index.js
mutations:{
changeName (state,payload) {
state.name=payload.aName
}
}
xxx.vue
change () {
this.$store.commit('changeName',{aName:'bar'}) //以对象的形式传参
}
1.4.3 其他方式提交
store/index.js
mutations:{
changeName (state,payload) {
state.name=payload.aName
}
}
xxx.vue
change () {
this.$store.commit({
type:'changeName',
aName:'bar'
})
}
1.4.4 mapMutations
import { mapMutations } from 'vuex'
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
])
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
1.5 Action
类似Mutation,Action提交的是Mutation,不是直接改变state,是异步改变state的方法,通过dispatch()方法实现
1.5.1 基本使用
store/index.js (参数和提交方式同Mutation一样,这里就不一一详细说明了)
actions:{
getChangeName ({commit},payload) { //{commit}是es6中对象解构的写法 let {commit}=context
commit('changeName',payload) //changeName与Mutation中的方法对应
}
}
xxx.vue
change () {
this.$store.dispatch('getChangeName',{aName:'bar'})
}
1.5.2 mapActions
import { mapActions } from 'vuex'
methods: {
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
]),
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
1.6 Getter
Getter是对state进行修改,相当于computed
1.6.1 基本使用
store/index.js\
state:{
list:[
{name:'foo',age:18},
{name:'bar',age:20},
{name:'tim',age:22},
]
},
getters:{
bigAge (state) {
return state.list.filter(item=>item.age>20)
}
}
xxx.vue
<h1>{{$store.getters.bigAge}}</h1>
1.6.2 参数
Getter接收2个参数(state,getters)
state---全局状态
getters---其他getters
getters: {
domain: (state, getters) => {
return getters.doneTodos.length
}
}
1.6.3 访问方式
属性访问
getters:{
bigAge (state) {
return state.list.filter(item=>item.age>20)
}
}
---------------------------------------------------------------------------
<h1>{{$store.getters.bigAge}}</h1>
方法访问
getters: {
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
---------------------------------------------------------------------------
<h1>{{$store.getters.getTodoById(2)
1.6.4 mapGetters
import { mapGetters } from 'vuex'
computed: {
...mapGetters([
'doneTodosCount',
'anotherGetter',
])
}
1.7 Module
想象一下,如果项目大,state比较多,我们应该怎么办,这时候就用到module,他可以将store分割成若干个模块,每个模块拥有自己的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
}
})
但是这样有一定缺点,若模块非常多,这导致模块都挤到一个文件里面,不易于维护,正确做法参考进阶。
1.8 进阶
目录结构
store
--modules //存放各个模块
--a.js //a模块
--b.js //b模块
--getters.js //操作公共state
--index.js //统一导入各个模块,向外暴露
1.8.1 基本使用
store/modules/a.js
const state = {
name:'foo'
}
const mutations = {
changeName (state) {
state.name='bar'
}}
const actions = {
getChangeName ({commit}) {
setTimeout(()=>{
commit('changeName')
},1000)
}}
export default {
namespaced: true, //带命名空间的模块,不与其他模块冲突
state,
mutations,
actions
}
store/getters.js
const getters={
add (state) {
return state.a.count //需要带上文件名
}
}
export default getters
store/index.js 需要在index.js中进行统以暴露
import vue from 'vue'
import vuex from 'vuex'
import getters from './getters'
vue.use(vuex)
//将所以模块在index中进行统一引入
const modulesFiles = require.context('./modules', true, /\.js$/)
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules
}, {})
const store = new vuex.Store({
modules,
getters
})
export default store
xxx.vue
<h1>{{$store.state.a.name}}</h1> //使用state 需要带上文件名
<h2>{{$store.commit('a/changeName')}}</h2> //使用mutations 需要带上文件名
<h2>{{$store.dispatch('a/getChangeName')}}s</h2> //使用actions 需要带上文件名
<h2>{{$store.getters.add}}</h2> //使用getters
如果觉得有帮助欢迎点赞、评论。 上述内容仅仅代表个人观点,如有错误,请指正。如果你也对前端感兴趣,欢迎访问我的个人博客sundestiny.github.io/myblog/