开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天点击查看活动详情
今天来简单介绍一下Vuex在使用过程中应该怎么获取或者改变我们在state中声明的变量;
关于这个问题,其实答案有很多种,每个人的习惯都不太一样,而最为正确和最安全的方法我来大概介绍一下,希望可以帮到大家! 1.首先我们来引入vuex,里面的几个常用方法我就不一一介绍了,不会安装VUEX的看下这个文章:vuex的安装,安装好了在根目录新建一个store文件夹,然后新建一个index.js文件,首先在state里面声明一个变量pathName,在mutations中定义一个方法savePath,第一个参数固定state,指向就是state本身,第二个参数是你调用方法时传的参数,看下代码:
// 在store里面的index.js文件写入
import Vue from "vue"
import Vuex from "vuex"
Vue.use(Vuex);
export default new Vuex.Store({
state:{
pathName: "",
},
mutations:{
// 保存当前菜单栏的路径
savePath(state,pathName){
state.pathName = pathName;
},
}
})
2、main.js引用VUEX
// 引入vuex-store
import store from './store/index';
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
3.接下来我们在页面中获取store值或者修改值的方法说一下
// 获取我们定义的变量值pathName
let data = this.$store.state.pathName //这样即可获取到
// 修改变量值两个方法
// 第一个方法,简单的,但不推荐
let name = '修改pathName值'
this.$store.state.pathName = name //这样即可修改
// 第二个方法 推荐安全 容易维护
this.$store.commit('savePath',name)
好了,简单说一下第二个方法吧,commit是自带的修改命名,第一个参数就是你在mutations里面定义的方法名,第二个参数就是你要传过去的参数,至于为什么要使用第二种,因为官方明确说明了,推荐使用第二种,不要直接修改state里面的变量,后期有可能会禁止直接修改,意味着你的页面有可能会集体报错无法修改,三思而后行啊,别为了一时的快乐,给自己制造无穷的麻烦!
第二部,VUEX使用进阶版,VUEX模块化,适合有一定基础的人阅读:
上述方法中我们把所有东西都写在一个文件中了,这样数据多的时候,耦合度太高,也不便于维护,而且mutations也不能解决异步问题,这里就介绍另一种方式以及actions,这是间接触发mutations方法的一种 " 中间商 ",而且它可以执行异步操作,避免用户去直接操作state
1、state.js :保存所有数据模块化,以对象的方式导出,简单点可以理解为声明了很多个变量,变量以对象的形式,里面有存了很多键值对
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);
};
这里有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)
});
- 保存数据
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中定义的变量
使用的时候,可以直接通过this.变量名拿到,例如本例中的 this.DbSource,我们可以把它赋给我们自定义的变量,也可以直接使用
值的注意的是,避免和data中自己定义的其他变量的名字冲突
至此,我们就完成了vuex的保存以及获取数据,希望对你有所帮助。
当然,我们需要把一vuex中的一组数据过滤,其他组件都共用过滤后的数据,这种情况大家可能会用到getters,这里我就不多赘述了,有兴趣的小伙伴可以自己了解一下。
附上vuex的运行过程,官网的图片:组件派发任务到actions,actions触发mutations中的方法,然后mutations来改变state中的数据,数据变更后响应推送给组件,组件重新渲染