Vuex 的简单使用
Vue 组件之间有很多种通信方式,例如 props
、ref
、$emit
等。但是这些通信方式都有一个问题就是一次只能和一个组件通信,如果要把值传给多个组件就需要写多行代码,而且对于层级较多的组件来说需要传很多次,不太方便。
Vuex 是 Vue 的一个状态管理插件,它能实现让多个组件共享同一份数据,如果某个组件更改了数据其它组件也能响应数据变化。
安装 & 引入
使用 npm 安装:
npm install vuex --save
在 main.js
中引入:
import Vuex from 'vuex'; // 引入 Vuex
vue.use(Vuex); // 注册 Vuex
编写 Store
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。
下面编写一个简单的 Store:
const store = new Vuex.Store({
state: {
content: 'Hello Vuex'
},
mutations: {
chContent(state) {
state.content = 'Hello World';
}
}
});
上面的 state
中的 content
就是状态,mutations
中的 chContent
就是改变状态的方法,如果调用 chContent
,state
中的 content
就会被更改为 Hello World
。
为了让其它组件能够访问 Store,在实例化 Vue 的时候需要传入 Store,如下:
const store = new Vuex.Store({
state: {
content: 'Hello Vuex'
},
mutations: {
chContent(state) {
state.content = 'Hello World';
}
}
});
new Vue({
store,
render: h => h(App),
}).$mount('#app');
Store 对象你也可以放到单独的文件中,我上面为了方便,直接放到了 main.js
中。
获取状态
下面在组件中获取 Store 的状态:
<template>
<div id="app">
<h1>{{$store.state.content}}</h1>
</div>
</template>
上面在 h1
中输出了 content
。
下面通过函数在控制台中输出 content
:
export default {
name: 'App',
created() {
console.log(this.$store.state.content);
}
}
更改状态
上面 Store 的 mutations
中有一个 chContent
方法可以把 content
更改为 Hello World
,下面就调用 chContent
方法:
this.$store.commit('chContent');
使用 $store.commit
方法可以调用 mutations
中的方法来更改状态,第一个参数 type
就是方法名称。
如果要动态改变内容,在编写 Store 的时候可以给 mutations
中的方法加第二个参数,如下:
const store = new Vuex.Store({
state: {
content: 'Hello Vuex'
},
mutations: {
chContent(state, content) {
state.content = content;
}
}
});
在调用 $store.commit
更改状态的时候也可以传入第二个参数,如下:
this.$store.commit('chContent', '更改的内容');
第二个参数就是需要动态改变的内容。
如果需要接收多个字段可以传入对象,而不是多个参数,如下:
const store = new Vuex.Store({
state: {
userName: '',
login: false
},
mutations: {
chContent(state, user) {
state.userName = user.userName;
state.login = user.login;
}
}
});
this.$store.commit('chContent', {
userName: 'Jack',
login: true
});
$store.commit
也可以使用对象语法提交状态更改,上面的 Store 不变,下面使用对象语法更改状态:
this.$store.commit({
type: 'chContent',
userName: 'Mark',
login: true
});
type
的值就是 mutations
的方法名称。
Action
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
下面是一个简单的 Action:
const store = new Vuex.Store({
state: {
content: 'Hello Vuex'
},
mutations: {
chContent(state) {
state.content = 'Hello World';
}
},
actions: {
chContent(context) {
context.commit('chContent');
}
}
});
actions
的方法可以接收一个 context
,可以通过 context
提交 commit
来调用 mutations
中的方法。
下面调用 actions
中的 chContent
来更改 state
中的 content
:
this.$store.dispatch('chContent');
使用 context.state
也可以获取 state
的状态,下面在 actions
中编写一个 getContent
方法来获取状态:
const store = new Vuex.Store({
state: {
content: 'Hello Vuex'
},
mutations: {
chContent(state) {
state.content = 'Hello World';
}
},
actions: {
getContent(context) {
return context.state.content;
}
}
});
下面调用 actions
中的 getContent
来获取 state
中的 content
:
const content = this.$store.dispatch('getContent');
// 返回一个 Promise
content.then(value => {
console.log(value); // 在控制台输出
});
actions
中的方法也可以接收第二个参数,如下:
const store = new Vuex.Store({
state: {
content: 'Hello Vuex'
},
mutations: {
chContent(state, text) {
state.content = text;
}
},
actions: {
chContent(context, text) {
context.commit('chContent', text);
}
}
});
this.$store.dispatch('chContent', '更改的内容');
上面说过 Action 可以包含异步操作,下面就在 actions
的 chContent
方法中设置一个 setTimeout
来延迟调用 mutations
中的 chContent
:
const store = new Vuex.Store({
state: {
content: 'Hello Vuex'
},
mutations: {
chContent(state, text) {
state.content = text;
}
},
actions: {
chContent(context, text) {
setTimeout(() => {
context.commit('chContent', text)
}, 3000);
}
}
});
this.$store.dispatch('chContent', '更改的内容');
3 秒后 mutations
中的 chContent
才会被调用。
Module
对于复杂的大型项目来说,如果把所有的状态都写到一个 store 对象中,可能会导致 store 对象的内容过多,不太好维护。
Vuex 允许将 store 分割成 模块 (module),每个模块拥有自己的 state、mutation、action、getter。
下面是两个 store 模块:
// 模块A的 store
const moduleA = {
state: () => {
return {text: '这里是模块A'};
},
mutations: {
chText(state) {
state.text = '模块A';
}
},
actions: {
chText(context) {
// 延迟 3 秒调用 mutations 的 chText
setTimeout(() => {
context.commit('chText');
}, 3000);
}
}
};
// 模块B的 store
const moduleB = {
state: () => {
return {text: '这里是模块B'};
},
mutations: {
chText(state) {
state.text = '模块B';
}
}
};
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
});
在组件中调用这两个模块:
<template>
<div id="app">
<h1>{{$store.state.a.text}}</h1>
<h1>{{$store.state.b.text}}</h1>
</div>
</template>
相关文章:
版权声明:本文为原创文章,版权归 Mr. Ma's Blog 所有,转载请联系博主获得授权。
本文地址:https://www.misterma.com/archives/881/
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。