vuex小结

什么是vuex

Vuex 是一个专为 Vue 开发的应用程序的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
总之:Vuex 采用类似全局对象的形式来管理所有组件的公用数据,如果想修改这个全局对象的数据,得按照Vuex提供的方式来修改想·

使用vuex

要想使用vuex 我们需要

1. 安装Vuex

# npm 安装
npm install vuex

# yarn 安装
yarn add vuex

2. 引入vuex
在src目录下创建一个store目录,在该目录下创建index.js文件,用于创建Store对象

//用于创建Vuex的核心对象Store
//1.导入
import {createStore } from 'vuex'


//2.创建Store对象
const store = createStore({
//state 用于存储数据
state(){
return {
count:1,
}
},
//actions 用于响应组件中的事件
actions:{

},
//mutations 用于操作数据
mutations:{

}
});


//3.暴露出store对象
export default store;

第二步: 在main.js 使用store对象

import store from './store';
app.use(store);
``

第三步: 在 Vue 组件中, 可以通过 this.$store 访问store实例```

<template>
<h2>{{$store.state.count}}</h2>
</template>

<script>
export default {
name: 'App',
data() {
return {

};
},
components: {
},
methods: {

},
mounted() {
console.log(this.$store.state.count);
}
};
</script>

<style lang="css" scoped>
</style>

vuex的包含模块

  1. State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
  2. Getter:允许组件从 store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter
    映射到局部计算属性。
  3. Mutation:是唯一更改 store 中状态的方法,而且要是同步函数。
  4. Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
  5. Module:可以将 store 分割成模块(module)。每个模块拥有自己的
    state、mutation、action、getter、甚至是嵌套子模块
    在这里插入图片描述
    vuex的工作流程就是:
    (1)通过dispatch去提交一个actions,
    (2) actions接收到这个事件之后,在actions中可以执行一些异步|同步操作,根据不同的情况去分发给不同的mutations,
    (3)actions通过commit去触发mutations,
    (4)mutations去更新state数据,state更新之后,就会通知vue进行渲染。

vuex的核心概念

1. State
假设我们有一个全局状态 count 的值为 5。那么,我们就可以将其定义为 state 对象中的 keyvalue,作为全局状态供我们使用。如下:

import { createStore } from 'vuex'
export default createStore({
    state: {
		count:5  //总数:5
    }
}    

2. Getters
可以认为,getters 是store的计算属性,类似于computed,对state里的数据进行一些过滤,改造等等
getters 接受 state 作为其第一个参数

const getters ={
    getNumDouble(state){
        let sum=0;
        sum=state.count*2;
        return sum;
    },

    getTotalNum(state){
        let totalNum=0;
        state.phoneList.forEach(phoneList => {
            totalNum+=phoneList.num;
        });
        return totalNum;
    },

    getTotalPrice(state){
        let totalPrice=0;
        state.phoneList.forEach(phoneList => {
            totalPrice+=phoneList.num*phoneList.price;
        });
        return totalPrice;
    }
}

3. Mutations
Vuex 给我们提供修改仓库 store 中的状态的唯一办法就是通过提交mutation

mutation必须是同步函数,这是 Vuex 设计时的一个核心原则:

Vuex 的状态跟踪机制依赖于同步的 mutations
当 mutation 异步执行时,Vuex 无法准确地知道何时状态已经更新,这可能导致无法正确地显示状态变化
在 mutations 中,可以直接修改state状态

//修改状态的方法
const mutations ={
    
    addCount(state){
        state.count++;
    },

    addCount2(state,payload) {
        state.count+=payload.value;
    },

    defCount(state){
        state.count=0;
    },

    addNum(state,payload) {
        console.log(state.phoneList[0]);
        console.log(payload.index);
        state.phoneList[payload.index].num++;
    },

    delNum(state,payload){
        state.phoneList[payload.index].num--;
    },

    delPhone(state,payload){
        console.log(payload.index);
        state.phoneList.splice(payload.index,1);
    }
}

4. Action
Actions 是可以包含任意异步操作的函数
在 actions 中,不能直接修改状态(state),而需要通过 dispatch 方法提交一个 mutation 来更改状态
只有通过 action => mutations => states ,这个流程进行操作,具体步骤如下:

//actions 操作 定义事件,让组件触发事件
const actions = {
    increment(context){
        //调用moutations中的方法修改state
        context.commit('addCount');
    },

    increment2(context,payload) {
        setTimeout(
            () => {
                context.commit("addCount2",payload);
    },3000
);
},

    reduce(context){
        context.commit('defCount');
    },

    addNum1(context,payload) {
        context.commit('addNum',payload);
    },

    delNum1(context,payload) {
        context.commit('delNum',payload);
    },

    delPhone1(context,payload) {
        context.commit('delPhone',payload);
    }
}

5. 操作数据
运用vuex语法糖 mapState、mapGetters 和 mapMutations

mapState:映射 state 到组件的计算属性:…mapState([“news”]) 就相当于 this.$store.state.news

mapGetters:映射 getters 到组件的计算属性:…mapGetters([“news”]) 就相当于 this.$store.getters.news

mapMutations :映射 mutations 到 组件的 methods:

…mapMutations([{ changeNews: “SET_NEWS” }]) 就相当于 给 SET_NEWS 重命名为 changeNews
this.changeNews(val) 就相当于 this.$store.commit(“SET_NEWS”, val)

<template>  
	<div>  
		<p>News: {{ news }}</p>  
		<button @click="submit">ChangeNews</button>  
	</div>  
</template>  

<script>  
import { mapState, mapGetters, mapMutations  } from "vuex";
export default {
	computed: {
		// 映射 state 到组件的计算属性
        ...mapState(["news"]) // 相当于 this.$store.state.news (vuex语法糖)
        
		// 或者
		
		// 映射 getters 到组件的计算属性
        ...mapGetters(["news"]) // 相当于 this.$store.getters.news (vuex语法糖)
	},
	methods: {  
		...mapMutations([{
		    // 将 changeNews 与 mutations中的 SET_NEWS 关联
		    changeNews: "SET_NEWS" // 相当于给 SET_NEWS 重命名为 changeNews
		}]),
		submit () {
			let val = 'test news';
			this.changeNews(val); // 相当于 this.$store.commit("SET_NEWS", val);
		}
	}  
}
</script>

六、Vue3 setup 中使用
在 Vue2 项目中可以使用 this.$store 获取 vuex 里的数据和保存全局数据,但是在 Vue3 的 setup 函数里,并没有 this 这个概念,这里可以使用 useStore 代替,具体使用如下:

<template>  
  <div>  
    <p>News: {{ news }}</p>  
    <button @click="changeNews">Change News</button>  
  </div>  
</template>  
  
<script>  
import { ref, onMounted } from 'vue';  
import { useStore } from 'vuex';  
  
export default {  
  setup() {  
    // 使用 useStore 钩子获取对 Vuex store 的引用  
    const store = useStore();  
  
    // 创建一个响应式引用来存储 news  
    const news = ref(store.state.news);  
  
    // 定义一个方法来改变 news  
    const changeNews = () => {  
      // 提交 mutation 来改变 news  
      store.commit('SET_NEWS', 'test news');  
    };  
  
    // 返回需要在模板中使用的响应式引用和方法  
    return {  
      news,  
      changeNews,  
    };  
  },  
};  
</script>

store/index.js:

//  Vue3.x 中通过 createStore 创建 store
import { createStore } from 'vuex'

export default createStore({
    state: {
        news: null
    },
    mutations: {
        SET_NEWS: (state, value) => {
            state.news = value;
        }
    },
    getters: {
        news : state => { state.news || sessionStorage.news }
    },
    actions: {
        getData(store) {
        	// 模拟异步
             setTimeout(() => {
                store.commit('SET_NEWS', '');
             }, 2000);
         }
    },
    modules: {}
})
  • 13
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值