首页 > 其他分享 >Vuex

Vuex

时间:2022-09-28 00:11:27浏览次数:49  
标签:counter getters mutations state Vuex payload store

Vuex概念

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。(响应式的状态管理模式 多个组件之间共享状态)

安装

npm install vuex --save

配置

新建store文件->index.js,进行如下配置,在mian.js中进行引入

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

Vue.use(Vuex)

export default new Vuex.Store({
  //数据,相当于data
  state: {

  },
  getters: {

  },
  //里面定义方法,操作state方发
  mutations: {

  },
  // 操作异步操作mutation
  actions: {

  },
  modules: {

  },
})

在 main.js 文件中挂载使用

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})

核心概念

state

一个store来管理全部的状态
单一数据源

在vuex中state中定义数据,可以在任何组件中进行调用

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

    <hello-vuex :counter="counter"></hello-vuex>
  </div>
</template>

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

export default {
  name: "App",
  components: {
    HelloVuex,
  },
  data() {
    return {
      message: "我是app组件",
      // counter: 0,
    };
  },
};
</script>

<template>
  <div>
    <h2>{{$store.state.counter}}</h2>
  </div>
</template>

<script>
export default {
  name: "HelloVuex",
  // props: {
  //   counter: Number,
  // },
};
</script>

main.js中

import store from "./store";
new Vue({
  el: "#app",
  store,
  render: h => h(App)
});

import Vue from "vue";
import Vuex from "vuex";

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

// 2. 创建对象
const store = new Vuex.Store({
  state: {
    counter: 1000
  },

  mutations: {},
  actions: {},
  getters: {},
  modules: {}
});

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

Mutations

mutations携带参数

mutations状态更新

Vuex的store状态更新唯一方式:提交Mutations

Mutations包含:

  • 字符串的事件类型
  • 一个回调函数,该回调函数的第一个参数就是state
<button @click="addCount(5)">+5</button>
<button @click="addCount(10)">+10</button>
<button @click="addStudent">添加学生</button>

<script>
  methods: {
    addCount(count) {
      // console.log("addCount...");
      // payload: 负载
      this.$store.commit("incrementCount", count);
    },
    addStudent() {
      // payload是一个对象
      const stu = { id: 114, name: "lisi", age: 22 };
      this.$store.commit("addStudent", stu);
    },
  },
};
</script>
  incrementCount(state, count) {
      state.counter += count;
    },
    addStudent(state, stu) {
      state.students.push(stu);
    }

提交风格

使用一个对象来封装
mutations里面最好用一个payload来封装

  incrementCount(state, payload) {
      // console.log(count); // 第二种方式打印: Object { type: "incrementCount", count: 5 }
      state.counter += payload.count;
    },
// 1. 普通的提交封装
      // this.$store.commit("incrementCount", count);

      // 2. 特殊的提交封装
      this.$store.commit({
        type: "incrementCount",
        count,
      });

响应规则

一开始在state中被定义的值,都会被放在响应式系统中,当属性发生变化时,会通知所有用到的地方发生更新

新的属性,是不会被监听的

updateInfo(state) {
      // state.info.name = "w"; // 是响应式的 旧属性
      // state.info["address"] = "Guangzhou"; // 新的属性 虽然在store中被改变了 但是在界面上不是响应式的

    // 必须要使用Vue的方法
      // 参考之前的数组里面的操作
      // Vue.set(state.info, "address", "Guangzhou"); // 这样才是响应式的
      // delete state.info.age; // 也不是响应式的
      Vue.delete(state.info, "age"); //是响应式的
    }

类型常量

store下新建一个文件mutations-types.js

export const INCREMENT = "increment";
// index.js
import { INCREMENT } from "./mutations-types";
[INCREMENT](state) {
      state.counter++;
    },

// App.vue
import { INCREMENT } from "./store/mutations-types";
addition() {
      this.$store.commit(INCREMENT);
    },

actions

mutations里面进行异步操作,在devtools里面不会更新

使用actions替代mutations

使用actions嵌套使用mutations

// App.vue
updateInfo() {
      // this.$store.commit("updateInfo");
      // this.$store.dispatch("aUpdateInfo", "我是payload"); // 可以传递参数
      // this.$store.dispatch("aUpdateInfo", () => {
      //   console.log("里面的操作已经完成了");
      // });
      // this.$store.dispatch("aUpdateInfo", {
      //   message: "我是携带的信息",
      //   success: () => {
      //     console.log("里面已经完成了");
      //   },
      // });
      this.$store
        .dispatch("aUpdateInfo", "我是携带的信息") // index.js中返回的Promise返回到这里
        // 通过actions做了中转,再返回到这里
        .then((res) => {
          console.log("里面完成了提交");
          console.log(res);
        });
    },
        
// index.js
        actions: {
    // context上下文 理解为store
    // 必须通过mutations来操作
    // aUpdateInfo(context, payload) {
    //   setTimeout(() => {
    //     context.commit("updateInfo");
    //     // console.log(payload);
    //     // payload();
    //     console.log(payload.message);
    //     payload.success();
    //   }, 1000);
    // }
    aUpdateInfo(context, payload) {
      // 这里的Promise返回到App.vue的方法中 可以进行then操作
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          context.commit("updateInfo");
          console.log(payload);
          // payload();
          // console.log(payload.message);
          resolve("11111");
        }, 1000);
      });
    }
  },

getters

类似于vue中的computed,进行缓存,对于Store中的数据进行加工处理形成新的数据

<template>
  <div id="app">
    <h2>------------App内容--------------</h2>
    <h2>{{message}}</h2>
    <h2>{{$store.state.counter}}</h2>
    <button @click="addition">+</button>
    <button @click="subtraction">-</button>
    <h2>---------------App内容:getters相关信息------------------</h2>
    <h2>{{$store.getters.powerCounter}}</h2>
    <h2>{{$store.getters.more20stu}}</h2>
    <h2>{{$store.getters.more20stuLength}}</h2>
    <h2>{{$store.getters.moreAgestu(18)}}</h2>

    <h2>-----------------------Hello Vuex内容---------------------------------</h2>
    <hello-vuex />
  </div>
</template>
const store = new Vuex.Store({
  state: {
    counter: 1000,
    students: [
      { id: 110, name: "why", age: 18 },
      { id: 111, name: "kobe", age: 28 },
      { id: 112, name: "james", age: 19 },
      { id: 113, name: "curry", age: 39 }
    ]
  },

  mutations: {
    // 方法
    increment(state) {
      state.counter++;
    },
    decrement(state) {
      state.counter--;
    }
  },
  actions: {},
  getters: {
    powerCounter(state) {
      return state.counter * state.counter;
    },
    more20stu(state) {
      return state.students.filter(s => s.age > 20);
    },
    // 调用其他的getters
    more20stuLength(state, getters) {
      return getters.more20stu.length;
    },
    // 传入自定义的参数
    moreAgestu(state) {
      // return function(age) {
      //   return state.students.filter(s => s.age > age);
      // };
      return age => {
        return state.students.filter(s => s.age > age);
      };
    }
  },
  modules: {}
});

modules

当遇见大型项目时,数据量大,store就会显得很臃肿

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割

const moduleA = {
  state: {
    name: "zhangsan"
  },
  mutations: {
    // 不能和store的mutations的函数名重复 优先在下面找
    updateName(state, payload) {
      state.name = payload;
    }
  },
  actions: {
    // 这里的context指的是 模块中的 mutations
      console.log(context); //这里的context可以拿到很多东西的
    aUpdateName(context) {
      setTimeout(() => {
        context.commit("updateName", "wangwu");
      }, 1000);
    }
  },
  getters: {
    fullname(state) {
      return state.name + 111;
    },
    // 嵌套调用getters
    fullname2(state, getters) {
      return getters.fullname + "222";
    },
    // 引用根state中的counter 添加一个参数rootState
    fullname3(state, getters, rootState) {
      return getters.fullname2 + rootState.counter;
    }
  }
};

const moduleB = {
  state: {},
  mutations: {},
  actions: {},
  getters: {}
};


// 可以进行抽离
  modules: {
    a: moduleA,
    b: moduleB
  }

// App.vue
<h2>----------App内容:modules里面的内容--------------</h2>
    <!-- 模块 a 添加到了 state 中,所以需要先拿到a 在引用name -->
    <h2>{{$store.state.a.name}}</h2>
    <button @click="updateName">修改名字</button>
    <!-- 也是可以直接调用 -->
    <h2>{{$store.getters.fullname}}</h2>
    <h2>{{$store.getters.fullname2}}</h2>
    <h2>{{$store.getters.fullname3}}</h2>
    <button @click="asyncUpdateName">异步修改名字</button>

updateName() {
      this.$store.commit("updateName", "lisi");
    },
    asyncUpdateName() {
      this.$store.dispatch("aUpdateName");
    },

标签:counter,getters,mutations,state,Vuex,payload,store
From: https://www.cnblogs.com/uuujh/p/16736475.html

相关文章

  • vuex从后端获取data
    //store.jsimport{createStore}from"vuex";importaxiosfrom"axios";conststore=createStore({state(){return{merchants:[]......
  • vue3的vuex简单配置
    vuex目录文件内容【store/index.js】import{createStore}from"vuex";importmodulesfrom"./modules";constsetupStore=(app)=>{letstoreOptions......
  • 封装加载动画组件,利用slot标签与vuex实现
     实现效果: 加载时:  加载完成时;   实现代码:通过vuex传入一个布尔值loading控制加载动画显示与否,动画关闭时,通过slot标签显示本组件中包含的其他内容组......
  • vuex4的简单使用
    安装vuexcnpminstallvuex@next--save官网地址是https://vuex.vuejs.org/zh/guide/#%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84-storevuex中的常用5个模块vuex模块......
  • Vuex 学习笔记
    组件之间共享数据的方式小范围父向子:v-bind属性绑定简写:子向父:v-on事件绑定简写@兄弟组件之间共享数据:EventBusVuex是实现组件全局状态(数据)管理的一种机制,可......
  • Vuex新一代状态管理 — Pinia
    最近在学习pinia,做了一些笔记,在这里分享一下:https://note.youdao.com/ynoteshare/index.html?id=3bedfc4d66825be097cee904fe311f56&type=note&_time=1663899586848......
  • Vue面试题20:说一说你对Vuex的理解(总结自B站up主‘前端杨村长’视频,仅供自用学习)
    回答范例1(定义):Vuex是一个专为Vue应用开发的状态管理模式+库。它采用集中式存储,管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化;2(必要性):我......
  • Pinia是一个全新的Vue状态管理库,是Vuex的代替者,尤雨溪强势推荐
    Pinia优势Pinia是一个全新的Vue状态管理库,是Vuex的代替者,尤雨溪强势推荐Vue2和Vue3都能支持抛弃传统的Mutation,只有state,getter和action,简化状态管理库......
  • 为什么使用 Pinia(Vuex)
    Pinia定义Pinia(Vuex?)是一个独立于组件的全局状态,每一个组件都可以读取和写入。Pinia有三个重要的概念:state、getters、actions。state等价于组件中的data、getters......
  • vue3中vuex使用实例
    通过脚手架创建项目会自动创建store/index.js1.vuex基本结构import{createStore}from'vuex'exportdefaultcreateStore({//全局的状态初始值state:{},......