vuex 之 概念和作用解析

vuex作用

vuex就是为了提供这样一个在多个组件间共享状态的插件

 

vuex管理什么状态呢?

例如:用户的登录状态,用户名称,头像,地理位置信息等

例如商品的收藏,购物中的物品等等

这些状态信息,可以放在统一的地方,对它进行保存和管理,而且还是响应式

 

安装vuex包

1
npm install vuex -S

  

简单案例演示

App.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
  <div id="app">
    <HelloWorld></HelloWorld>
  </div>
</template>
 
<script>
import HelloWorld from "./components/HelloWorld";
export default {
  name: "App",
  components: {
    HelloWorld,
  },
};
</script>
 
<style>
</style>

main.js

1
2
3
4
5
6
7
8
9
10
import Vue from "vue";
import App from "./App.vue";
import store from "./store/index.js";
 
Vue.config.productionTip = false;
 
new Vue({
  render: (h) => h(App),
  store,
}).$mount("#app");

components/HelloWorld.vue

<template>
  <div>
    <h2>这是一个HelloWorld</h2>
    <h2>{{ $store.state.counter }}</h2>
    <button @click="add">+</button>
    <button @click="sub">-</button>
    <button @click="addCount(8)">跳数</button>
    <div>-------------getter----------------</div>
    <h2>{{ $store.getters.powerCounter }}</h2>
    <div>-------modules---------</div>
    <h2>{{ $store.state.a.name }}</h2>
    <button @click="updateName"></button>
    <h2>{{ $store.getters.fullName }}</h2>
  </div>
</template>
<script>
import { INCREMENT } from "../store/mutations-type";
export default {
  data() {
    return {};
  },
  methods: {
    add() {
      this.$store.commit(INCREMENT);
    },
    sub() {
      this.$store.commit("decrement");
    },

    addCount(count) {
      //简单方式提交封装
      this.$store.commit("incrementCount", count);
      //特殊的提交封装
      this.$store.commit({
        type: "incrementCount",
        count,
      });
    },
    addStudent() {
      let stu = { id: 160, name: "kkk", age: 18 };
      this.$state.commit("addStudent", stu);
    },
    updateInfo() {
      //   this.$state.dispatch("aUpdateInfo", {
      //     msg: "我是携带的信息",
      //     success() {
      //       console.log("里面已经完成了");
      //     },
      //   });
      this.$state.dispatch("aUpdateInfo").then((res) => {
        console.log(res);
      });
    },
    updateName() {
      this.$store.commit("updateName", "李四");
    },
  },
};
</script>
<style lang=""></style>

/store/index.js

import Vue from "vue";
import Vx from "vuex";
import { INCREMENT } from "./mutations-type";

//1安装插件
Vue.use(Vx);
const moduleA = {
  state: {
    name: "zhangsan",
    count: 15,
  },
  mutations: {
    updateName(state, payload) {
      state.name = payload;
    },
  },
  getters: {
    fullName(state) {
      return state.name + "111";
    },
    fullName3(state, getter, rootState) {
      //rootState 是指Vx.Store对象中的state对象
      return getter.fullName + state.name + rootState.counter;
    },
  },
  actions: {
    aupdateName(context) {
     console.log(context);
      setTimeout(() => {
        //只能调用moduleA中的mutations
        context.commit("updateName");
      }, 1000);
    },
    incrementRootSum({ state, commit, rootState }) {
      if ((state.count + rootState.counter) % 2 === 1) {
        commit("updateName");
      }
    },
  },
};
const moduleB = {
  state: {},
  mutations: {},
};
//2创建对象
const store = new Vx.Store({
  state: {
    counter: 10000,
    students: [
      { id: 110, name: "why", age: 18 },
      { id: 120, name: "kobe", age: 19 },
      { id: 130, name: "james", age: 20 },
      { id: 140, name: "curry", age: 10 },
    ],
    info: {
      name: "张三",
      age: 18,
    },
  },
  mutations: {
    //方法
    [INCREMENT](state) {
      state.counter++;
    },
    decrement(state) {
      state.counter--;
    },

    incrementCount(state, count) {
      state.counter += count;
      //当是普通方式时 count就是普通的数字 8
      //当是特殊方式时  count 是对象,所以推荐使用 payload来取名,通过payload.count来获取
    },
    addStudent(state, stu) {
      state.students.push(stu);
    },
    test(state, payload) {
      //多参数时,可以将payload对为对象,名字可以修改
      state.counter = payload.counter;
    },
    updateInfo(state) {
      //不能在这里进行异步操作
      //   setTimeout(() => {
      //     state.info.name = "王五";
      //   }, 1000);
      state.counter = "";
    },
  },

  getters: {
    powerCounter(state) {
      return state.counter * state.counter;
    },
    more20stu(state) {
      return state.students.filter((s) => s.age > 20);
    },
    more20stuLength(state, getters) {
      return getters.more20stu.length;
    },
    moreAgeStu(state) {
      return function(age) {
        return state.students.filter((s) => s.age > age);
      };
    },
  },
  actions: {
    //context是上下文
    aUpdateInfo(context, payload) {
      //   setTimeout(() => {
      //     context.commit("updateInfo");
      //     console.log(payload.msg);
      //     payload.success();
      //   }, 1000);

      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log(payload.msg);
          context.commit("updateInfo");
          let err = "";
          if (err === "err") {
            resolve("11");
          } else {
            reject("11");
          }
        }, 1000);
      });
    },
  },
  modules: {
    a: moduleA,
    b: moduleB,
  },
});

//3导出store独享
export default store;

mutations-type.js

1
export const INCREMENT = "increment";

   

Vuex核心概念

(1)State   状态树

  1>vuex提出使用单一状态树,什么是单一状态树?

     英文名称是Single Source of Truth  也可以翻译为单一数据源

(2)Getters  

   1> 类似于计算属性

       如上面的简单案例代码中的使用

   2>getters作为参数和传递参数

      如上面的简单案例代码中的使用

(3)Mutations  状态更新

    1>官方:修改state的值肯定是在mutations中进行

       参数被称为是mutation的载荷(Payload)

    2>mutations 简单使用(不带参数)

        如上面的简单案例代码中的使用

   3>mutations 携带参数

       如上面的简单案例代码中的使用

   4>若参数不是一个呢? 

    有时候需要用到多个参数,那么就会以对象的形式传递,也就是payload是一个对象,这样就可以从对象获取

    5>mutation提交风格

      上面是通过commit进行提交是一种普通的方式

      Vue还提供了另外一种风格,他是一个包含type属性的对象

    6>mutation响应规则  

     vuex的store是响应式的,当state中的数据改变时,vue组件会更新

     (1).提前在store中初始化好所需的属性

     (2).当给state中的对象添加新属性时,使用下面的方式

                   方式一:使用Vue.set(obj,'newProp',123)

                  方式二:用新对象给旧对象重新赋值

    

1
2
3
4
5
6
7
8
9
10
11
在state中,实际上,这里的info各种属性在定义时,就会自动挂载到响应式系统中,只要而响应式系统会监听这些属性的变化,当属性发生变化是,就会通知所有用到该属性的页面进行刷新
info:{
    name:'张三',
    age:18   
}
 
在mutation中
updateInfo(state){
   // state.info.name ='李四' 
   //state.info['address'] = '中国' //不报错,info虽然添加了该属性,但是界面并不会发生刷新,因为需要提前在store中初始化才行   Vue.set(state.info,'address','洛杉矶')   //delete state.info.name   //没发生任何变化,info没有变化  Vue.delete(state.info,'name') 
}

 7>mutations的类型常量

        如上面的简单案例代码中的使用(就是创建 mutations-type.js来处理)  

 

   8>mutation同步函数

      devtools可以帮助扑捉mutation的快照

      若是异步操作,那么devtools将不能很好的追踪这个操作什么时候会被完成,通过铜鼓vue工具看时,里面的state没有变化,实际页面已经发生变化了

(4)Actions

   1>基本定义

       actions类似于mutation,但是是用来替代mutation进行异步操作的,可以解决mutation同步函数问题

  2>基本使用

    如上面的简单案例代码中的使用(dispatch部分)

(5)Modules 

    1>module是模块的意思,为什么要用到模块呢?

     1.因为使用单一状态树,也就意味着很多模块都会交给vuex来管理

     2.当应用变得非常复杂时,store对象就会变得相当臃肿

     3.为了解决该问题,vuex允许我们将store分割成模块,而每个模块拥有自己的state,mutations,actions,getters等

    如上面的简单案例代码中的使用(moduleA部分)

 

合理的项目结构

 

 

  

  

posted @   zmztyas  阅读(279)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2018-02-28 oracle 之 定时任务,存储过程和游标等语法案例
点击右上角即可分享
微信分享提示