vue中使用vuex(超详细)

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

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

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

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

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

import Vue from "vue"
import Vuex from "vuex"
 
Vue.use(Vuex);
 
export default new Vuex.Store({
    state:{
        pathName: "",
        currDbSource: {},
        currJobData: {},
        DbSource: []
    },
    mutations:{
        // 保存当前菜单栏的路径
        savePath(state,pathName){
            state.pathName = pathName;
        },
        // 保存当前点击的数据源
        saveCurrDbSource(state,currDbSource){
            state.currDbSource = currDbSource;
        },
        // 保存当前点击的元数据
        saveCurrJobData(state,currJobData){
            state.currJobData = currJobData;
        },
        // 保存所有数据源
        saveDbSource(state,DbSource){
            state.DbSource = DbSource;
        }
    }
})

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

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

// 引入vuex-store
import store from './store/index';
 
new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
});

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

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

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

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

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

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

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

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

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

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

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

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

// 保存当前菜单栏的路径
export const savePath = (state, pathName) => {
  state.pathName = pathName;
};
 
// 保存当前点击的数据源
export const saveCurrDbSource = (state, currDbSource) => {
  state.currDbSource = currDbSource;
};
 
// 保存当前点击的元数据
export const saveCurrJobData = (state, currJobData) => {
  state.currJobData = null;
  state.currJobData = currJobData;
};
 
// 保存所有数据源
export const saveDbSource = (state, DbSource) => {
  state.DbSource = DbSource;
};
 
// 保存搜索后选择的那一条元数据
export const saveSelectJobMeta = (state, selectJobMeta) => {
  state.selectJobMeta = selectJobMeta;
};
 
// 保存搜索的那一类专题
export const saveSpecialSubject = (state, specialSubject) => {
  state.specialSubject = specialSubject;
  state.selectJobMeta = {};
};
 
// 保存复制的元数据(名称为空)
export const saveDuplicateJobMeta = (state, duplicateJobMeta) => {
  state.duplicateJobMeta = duplicateJobMeta;
};

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

// 触发保存菜单栏的路径方法
export const savePath = ({ commit }, payload) => {
  commit('savePath', payload);
};
 
// 触发获取当前点击的数据源方法
export const saveCurrDbSource = ({ commit }, payload) => {
  commit('saveCurrDbSource', payload);
};
 
// 触发获取当前点击的元数据方法
export const saveCurrJobData = ({ commit }, payload) => {
  commit('saveCurrJobData', payload);
};
 
// 触发获取所有数据源方法
export const saveDbSource = ({ commit }, payload) => {
  commit('saveDbSource', payload);
};
 
// 触发保存搜索后选择单条元数据方法
export const saveSelectJobMeta = ({ commit }, payload) => {
  commit('saveSelectJobMeta', payload);
};
 
// 触发保存搜索专题数据方法
export const saveSpecialSubject = ({ commit }, payload) => {
  commit('saveSpecialSubject', payload);
};
 
// 触发保存复制元数据方法
export const saveDuplicateJobMeta = ({ commit }, payload) => {
  commit('saveDuplicateJobMeta', payload);
};

这里有2种方式:

// 方法一:
export const saveDbSource = (context, payload) => {
   context.commit('saveDbSource', payload);
};
 
// 方法二:
export const saveDbSource = ({ commit }, payload) => {
  commit('saveDbSource', payload);
};

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

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

import Vue from 'vue';
import Vuex from 'vuex';
import state from './state';
import * as actions from './actions';
import * as mutations from './mutations';
 
Vue.use(Vuex);
 
export default new Vuex.Store({
  state,
  actions,
  mutations
});

5、main.js中引入index.js

// 引入vuex-store
import store from './store/index';
 
new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
});

6、保存数据

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

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

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

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

7、获取数据
 

import { mapState } from 'vuex';
 
computed: {
    ...mapState(['DbSource']),
},
watch: {
    DbSource(currVal) {
        // 监听mapState中的变量,当数据变化(有值、值改变等),
        // 保证能拿到完整的数据,不至于存在初始化没有数据的问题,然后可以赋给本组件data中的变量
      this.currVal = currVal;
    }
}

通过计算属性,当数据发生改变,我们可以保证拿到的是响应过后的数据,也是数组形式,意味着我们可以拿到多组数据,这里数组中的数据也是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中的数据,数据变更后响应推送给组件,组件重新渲染

转载于:vue中使用vuex(超详细)_坏丶毛病的博客-CSDN博客_vuex使用

1.传值

// 定义参数
let params = {
  workItemId: workItemId,
  flowInstId: flowInstId,
  itemStatus: itemStatus,
  type: type,
  srcId: srcId
}
// 保存参数
this.$store.dispatch('approvalConfirmParams', params);

2.vuex

(1)index.js

/**
 * 步骤一
 * vuex 入口文件
 */
// 引入 vue
import Vue from 'vue'
// 引入 vuex
import Vuex from 'vuex'
 
import actions from './actions'
import mutations from './mutations'
 
Vue.use(Vuex);
 
// 导出
export default new Vuex.Store({
  modules:{
    mutations
  },
  actions
});

(2)types.js

/**
 * 步骤二
 * 状态(类型)
 */
// 审批历史页请求参数
export const APPROVAL_HISTORY_PARAMS = 'APPROVAL_HISTORY_PARAMS';

 (3)actions.js

/**
 * 步骤三
 * 管理事件(行为)
 */
// 引入 状态(类型),用于提交到mutations
import * as types from './types'
 
// 导出
export default {
  // 保存 请求参数 approvalHistoryParams为上面的"action名"
  approvalHistoryParams: ({commit}, res) => {
    // 此处是触发mutation的 STORE_MOVIE_ID为"mutation名"
    commit(types.APPROVAL_HISTORY_PARAMS, res);
  }
}

(4)mutations.js

/**
 * 步骤四
 * 突变(处理状态改变)
 */
import {
  APPROVAL_HISTORY_PARAMS // 审批历史参数
} from './types'
 
// 引入 getters
import getters from './getters'
 
// 定义、初始化数据
const state = {
  approvalHistoryParams:{}
}
 
// 定义 mutations
const mutations = {
  // 匹配actions通过commit传过来的值,并改变state上的属性的值
  // 审批历史页 请求参数
  [APPROVAL_HISTORY_PARAMS](state, res){
    state.approvalHistoryParams = res;   //state.数据名 = data
  }
}
 
// 导出
export default {
  state,
  mutations,
  getters
}

(5)getters.js

/**
 * 步骤五
 * 获取数据
 */
// 导出
export default {
  // 获取 审批历史参数
  approvalHistoryParams: (state) => {
    return state.approvalHistoryParams;
  }
}

3.取值

import { mapGetters } from 'vuex';
 
export default {
  computed: {
    ...mapGetters([//...函数名 使用对象展开运算符将此对象混入到外部对象中
      'approvalHistoryParams'
    ])
  },
  methods: {
    fetchData(){
      console.log(this.approvalHistoryParams.name);
    }
  }
}

注:

dispatch:含有异步操作,例如向后台提交数据,写法: this.$store.dispatch('mutations方法名',值)

commit:同步操作,写法:this.$store.commit('mutations方法名',值)

Vuex(四)--Vue核心概念Mutation

文章目录
1.Vuex(一)--为什么要使用Vuex_小猿猪哥的博客-CSDN博客_为什么要用vuex
2.Vuex(二)--Vue核心概念State_小猿猪哥的博客-CSDN博客
3.Vuex(三)--Vue核心概念Getter_小猿猪哥的博客-CSDN博客
4.Vuex(四)--Vue核心概念Mutation_小猿猪哥的博客-CSDN博客
5.Vuex(五)--Vue核心概念Action_小猿猪哥的博客-CSDN博客
6.Vuex(五)--Vue核心概念Action_小猿猪哥的博客-CSDN博客
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。mutation 必须是同步函数。

不带载荷
接前面几篇文章的例子,这里我们修改商品价格减半。

store.js

mutations: {
    // 商品价格减半  
    goodsPriceDiscount: state => {
        var goodsPriceDiscount = state.goodsList.map(function(item){
            return {
                price: item.price / 2,
                name: item.name
            }
        })
        state.goodsList = goodsPriceDiscount;
    }
}


Page5.vue
要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法。

methods: {
    // 商品价格减半
    discountPrice: function(){
        this.$store.commit('goodsPriceDiscount');
    },
}

这里写图片描述

提交载荷(Payload)
这里修改商品名字。

store.js

// 统一修改商品名字
changeName: (state,payload) => {
    var changeName = state.goodsList.map(function(item){
        return {
            price: item.price,
            name: payload // 接收参数
        }
    })
    state.goodsList = changeName;
}


这里的载荷payload可以是一个对象。

Page6.vue

<div>
    <h2>我是第二个页面</h2>
    <p>
        <input placeholder="请输入新的名字" v-model="input_value" class="input_name" />
        <button v-on:click="changeGoodsName">修改商品名字</button>
    </p>
    <ul class="ul_list page2">
        <li v-for="item in dataList">
            <p class="name">商品:{{item.name}}</p>
            <p class="price">价格:¥{{item.price}}</p>
        </li>
    </ul>
</div>
methods: {
    // 修改商品名字
    changeGoodsName: function(){
        this.$store.commit('changeName',this.input_value);
    },
}


这里的载荷payload就是输入框的值。

效果图这里写图片描述

代码执行过程
上面的Mutation执行过程是:按钮点击–>执行按钮点击事件方法–>执行store.commit–>执行mutations里面对应的方法–>修改state里面对应的数据–>页面渲染。

Mutation 需遵守 Vue 的响应规则
既然 Vuex 的 store 中的状态是响应式的,那么当我们变更状态时,监视状态的 Vue 组件也会自动更新。这也意味着 Vuex 中的 mutation 也需要与使用 Vue 一样遵守一些注意事项:
最好提前在你的 store 中初始化好所有所需属性。
当需要在对象上添加新属性时,你应该
使用 Vue.set(obj, 'newProp', 123), 或者
以新对象替换老对象。例如,利用 stage-3 的对象展开运算符我们可以这样写:

state.obj = { ...state.obj, newProp: 123 }



代码下载地址 GitHub - zhuming3834/Vuex: Vuex使用例子

###

account.js

export default {
  state: {
    user: {
      'data': null
      'success': false,
      'timestamp': 0
    }
  },
  mutations: {
    ...
  },
  actions: {
    ...
  }
}

在另一个组件中获取user数据

export default {
  created () {
    let user = this.$store.state.account.user.data
    console.log(user)
  },
}

注:使用$store的前提是在main.js中初始化Vue时加载store/index.js

main.js

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/index.js'

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import * as getters from './getters'

import account from './modules/account'

Vue.use(Vuex)
const debug = process.env.NODE_ENV !== 'production'

export default new Vuex.Store({
  getters,
  modules: {
    account
  },
  strict: debug
})

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值