• 【Vue】Vuex详解,一文读懂并使用Vuex


    🎉🎉欢迎来到我的CSDN主页!🎉🎉

    🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚

    🌟推荐给大家我的专栏《ELement》。🎯🎯

    👉点击这里,就可以查看我的主页啦!👇👇

    Java方文山的个人主页

    🎁如果感觉还不错的话请给我点赞吧!🎁🎁

    💖期待你的加入,一起学习,一起进步!💖💖

    请添加图片描述

    目录

    一、适合初学者使用,保存数据以及获取数据

    1、在store文件夹,新建个index.js文件(命名看个人习惯,如果没有该文件夹,可以新建一个,当然也可以不建文件夹,直接新建个js文件也是可以的)

    2、main.js引用:(注意路径即可)

    3、保存数据:(场景举例:当我点击按钮后,我需要把当前的数据保存到vuex中,然后跳转到别的路由,然后使用这些数据)

    4、获取变量:(当数据初始获取不到时,可以使用计算属性用来获取)

    二、模块化(适合有部分基础的人)

    1、state.js :保存所有数据,以对象的方式导出

    2、mutations.js :保存所有方法,用来改变state的数据

    3、actions.js :暴露给用户使用,借此触发mutations中的方法,保存数据(可执行异步操作)

    4、index.js:引入相应模块,暴露出store,供vue注册后全局使用

    5、main.js中引入index.js

    6、保存数据

    7、获取数据


    vuex是使用vue中必不可少的一部分,基于父子、兄弟组件,我们传值可能会很方便,但是如果是没有关联的组件之间要使用同一组数据,就显得很无能为力,那么vuex就很好的解决了我们这种问题,它相当于一个公共仓库,保存着所有组件都能共用的数据。

    那么,我们一起来看看vue项目怎么使用它吧。(如果你对vuex有一定了解,不是刚接触的小白,请忽略第一步,直接查看第二步)

    一、适合初学者使用,保存数据以及获取数据

    1、在store文件夹,新建个index.js文件(命名看个人习惯,如果没有该文件夹,可以新建一个,当然也可以不建文件夹,直接新建个js文件也是可以的)

    在新建的js文件中写入如下代码:

    1. import Vue from "vue"
    2. import Vuex from "vuex"
    3. Vue.use(Vuex);
    4. export default new Vuex.Store({
    5. state:{
    6. pathName: "",
    7. currDbSource: {},
    8. currJobData: {},
    9. DbSource: []
    10. },
    11. mutations:{
    12. // 保存当前菜单栏的路径
    13. savePath(state,pathName){
    14. state.pathName = pathName;
    15. },
    16. // 保存当前点击的数据源
    17. saveCurrDbSource(state,currDbSource){
    18. state.currDbSource = currDbSource;
    19. },
    20. // 保存当前点击的元数据
    21. saveCurrJobData(state,currJobData){
    22. state.currJobData = currJobData;
    23. },
    24. // 保存所有数据源
    25. saveDbSource(state,DbSource){
    26. state.DbSource = DbSource;
    27. }
    28. }
    29. })

    这里解释一下各个代码段的作用:state是自定义的一些变量,需要用来保存数据,mutations是用来触发事件,相当于方法,用户需要通过触发这个方法,借此来保存数据,参数的话,第二个参数就是用户传入的值,然后在方法中赋值给state中的变量

    2、main.js引用:(注意路径即可)

    1. // 引入vuex-store
    2. import store from './store/index';
    3. new Vue({
    4. el: '#app',
    5. router,
    6. store,
    7. render: h => h(App)
    8. });

    3、保存数据:(场景举例:当我点击按钮后,我需要把当前的数据保存到vuex中,然后跳转到别的路由,然后使用这些数据)

    1. methods:{
    2. click(){
    3. // 点击按钮进行一些操作,然后保存数据
    4. this.$store.commit('saveCurrDbSource',this.db)
    5. }
    6. }

    这里的第一个参数是要触发的方法,也就是上面mutations中的方法,第二个参数是你要传递的数据

    4、获取变量:(当数据初始获取不到时,可以使用计算属性用来获取)

    1. this.$store.state.变量名
    2. // 例如
    3. this.$store.state.currDbSource

    这样其他组件就可以共用这个保存起来的数据了,也能进行相应的修改

    二、模块化(适合有部分基础的人)

    当然,上述方法中我们把所有东西都写在一个文件中了,这样数据多的时候,耦合度太高,也不便于维护,而且mutations也不能解决异步问题,这里就介绍另一种方式以及actions

    actions:看过官网介绍的人都知道,这是间接触发mutations方法的一种 " 中间商 ",而且它可以执行异步操作,避免用户去直接操作state

    1、state.js :保存所有数据,以对象的方式导出

    1. export default {
    2. pathName: '', // 路由
    3. currDbSource: {}, // 当前数据源
    4. currJobData: {}, // 当前元数据
    5. DbSource: [], // 所有数据源,供元数据界面下拉列表使用
    6. selectJobMeta: {}, // 当前选择的元数据(搜索后点击的单条数据)
    7. specialSubject: [], // 专题数据(多条)
    8. duplicateJobMeta: {}, // 复制的数据
    9. };

    2、mutations.js :保存所有方法,用来改变state的数据

    1. // 保存当前菜单栏的路径
    2. export const savePath = (state, pathName) => {
    3. state.pathName = pathName;
    4. };
    5. // 保存当前点击的数据源
    6. export const saveCurrDbSource = (state, currDbSource) => {
    7. state.currDbSource = currDbSource;
    8. };
    9. // 保存当前点击的元数据
    10. export const saveCurrJobData = (state, currJobData) => {
    11. state.currJobData = null;
    12. state.currJobData = currJobData;
    13. };
    14. // 保存所有数据源
    15. export const saveDbSource = (state, DbSource) => {
    16. state.DbSource = DbSource;
    17. };
    18. // 保存搜索后选择的那一条元数据
    19. export const saveSelectJobMeta = (state, selectJobMeta) => {
    20. state.selectJobMeta = selectJobMeta;
    21. };
    22. // 保存搜索的那一类专题
    23. export const saveSpecialSubject = (state, specialSubject) => {
    24. state.specialSubject = specialSubject;
    25. state.selectJobMeta = {};
    26. };
    27. // 保存复制的元数据(名称为空)
    28. export const saveDuplicateJobMeta = (state, duplicateJobMeta) => {
    29. state.duplicateJobMeta = duplicateJobMeta;
    30. };

    3、actions.js :暴露给用户使用,借此触发mutations中的方法,保存数据(可执行异步操作)

    1. // 触发保存菜单栏的路径方法
    2. export const savePath = ({ commit }, payload) => {
    3. commit('savePath', payload);
    4. };
    5. // 触发获取当前点击的数据源方法
    6. export const saveCurrDbSource = ({ commit }, payload) => {
    7. commit('saveCurrDbSource', payload);
    8. };
    9. // 触发获取当前点击的元数据方法
    10. export const saveCurrJobData = ({ commit }, payload) => {
    11. commit('saveCurrJobData', payload);
    12. };
    13. // 触发获取所有数据源方法
    14. export const saveDbSource = ({ commit }, payload) => {
    15. commit('saveDbSource', payload);
    16. };
    17. // 触发保存搜索后选择单条元数据方法
    18. export const saveSelectJobMeta = ({ commit }, payload) => {
    19. commit('saveSelectJobMeta', payload);
    20. };
    21. // 触发保存搜索专题数据方法
    22. export const saveSpecialSubject = ({ commit }, payload) => {
    23. commit('saveSpecialSubject', payload);
    24. };
    25. // 触发保存复制元数据方法
    26. export const saveDuplicateJobMeta = ({ commit }, payload) => {
    27. commit('saveDuplicateJobMeta', payload);
    28. };

    这里有2种方式:

    1. // 方法一:
    2. export const saveDbSource = (context, payload) => {
    3. context.commit('saveDbSource', payload);
    4. };
    5. // 方法二:
    6. export const saveDbSource = ({ commit }, payload) => {
    7. commit('saveDbSource', payload);
    8. };

    第一种是通过 context上下文用来触发事件,一种是直接通过commit,为了保存数据,都需要加第二个参数payload,不然保存到vuex的数据就是空值

    4、index.js:引入相应模块,暴露出store,供vue注册后全局使用

    1. import Vue from 'vue';
    2. import Vuex from 'vuex';
    3. import state from './state';
    4. import * as actions from './actions';
    5. import * as mutations from './mutations';
    6. Vue.use(Vuex);
    7. export default new Vuex.Store({
    8. state,
    9. actions,
    10. mutations
    11. });

    5、main.js中引入index.js

    1. // 引入vuex-store
    2. import store from './store/index';
    3. new Vue({
    4. el: '#app',
    5. router,
    6. store,
    7. render: h => h(App)
    8. });

    6、保存数据

    1. import { mapActions } from 'vuex';
    2. // 2种方式
    3. // 方法一(dispatch)
    4. this.$store.dispatch('saveDbSource', this.DbSource);
    5. // 方法二(映射)
    6. // 1、通过methods方法添加映射关系
    7. methods: {
    8. ...mapActions(['saveDbSource'])
    9. }
    10. // 2、使用
    11. this.saveDbSource

    这里也有2种保存数据的方法,第一种就是直接操作方法,通过disptach派发给actions,让actions去触发

    第二种就是通过在methods中添加映射关系,数组方式,意味着我们可以在数组中写多个方法(这里数组中的每一个方法名是actions.js文件中所定义的方法名),然后在需要使用的地方直接this.方法名即可。当然,也可以直接绑定给html中的某个事件。

    值的注意的是,避免和methods中自己定义的其他方法的名字冲突

    7、获取数据

    1. import { mapState } from 'vuex';
    2. computed: {
    3. ...mapState(['DbSource']),
    4. // 推荐写法如下:
    5. //...mapState({
    6. // DbSource: state => state.DbSource,
    7. // phoneMap: state => state.richCommunicationSuite.phoneMap, // 模块化写法
    8. //}),
    9. },
    10. watch: {
    11. DbSource(currVal) {
    12. // 监听mapState中的变量,当数据变化(有值、值改变等),
    13. // 保证能拿到完整的数据,不至于存在初始化没有数据的问题,然后可以赋给本组件data中的变量
    14. this.currVal = currVal;
    15. }
    16. }

    通过计算属性,当数据发生改变,我们可以保证拿到的是响应过后的数据,也是数组形式,意味着我们可以拿到多组数据,这里数组中的数据也是state.js中定义的变量(当然,更推荐使用我注释的那段代码,那种写法可以应对当state中存在多模块的情况,比如state.a.xxx,state.b.xxx,其中a和b都是两个模块,各自有对应的数据要存储,也可以自定义我们前面的名字来避免和data中数据重名的情况)

    使用的时候,可以直接通过this.变量名拿到,例如本例中的 this.DbSource,我们可以把它赋给我们自定义的变量,也可以直接使用

    值的注意的是,避免和data中自己定义的其他变量的名字冲突

    至此,我们就完成了vuex的保存以及获取数据,希望对你有所帮助。

    当然,我们需要把一vuex中的一组数据过滤,其他组件都共用过滤后的数据,这种情况大家可能会用到getters,这里我就不多赘述了,有兴趣的小伙伴可以自己了解一下。

    附上vuex的运行过程,官网的图片:组件派发任务到actions,actions触发mutations中的方法,然后mutations来改变state中的数据,数据变更后响应推送给组件,组件重新渲染

    三、案例实操 

    1、安装Vuex

          npm install vuex -S

           npm i -S vuex@3.6.2

    2、创建store模块,分别维护state/actions/mutations/getters

          store

            index.js

            state.js

            actions.js

            mutations.js

            getters.js

      

    3、 store/index.js文件中新建vuexstore实例,并注册上面引入的各大模块

    1. import Vue from 'vue'
    2. import Vuex from 'vuex'
    3. import state from './state'
    4. import getters from './getters'
    5. import actions from './actions'
    6. import mutations from './mutations'
    7. Vue.use(Vuex)
    8. const store = new Vuex.Store({
    9. state,
    10. getters,
    11. actions,
    12. mutations
    13. })
    14. export default store

    并在main.js中导入并使用store实例

    4、通过vuex获取值和改变值

    state.js:保存对象

    1. export default {
    2. Name: '哈佛大学'
    3. };

    mutations.js:改变state 

    1. export default {
    2. setName:(state,payload) => {
    3. state.Name = payload.Name;
    4. }
    5. };

    getters.js:获取state

    1. export default {
    2. getName:(state) => {
    3. return state.Name
    4. }
    5. };

    vue组件效果展示

    1. <script>
    2. export default {
    3. data() {
    4. return {
    5. msg: '北京大学'
    6. }
    7. },
    8. methods: {
    9. fun1(){
    10. let name= this.$store.state.Name
    11. alert(name)
    12. },
    13. fun2(){
    14. this.$store.commit('setName',{
    15. Name:this.msg
    16. })
    17. }
    18. }
    19. }
    20. script>
    21. <style>
    22. style>

    扩展:在别的页面上同样可以获取到state的值

    1. <script>
    2. export default {
    3. computed:{
    4. name(){
    5. return this.$store.state.Name
    6. }
    7. }
    8. }
    9. script>
    10. <style>
    11. style>

    5、通过异步操作获取和改变值

    actions.js:异步改变state的值

    1. export default {
    2. setNameSync:(context,payload) => {
    3. //context指的是vuex的上下文
    4. setTimeout(function(){
    5. context.commit('setName',payload)
    6. },5000)
    7. }
    8. };

     在刚刚的Vue组件中新增一个按钮和点击事件

    1. fun3() {
    2. this.$store.dispatch('setNameSync', {
    3. Name: this.msg
    4. })
    5. }

    效果演示:

    6、通过异步操作发送Ajax到后端

    这个我们有两个注意的点:

    1.发送ajax的vue实例在vuex中不生效;

    2.异步相应时间超时内容不会显示;

     其实很好解决我们只需将vue实例在调用方法的时候就通过参数传递过来,在vuex接收即可使用,然后超时的问题我们设置好我们的响应时间即可。

     后端代码

    1. package com.zking.ssm.controller;
    2. import com.zking.ssm.util.JsonResponseBody;
    3. import org.springframework.web.bind.annotation.RequestMapping;
    4. import org.springframework.web.bind.annotation.RestController;
    5. import javax.servlet.http.HttpServletRequest;
    6. import java.text.SimpleDateFormat;
    7. import java.util.Date;
    8. @RestController
    9. @RequestMapping("/vuex")
    10. public class VuexController {
    11. @RequestMapping("/queryVuex")
    12. public JsonResponseBody queryVuex(HttpServletRequest request) {
    13. String resturantName = request.getParameter("resturantName");
    14. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    15. String date = sdf.format(new Date());
    16. try {
    17. System.out.println("模拟异步情况,睡眠6秒,不能超过10秒,axios超时时间设置的是10秒!");
    18. Thread.sleep(6000);
    19. System.out.println("睡醒了,继续...");
    20. } catch (Exception e) {
    21. e.printStackTrace();
    22. }
    23. return new JsonResponseBody<>(resturantName + "-" + date,true,0,null);
    24. }
    25. }

    在api文件夹下的action.js设置后台请求的地址的封装(URL)

     'VUEX': '/vuex/queryVuex', //Vue后端异步获取

    actions.js:异步发送ajax到后端

    1. setNameAjax: (context, payload) => {
    2. let _this=payload._this
    3. let url = _this.axios.urls.VUEX
    4. let params = {
    5. resturantName: payload.Name
    6. }
    7. _this.axios.post(url, params).then(r => {
    8. console.log(r)
    9. }).catch(r => {
    10. });
    11. }

     继续在刚刚的Vue组件中新增一个按钮和点击事件

    1. fun4() {
    2. this.$store.dispatch('setNameAjax', {
    3. Name: this.msg,
    4. _this:this
    5. })
    6. }

    效果演示:

    请添加图片描述

    到这里我的分享就结束了,欢迎到评论区探讨交流!!

    💖如果觉得有用的话还请点个赞吧 💖

  • 相关阅读:
    TikTok视频播放量低,是被限流了吗?
    C++ 对象克隆关键点
    Omapl38+国产FPGA开发板——开发案例使用测试资料说明(下)
    ❋JQuery的快速入门 1 了解jq
    java-net-php-python-springboot床上用品销售系统计算机毕业设计程序
    VMware vCenter和ESXi 升级注意事项
    竞赛 题目:基于机器视觉opencv的手势检测 手势识别 算法 - 深度学习 卷积神经网络 opencv python
    React 网络请求
    安卓文件权限总结
    接口数据源变更,用 DeepDiff 测
  • 原文地址:https://blog.csdn.net/weixin_74318097/article/details/133412363