前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vuex的实战使用

Vuex的实战使用

作者头像
何处锦绣不灰堆
发布2020-05-28 23:02:11
8090
发布2020-05-28 23:02:11
举报
文章被收录于专栏:农历七月廿一农历七月廿一

vuex的实战使用

什么是vuex

说白了就是一个可以全局管理状态的东西,用官方的话说是它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化,说人话就是可以时刻监听一个值的状态改变,同时项目里面别的组件也可以使用这个变量。做出相应的处理。

安装
  • 这个是万年不变的,没什么好说的。直接在项目里面运行下面这行代码
代码语言:javascript
复制
npm install vuex --save
我的业务场景

首先说一下业务场景,不然看代码是没有意义的,毕竟代码是为了解决业务的问题,我的业务是需要做一个机器的管理项目,那么这个机器有很多台,例如机器1、机器2等,那么想管理就需要将所有的机器先拿到,然后根据需要切换想设置的机器,view显示对应的机器的配置信息,需求是很明确的,我语言表达能力不行,直接看图。

在这里插入图片描述
在这里插入图片描述

这里简单的解释一下,有人说,这个不是很简单嘛,直接将切换的函数写到select的控件里面,直接点击切换的函数的时候直接给后端对应的uuid,拿到值就可以了,是的,如果只有这一个页面是可以的,但是仔细看布局,select组件是在一个公共组件里面的,你选择的时候你的uuid是不可以直接给到当前页面的,即时给到他,别的配置怎么办呢?而且我们要做的是切换的时候直接整个项目里面的uuid全部改掉,然后重新渲染整个数据,才是合理的解决方案。说一下我开始的想法,我开始是准备使用缓存做,每次用户切换的时候我都将最新的uuid放到缓存里面,但是有一个问题解决不了就是在别的页面怎么实时监听这个值改变了呢?所以,使用vuex是一个比较合理的解决方案,看代码

使用
  • 新建一个store.js
引入
  • 在store.js里面直接将下面的代码复制到里面
  • 声明一个您需要监听的变量(store.js)
代码语言:javascript
复制
/**
 * 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
})
页面使用
  • 首先我们子啊公共组件也就是展示select组件的地方将切换事件处理一下
代码语言:javascript
复制
       /**
       * @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)
      },
  • 把引入组件的代码也贴上来吧,这样好理解
代码语言:javascript
复制
<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>
  • 这个时候下面的页面怎么接收这个值做出相应的改变呢?
代码语言:javascript
复制
    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)
        })
      }
    },
  • 我在想你们是不是心里一万句cnm飘过,写那么多做什么?装逼吗?其实不是的,是我在看别人的博客的时候发现一个问题,就是很多人贴代码的时候因为贴的是一部分,导致很多人摸不着头脑,也不知道每一个方法是怎么传递的,我不想我的博客别人看了以后也有这样的疑问,所以才整个直接贴出来,当然我会做出详细的解释。

解释一下上面的代码:首先我们在页面加载的时候也就是created的阶段将最新的uuid也就是store里面的全局变量的值拿到,有人说你拿到, 为什么还要写下面的,那么问题就来了,如果用户在当前页面直接切换了机器的uuid,那么他没有刷新页面,也没有切换页面,这个时候created是不会执行的,是不是,那么最新的uuid怎么更新呢?你即使监听了但是由于createrd不执行,导致的问题就是你监听的值一直没有变化,所以我们需要将页面里面的uuid变化时刻监听,所以我们需要在computed里面接收最新的uuid,然后我们监听这个里面的值,只要改变,就做出相应的改变,这样就满足了我们的需求,

  • 问题1:为什么使用computed不直接使用watch?

有人看到以后就会觉得我们直接监听这个值不行吗?我们这里要明白的是watch是只可以监听data里面声明的变量或者对象,除此之外是监听不到的,而computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理。

  • 问题2:为什么使用缓存?

这里使用缓存的目的是为了你第一次进来的时候,如果用户什么都不切换,不执行change_machine函数的话,那么我们请求接口的参数是空的,所以我们需要默认一个值,你可以直接在store里面默认,也可以我在第一次进来的时候直接判断是不是存在store的值,没有的话就用我默认的缓存里面的值。

  • 问题3: 为什么created里面已经拿到了,还要写监听函数?

这个问题可能有人会问,但是其实很简单,因为用户不刷新页面的时候created是不执行的,那么我们就拿不到最新的uuid进行数据的更新,所以要写监听的函数。

  • 问题4: 为什么使用this.$store.dispatch?

我们这里使用是根据官方文档来的,你可以直接使用commit或者什么也不用,直接this.$store.state.machine_uuid_flag也是可以的,但是我们改变了uuid,那么就要重置一下store里面的原始值,所以这里需要接收我们改变的值,也就是用户选择了别的机器的时候用的值。如果我们不需要重置原始值的话,可以直接定义一个全局变量,然后直接

  • this.$store.state.machine_uuid_flag(这里格式乱了)就可以了,但是这样的业务场景应该不多。毕竟我们定义了就是为了改变它从而我们可以监听这个变化的值。

总结

更新(2019-11-07)
更新内容:main.js配置信息

上面说了我们直接使用的时候是没有问题的,但是呢,如果你的main.js里面没有引入store的话。会直接报错,报错信息如下:

代码语言:javascript
复制
Cannot read property 'dispatch' of ?developer/article/1634675/undefined

这句话什么意思呢?很简单就是说无法读取未定义的“dispatch”属性,我们vue里面只要是提示无法读取什么为定义的一些东西的时候,基本不用找什么原因, 无法就是两种,第一是页面上的没有在data里面完成定义,第二种无非就是配置文件里面没有定义,这个很明显就是我们的main.js没有完成相应的配置,配置很简单: 在我们的main.js里面引入一下store就可以了

代码语言:javascript
复制
import store from './store.js'

在vue的引入的地方将store加进去

代码语言:javascript
复制
new Vue({
  router:router,
  store,
  components: { App },
  el: '#app',
  render: h => h(App)
});

这样就可以了,基本完成了我们的引入,就不会报错了。

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • vuex的实战使用
    • 总结
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
    http://www.vxiaotou.com