说白了就是一个可以全局管理状态的东西,用官方的话说是它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化,说人话就是可以时刻监听一个值的状态改变,同时项目里面别的组件也可以使用这个变量。做出相应的处理。
npm install vuex --save
首先说一下业务场景,不然看代码是没有意义的,毕竟代码是为了解决业务的问题,我的业务是需要做一个机器的管理项目,那么这个机器有很多台,例如机器1、机器2等,那么想管理就需要将所有的机器先拿到,然后根据需要切换想设置的机器,view显示对应的机器的配置信息,需求是很明确的,我语言表达能力不行,直接看图。
这里简单的解释一下,有人说,这个不是很简单嘛,直接将切换的函数写到select的控件里面,直接点击切换的函数的时候直接给后端对应的uuid,拿到值就可以了,是的,如果只有这一个页面是可以的,但是仔细看布局,select组件是在一个公共组件里面的,你选择的时候你的uuid是不可以直接给到当前页面的,即时给到他,别的配置怎么办呢?而且我们要做的是切换的时候直接整个项目里面的uuid全部改掉,然后重新渲染整个数据,才是合理的解决方案。说一下我开始的想法,我开始是准备使用缓存做,每次用户切换的时候我都将最新的uuid放到缓存里面,但是有一个问题解决不了就是在别的页面怎么实时监听这个值改变了呢?所以,使用vuex是一个比较合理的解决方案,看代码
/**
* created by ClearLove
* @aim 标题栏中需要更改自助机的uuid,所有的返回值都需要是该自助机下的数据,所以需要声明一个全局的可以监听uuid的变化
* @params machine_uuid_flag 全局uuid
*/
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
machine_uuid_flag: '', //机器uuid
}
const getters = {
getters_mac_uuid() {
return state.machine_uuid_flag
}
};
const mutations = {
mutations_mac_uuid(state, mac_uuid) {
state.machine_uuid_flag = mac_uuid
}
};
const actions = {
actions_mac_uuid(state, mac_uuid) {
state.commit('mutations_mac_uuid', mac_uuid)
}
};
export default new Vuex.Store({
state,
getters,
mutations,
actions
})
/**
* @change_machine 更改自助机
*/
change_machine(machine_mac_uuid) {
this.machine_id = machine_mac_uuid;
// 这里是将最新的更换的机器的uuid,将store里面的uuid更换掉,这样才可以保证别的地方使用这个uuid的地方也会同时改变
this.$store.dispatch('actions_mac_uuid',machine_mac_uuid);
sessionStorage.setItem('machine_mac_uuid', this.machine_id)
},
<el-select v-model="machine_name" placeholder="自助机列表" size="mini" @change="change_machine">
<el-option
v-for="item in machine_list"
:key="item.mac_uuid"
:label="item.machine_name"
:value="item.mac_uuid">
</el-option>
</el-select>
created: function () {
this.machine_mac_uuid = sessionStorage.getItem('machine_mac_uuid');
this.machine_name = sessionStorage.getItem('machine_name');
//将最新的uuid拿到
this.update_mac_uuid = this.$store.state.machine_uuid_flag;
this.get_settings_info()
},
/**
* 接收store的改变的值
*/
computed:{
machine_uuid_flag(){
//将接收到的最新的uuid return出去
return this.$store.state.machine_uuid_flag
}
},
/**
* 监听该store里面值的变化
*/
watch: {
//监听这个值是不是接收到,改变的话直接重新执行获取机器的方法
machine_uuid_flag: function (newvalue , oldvalue) {
this.update_mac_uuid = newvalue; //将最新的值传递给更新的对象
this.get_settings_info();
}
},
methods: {
/**
* @get_settings_info 获取某一台自助机的详情
*/
get_settings_info() {
this.$axios({
method: 'post',
url: this.api.api_zzj_9006 + 'manager_back/get_main_info/',
data: {
machine_uuid: this.update_mac_uuid ? this.update_mac_uuid : this.machine_mac_uuid
}
}).then((res) => {
let machine = res.data.data;
this.machine_name = machine.machine_name;
this.machine_mac_uuid = machine.machine_mac_uuid;
this.location = machine.location;
this.mac_uuid = machine.mac_uuid;
this.machine_uuid = machine.machine_uuid;
this.mac_uuid_two = machine.mac_uuid_two;
this.expire_data = machine.expire_data;
this.environmental_state_dec = machine.environmental_state_dec;
this.machine_type_des = machine.machine_type_des;
this.system_version = machine.system_version;
}).catch((err) => {
console.error(err)
})
}
},
解释一下上面的代码:首先我们在页面加载的时候也就是created的阶段将最新的uuid也就是store里面的全局变量的值拿到,有人说你拿到, 为什么还要写下面的,那么问题就来了,如果用户在当前页面直接切换了机器的uuid,那么他没有刷新页面,也没有切换页面,这个时候created是不会执行的,是不是,那么最新的uuid怎么更新呢?你即使监听了但是由于createrd不执行,导致的问题就是你监听的值一直没有变化,所以我们需要将页面里面的uuid变化时刻监听,所以我们需要在computed里面接收最新的uuid,然后我们监听这个里面的值,只要改变,就做出相应的改变,这样就满足了我们的需求,
有人看到以后就会觉得我们直接监听这个值不行吗?我们这里要明白的是watch是只可以监听data里面声明的变量或者对象,除此之外是监听不到的,而computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理。
这里使用缓存的目的是为了你第一次进来的时候,如果用户什么都不切换,不执行change_machine函数的话,那么我们请求接口的参数是空的,所以我们需要默认一个值,你可以直接在store里面默认,也可以我在第一次进来的时候直接判断是不是存在store的值,没有的话就用我默认的缓存里面的值。
这个问题可能有人会问,但是其实很简单,因为用户不刷新页面的时候created是不执行的,那么我们就拿不到最新的uuid进行数据的更新,所以要写监听的函数。
我们这里使用是根据官方文档来的,你可以直接使用commit或者什么也不用,直接this.$store.state.machine_uuid_flag也是可以的,但是我们改变了uuid,那么就要重置一下store里面的原始值,所以这里需要接收我们改变的值,也就是用户选择了别的机器的时候用的值。如果我们不需要重置原始值的话,可以直接定义一个全局变量,然后直接
上面说了我们直接使用的时候是没有问题的,但是呢,如果你的main.js里面没有引入store的话。会直接报错,报错信息如下:
Cannot read property 'dispatch' of undefined
这句话什么意思呢?很简单就是说无法读取未定义的“dispatch”属性,我们vue里面只要是提示无法读取什么为定义的一些东西的时候,基本不用找什么原因, 无法就是两种,第一是页面上的没有在data里面完成定义,第二种无非就是配置文件里面没有定义,这个很明显就是我们的main.js没有完成相应的配置,配置很简单: 在我们的main.js里面引入一下store就可以了
import store from './store.js'
在vue的引入的地方将store加进去
new Vue({
router:router,
store,
components: { App },
el: '#app',
render: h => h(App)
});
这样就可以了,基本完成了我们的引入,就不会报错了。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有