vuex的基本使用
安装:(可以参考vuex官网:https://vuex.vuejs.org/zh/)
下面是从官网截的图:
(以下是学习时进行的一些小案例,具体项目中不会只建一个store.js文件,而是使用modules模块化。)
新建一个store.js的文件进行配置
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state:{ },
getters:{},
mutations:{},
actions:{},
})
同时在main,js里引入
import store from './store'
new Vue({
store
})
1、vuex中的state和mapState
例子:
在store.js中写入数据
state:{
count:0,
todos:[
{
id: 1,
title: 'todo item 1',
completed: true
},
{
id: 2,
title: 'todo item 2',
completed: true
},
{
id: 3,
title: 'todo item 3',
completed: false
}
]
},
在vue的文件里获取数据:
<template>
<div>count的值:{{count}}<br/>{{todos}}</div>
</template>
获取写在计算方法属性里:
方法1:
computed:{
count(){
return this.$store.state.count
},
todos(){
return this.$store.state.todos
}
}
方法2:
import {mapState} from 'vuex'
export default {
computed:mapState({
count:state => state.count,
todos:state => state.todos
})
}
方法3:
import {mapState} from 'vuex'
export default {
computed:mapState(["count","todos"])
}
这三种方法的显示效果都是一样的,只是书写的复杂程度不同。
运行结果:
2、vuex中的getters和mapGetters
有时候我们需要从 store 中的 state 中派生出一些状态。
使用getters可以对数据进行改变
例子:
在store,js中
export default new Vuex.Store({
state:{
count:0,
todos:[
{
id: 1,
title: 'todo item 1',
completed: true
},
{
id: 2,
title: 'todo item 2',
completed: true
},
{
id: 3,
title: 'todo item 3',
completed: false
}
]
},
getters:{
count:state => {
return ++state.count
},
completedTodos: state => {
return state.todos.filter(todo => todo.completed);
// 这里是使用一个过滤,将todos数组中completed为true的过滤出来。
},
completedTodosCount:(state,getters) => {
return getters.completedTodos.length;
},
// 这里传入的第一个是参数state,第二个是外部传过来的参数id
getTodosById:state => id =>{
return state.todos.find(todo => todo.id === id);
}
},
mutations:{},
actions:{},
})
.vue文件里获取数据:
<div class='container'>
<div>count的值:{{count}}<br/>
{{completedTodos}} <br/>
todos 过滤后的长度{{completedTodosCount}} <br/>
<div>{{getTodosById(2)}}</div>
</div>
</div>
获取方法写在计算属性里:
方法1:
computed:{
count(){
return this.$store.getters.count;
},
completedTodos(){
return this.$store.getters.completedTodos;
},
completedTodosCount(){
return this.$store.getters.completedTodosCount;
},
getTodosById(){
return this.$store.getters.getTodosById;
}
}
方法2:
import {mapState,mapGetters} from 'vuex'
export default {
computed:mapGetters(['count','completedTodos','completedTodosCount','getTodosById'])
}
这两种方法显示结果也是一样的。
关于getters的测试,这里写了四个方法,分别是显示四种数据:
第一个方法count是显示state中的数据count+1之后的值;
第二个方法completedTodos显示的是过滤出state中completed的值为true的数据;
第三个方法completedTodosCount是显示出completedTodos的长度
第四个方法是根据传入的id来决定显示的数据。
运行结果:
3、vuex中的mutation和mapMutations
类似于事件中的方法!
例:
在store.js中
mutations:{
// 不带参数改变
incrementCount(state){
state.count++;
},
// 携带参数
decrementCount(state,n) {
state.count -= n;
},
// 携带参数,且参数是对象
btncrementCount(state,payload){
state.count -= payload.amount;
}
},
在.vue中
<div class='container'>
{{count}}
<button @click="decrement(10)"> 带参数减 </button>
<button @click="increment"> 不带参数加 </button>
<button @click="btncrement({amount:5})">参数是对象减</button>
</div>
获取数据写在methods方法里:
methods:{
decrement(m){
this.$store.commit("decrementCount",m)
},
increment(){
this.$store.commit("incrementCount");
},
btncrement(m){
this.$store.commit("btncrementCount",m)
}
},
写法二与前面两种写法一样,只是将computed换为methods。
注意:一条重要的原则就是要记住 mutation 必须是同步函数
4、vuex中的actions和mapActions
actions里主要进行一些异步额操作,比如请求接口,进行计时器等等。
1------计数器例子:
在store.js中:
actions:{
// 这里的意思是执行actions的时候,延迟两秒去提交mutations
// (不带参数延迟两秒增加)---写法1:
incrementCountAsync(context){
setTimeout(() => {
//在这里的context相当于vue文件中的this.$store
context.commit('incrementCount')
},2000)
},
// (不带参数延迟两秒增加)---写法2:
incrementCountAsync({commit}){
setTimeout(() => {
commit('incrementCount')
},2000)
},
// 携带参数延迟两秒减少
decrementCountAsync({commit}, payload){
setTimeout(() => {
commit('decrementCount',payload)
},2000)
}
},
.vue文件中:
methods:{
increment(){
this.$store.dispatch("incrementCountAsync");
},
decrement(m){
this.$store.dispatch("decrementCountAsync",m);
}
},
以上可以实现点击按钮之后,延迟两秒,数据改变。
2------请求接口
首先,要引入axios
然后,在store.js中
import Vue from 'vue'
import axios from 'axios'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state:{
count:0,
todos:[]
},
getters:{
count:state => {
return ++state.count
},
completedTodos: state => {
return state.todos.filter(todo => todo.completed);
// 这里是使用一个过滤,将todos数组中completed为true的过滤出来。
},
},
mutations:{
// 请求接口
setTodos:(state,todos) => (state.todos = todos)
},
actions:{
// 请求接口
async fetchTodos({commit}){
const response = await axios.get('http://jsonplaceholder.typicode.com/todos');
console.log(response);
commit('setTodos',response.data);
}
},
})
在.vue文件中
<div class='container'>
<!-- fetchTodos -->
<div>{{completedTodos}}</div>
<br/>
<br/>
<button @click="fetchTodos">拉取api接口数据</button>
</div>
<script>
import {mapState,mapGetters} from 'vuex'
export default {
methods:{
fetchTodos(){
this.$store.dispatch("fetchTodos");
}
},
computed:mapGetters(['count','completedTodos'])
}
</script>
思路分析:在store里进行接口请求;在触发fetchTodos的方法是,会去store的actions里请求接口,然后actions再触发mutations将数据传递给vue文件,而getters则对数据进行了过滤。
actions的简写的方法也和上面是一样的。