Vue学习29_Vue中Devtools的安装以及vuex的几个核心概念

Vue状态管理的属性

在使用vue时,vue为我们提供了一个浏览器插件Devtools,用于跟踪vue的操作,为我们使用vue进行开发时提供了极大的便利,安装方式有两种:一种是在谷歌浏览器的网上商店进行安装,点击浏览器右上角的菜单,更多工具,拓展程序,进去里面进行安装,我在安装时遇到了一个问题就是谷歌的网上商店进不去,所以这里采用另一种安装方式:
附安装教程:https://blog.csdn.net/yizufengdou/article/details/103985709
在最后一步拖拽时可能会提无法使用拖拽进行安装,这里可以点击右上角的开发者模式开关,就可以解决;
安装完成之后,浏览器会出现这样的内容:
在这里插入图片描述

  1. mutations:可以在mutations属性添加一些方法,方法必须传入一个参数state,这个参数的state就是对应vuex中state对象,因此当需要对state对象中的数据进行操作时,可以通过state.变量名的形式进行操作:
    示例代码:为mutations添加两种方法,increment和decrement
import Vue from 'vue'
import Vuex from 'vuex'

// 1.安装插件
Vue.use(Vuex)


// 2.创建对象
const store = new Vuex.Store({
  state: {
    counter: 1000
  },
  mutations: {
    // 必须传入一个参数state,state对应state对象
    increment(state) {
      state.counter++
    },
    decrement(state) {
      state.counter--
    },
  },
  actions: {

  },
  getters: {

  },
  modules: {

  }
})
// 3.导出对象
export default store

示例代码:

import Vue from 'vue'
import Vuex from 'vuex'
// 1.安装插件
Vue.use(Vuex)
// 2.创建对象
const store = new Vuex.Store({
  state: {
    counter: 1000
  },
  mutations: {
    // 必须传入一个参数state,state对应state对象
    increment(state) {
      state.counter++
    },
    decrement(state) {
      state.counter--
    },
  },
  actions: {
  },
  getters: {
  },
  modules: {
  }
})
// 3.导出对象
export default store

运行结果:
在这里插入图片描述
有时候我们也需要对mutations传入一些参数,因此我们可以在传参时,传入一个参数,并且在提交commit时将该参数传递过去:
App.vue

    addCounter(counter) {
      this.$store.commit("addCount", counter);
    },

vuex:

    addCount(state, counter) {
      state.counter += counter;
    }

运行结果
在这里插入图片描述
特殊的提交风格:

    addCounter(counter) {
      // 1.普通的提交风格
      // this.$store.commit("addCount", counter);
      // 2.特殊的提交风格
      this.$store.commit({
        type: "addCount",
        counter,
      });
    },

在vuex中接受的对象将会是一个对象

在mutations中,最好不要进行异步操作
示例代码:以setTimeout为例,进行异步操作,修改info对象的值:
App.vue

    setTimeout() {
      this.$store.commit(SETTIMEOUT);
    },

vuex:

    [SETTIMEOUT](state) {
      setTimeout(() => {
        state.info.name = "小张"
      }, 3000)
    }

运行结果:初始状态时,两者之间值一样
在这里插入图片描述
异步请求修改info信息:三秒钟过后,界面值修改,而控制台的Devtools显示值未修改:可能在项目开发过程中给人造成困扰
在这里插入图片描述
2. state:单一状态树, 用于存放共享状态信息
3. getters的基本使用:相当于计算属性,用于对数据进行处理后展示
示例代码:

import Vue from 'vue'
import Vuex from 'vuex'

// 1.安装插件
Vue.use(Vuex)


// 2.创建对象
const store = new Vuex.Store({
  //相当于data
  state: {
    counter: 1000
  },
  //类似于方法
  mutations: {
    // 必须传入一个参数state,state对应state对象
    increment(state) {
      state.counter++
    },
    decrement(state) {
      state.counter--
    },
  },
  //进行异步操作
  actions: {

  },
  //getters类似于计算属性
  getters: {
    powerCounter(state) {
      return state.counter * state.counter
    }
  },
  modules: {

  }
})

// 3.导出对象
export default store

在App组件中引用:

<template>
  <div id="app">
    <h2>{{ message }}</h2>
    <h3>{{ $store.state.counter }}</h3>
    <button @click="add">+</button>
    <button @click="sub">-</button>
    <hello-vuex></hello-vuex>

    <h3>{{ $store.getters.powerCounter }}</h3>
  </div>
</template>

<script>
import HelloVuex from "./components/HelloVuex";

export default {
  name: "App",
  components: {
    HelloVuex,
  },
  data() {
    return {
      message: "我是APP组件",
    };
  },
  methods: {
    add() {
      // 通过this.$store.commit提交
      this.$store.commit("increment");
    },
    sub() {
      this.$store.commit("decrement");
    },
  },
};
</script>

<style>
</style>

运行结果:
在这里插入图片描述
示例代码:对vuex对应的学生数组对象进行筛选,筛选出年龄大于20的学生:
方法一:使用计算属性
vuex:

import Vue from 'vue'
import Vuex from 'vuex'
// 1.安装插件
Vue.use(Vuex)
// 2.创建对象
const store = new Vuex.Store({
  //相当于data
  state: {
    counter: 1000,
    students: [{
        id: 1,
        name: "张三",
        age: 24
      },
      {
        id: 2,
        name: "李四",
        age: 22
      },
      {
        id: 3,
        name: "王五",
        age: 18
      },
      {
        id: 4,
        name: "赵六",
        age: 20
      },
      {
        id: 5,
        name: "马七",
        age: 15
      },
      {
        id: 6,
        name: "刘八",
        age: 24
      },
    ]
  },
  //类似于方法
  mutations: {
    // 必须传入一个参数state,state对应state对象
    increment(state) {
      state.counter++
    },
    decrement(state) {
      state.counter--
    },
  },
  //进行异步操作
  actions: {

  },
  //getters类似于计算属性
  getters: {
    powerCounter(state) {
      return state.counter * state.counter
    },
    }
  },
  modules: {

  }
})

// 3.导出对象
export default store

App.vue:

<template>
  <div id="app">
    <h2>{{ message }}</h2>
    <h3>{{ $store.state.counter }}</h3>
    <button @click="add">+</button>
    <button @click="sub">-</button>
    <hello-vuex></hello-vuex>

    <h3>{{ $store.getters.powerCounter }}</h3>
    <p>{{ filterAge }}</p>
  </div>
</template>

<script>
import HelloVuex from "./components/HelloVuex";

export default {
  name: "App",
  components: {
    HelloVuex,
  },
  data() {
    return {
      message: "我是APP组件",
    };
  },
  computed: {
    filterAge() {
      return this.$store.state.students.filter((student) => {
        return student.age > 20;
      });
    },
  },
  methods: {
    add() {
      // 通过this.$store.commit提交
      this.$store.commit("increment");
    },
    sub() {
      this.$store.commit("decrement");
    },
  },
};
</script>

<style>
</style>

运行结果:
在这里插入图片描述
但是这样有个弊端就是当你在其他组件中也要使用到这一个筛选时,则需要再次复制粘贴,在其他组件的计算属性在添加,所以最好的解决方法就是在vuex中的getters中定义一个方法:
方法二:
vuex:

import Vue from 'vue'
import Vuex from 'vuex'

// 1.安装插件
Vue.use(Vuex)
// 2.创建对象
const store = new Vuex.Store({
  //相当于data
  state: {
    counter: 1000,
    students: [{
        id: 1,
        name: "张三",
        age: 24
      },
      {
        id: 2,
        name: "李四",
        age: 22
      },
      {
        id: 3,
        name: "王五",
        age: 18
      },
      {
        id: 4,
        name: "赵六",
        age: 20
      },
      {
        id: 5,
        name: "马七",
        age: 15
      },
      {
        id: 6,
        name: "刘八",
        age: 24
      },
    ]
  },
  //类似于方法
  mutations: {
    // 必须传入一个参数state,state对应state对象
    increment(state) {
      state.counter++
    },
    decrement(state) {
      state.counter--
    },
  },
  //进行异步操作
  actions: {

  },
  //getters类似于计算属性
  getters: {
    powerCounter(state) {
      return state.counter * state.counter
    },
    filterAge(state) {
      return state.students.filter((student) => {
        return student.age > 20;
      });
    }
  },
  modules: {

  }
})

// 3.导出对象
export default store

运行结果:效果与上面定义计算属性的结果相同,其他组件在使用时不需要重复定义
在这里插入图片描述
在getters中,不仅可以传递一个参数state,也可以床底两个参数state和getters,其中getters就是我们所定义的getters中的方法
示例代码:统计年龄大于20的学生人数:

import Vue from 'vue'
import Vuex from 'vuex'

// 1.安装插件
Vue.use(Vuex)


// 2.创建对象
const store = new Vuex.Store({
  //相当于data
  state: {
    counter: 1000,
    students: [{
        id: 1,
        name: "张三",
        age: 24
      },
      {
        id: 2,
        name: "李四",
        age: 22
      },
      {
        id: 3,
        name: "王五",
        age: 18
      },
      {
        id: 4,
        name: "赵六",
        age: 20
      },
      {
        id: 5,
        name: "马七",
        age: 15
      },
      {
        id: 6,
        name: "刘八",
        age: 24
      },
    ]
  },
  //类似于方法
  mutations: {
    // 必须传入一个参数state,state对应state对象
    increment(state) {
      state.counter++
    },
    decrement(state) {
      state.counter--
    },
  },
  //进行异步操作
  actions: {

  },
  //getters类似于计算属性
  getters: {
    powerCounter(state) {
      return state.counter * state.counter
    },
    filterAge(state) {
      return state.students.filter((student) => {
        return student.age > 20;
      });
    },
    filterAgeLength(state, getters) {
      return getters.filterAge.length
    }
  },
  modules: {

  }
})

// 3.导出对象
export default store

运行结果:
在这里插入图片描述
有时候我们也需要自定义一个参数传递进去,比如上述例子中的年龄,有时候我们需要定义一个参数,来获取年龄大于这个参数的学生信息并且返回,但getters中的方法有一个参数时,表示state对象,有两个参数的时候,第二个参数表示getters对象:
示例代码:

    // 自定义变量,获取年龄大于该参数的学生信息
    filterAgeStu(state) {
      return function (age) {
        return state.students.filter(stu => stu.age >= age)
      }
    }

运行结果:
在这里插入图片描述

  1. actions:进行异步操作:
    当我们需要执行异步操作时,如果在mutations里面执行,就会遇到上面那种情况,浏览器确实更新过去了,但是控制台并没有更新,因此,假如要执行异步操作时,必须将异步操作放入到actions里面执行:
    示例代码
    App.vue
    setTimeout() {
      // this.$store.commit(SETTIMEOUT);
      this.$store.dispatch('aSetTimeout')
    },

vuex的mutations:

    [SETTIMEOUT](state) {
      state.info.name = "小张"
      // 不建议这样使用
      // setTimeout(() => {
      //   state.info.name = "小张"
      // }, 3000)
    }

vuex的actions:

    [SETTIMEOUT](state) {
      state.info.name = "小张"
      // 不建议这样使用
      // setTimeout(() => {
      //   state.info.name = "小张"
      // }, 3000)
    }

当然payload也可以是一个对象:可以在里面定义多个内容

    setTimeout() {
      // this.$store.commit(SETTIMEOUT);
      // this.$store.dispatch('aSetTimeout','我是payload')
      // 传入的payload也可以是一个对象
      this.$store.dispatch("aSetTimeout", {
        message: "hello zyt",
        success: () => {
          console.log("执行函数");
        },
      });
    },

当要回调时:

  actions: {
    aSetTimeout(context, payload) {
      setTimeout(() => {
        context.commit(SETTIMEOUT)
        console.log(payload.message);
        payload.success()
      }, 3000)
    }
  },

运行结果
在这里插入图片描述
上面的代码看起来可能不够优雅:可以使用Promise:

    aSetTimeout(context, payload) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          context.commit(SETTIMEOUT)
          console.log(payload);
          resolve()
        }, 3000)
      })
    }
  1. modules:当数据太多时,单一状态树就会显得十分的臃肿,为了解决这一问题,我们可以在modules中定义不同的模块:
  modules: {
    a: {
      state: {},
      getters: {},
      mutations: {},
      actions: {}
    },
    b: {
      state: {},
      getters: {},
      mutations: {},
      actions: {}
    }

  }

模块中也可以定义state、actions、mutations以及getters:
当我们在组件中需要使用到自己定义的模块的state数据时:

    <p>使用moduleA的state:{{ $store.state.modulesA.name }}</p>

运行结果
在这里插入图片描述
在模块中使用mutations

    changeName() {
      this.$store.commit("changeName", "李四");
    },
    changeName() {
      this.$store.commit("changeName", "李四");
    },

运行结果
在这里插入图片描述
在模块中使用getters

  getters: {
    fullName(state) {
      return state.name + '他爸爸'
    }
  },
    <p>使用moduleA的getters:{{ $store.getters.fullName }}</p>

运行结果
在这里插入图片描述
在模块中使用actions

  actions: {
    updateMa(context) {
      setTimeout(() => {
          context.commit('changeName', '王五')
        },1000)
    }
  },
    updateMa() {
      this.$store.dispatch("updateMa");
    },

运行结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值