Use of vue3+ts vuex

1、state

The way of writing state has changed. The way of writing state in the new version is similar to the way of writing data in vue2. It is a function that returns an object instead of an ordinary object. Since it is written in ts, the state created must have a type.

import { createStore } from "vuex";

//一定要有类型
interface States {
  count: number;
}

// 创建一个新的 store 实例
const store = createStore<States>({
  state() {
    return {
      count: 0,
    };
  },
});

export default store;

1.1 Use in components

In the component, the state data in vuex must be used. The home page component imports the store file, and then store.state.xxx (data name) can obtain the data.

import store from "@/store";
onMounted(() => {
  console.log(store.state.count);
});

2、mutations

Mutations are also used to change the data in the state, and it is a synchronous operation. Mutations must be used to change the data in the state. The first parameter of the function in mutations receives a state, so that the data in the state can be changed. The second parameter is also called the load, which means you can pass in additional parameters when using it. If there are more than one, you can pass in an object.

import { createStore } from "vuex";

//一定要有类型
interface States {
  count: number;
}

// 创建一个新的 store 实例
const store = createStore<States>({
  state() {
    return {
      count: 0,
    };
  },
 mutations:{
   increment(state:any,value:number):void{
      state.count+=value;
   }
 }

});

export default store;

2.1 Use in components

When using mutations in a component to change the data in the state, you must use commit to submit an application, using the format: store.commit ("defined function name", passed in parameters). Note that mutations can only perform synchronous operations, not asynchronous operations! ! !

import store from "@/store";
onMounted(() => {
 //括号里面的名称对应的是想触发的mutations里面函数的名称,后面是参数,这样就会触发store里面的mutations的increment函数。
  store.commit("increment",1)
});

3、actions

As before, actions are responsible for asynchronously changing state data, but it cannot change it directly. Instead, it submits a mutation and triggers the mutation to change the state data. The Action function accepts a context object with the same methods and properties as the store instance, so you can call context.commit to submit a mutation, or obtain state through context.state. The second parameter is also a load, which is an additional parameter.

import { createStore } from "vuex";

//一定要有类型
interface States {
  count: number;
}

// 创建一个新的 store 实例
const store = createStore<States>({
  state() {
    return {
      count: 0,
    };
  },
 mutations:{
   increment(state:any,value:number):void{
      state.count+=value;
   }
 }
 actions:{
  //这个名字可以随便起,和上面一样也没关系。函数里面进行了commit mutations,提交了mutations里面的increment,触发了increment这个函数,把 
    额外的参数传进去,mutations里面的increment负责更改state的count。
   incrementAction(context:any,value:number){
      context.commit("increment",value)
   }
 }
//官网给出一种解构的写法,因为context和store一样有相同的方法和属性,所以也有commit,把commit解构出来 {commit} 就变成了官网的那种写法

});

export default store;

3.1 Use in components

Note that because actions must be asynchronous operations, they must be asynchronous when used. For example, click a button to increase the state count by 1, and use dispatch to trigger actions.

<template>
  <div class="home">
    <el-button type="primary" round @click="onSubmit">Primary</el-button>
  </div>
</template>
import store from "@/store";
const onSubmit = () => {
  store.dispatch("incrementAction", 1);
};

4、getters

Sometimes we need to derive some state from the state in the store, such as filtering and counting the list: if multiple components need to use this property, we either copy this function, or extract it to a shared function and then use it in multiple places Import it - not ideal either way. Vuex allows us to define "getters" in the store (which can be thought of as computed properties of the store).

import { createStore } from "vuex";

//一定要有类型
interface States {
  count: number;
  todo:any[];
}

// 创建一个新的 store 实例
const store = createStore<States>({
  state() {
    return {
      count: 0,
      todo:[{age:2},{age:3},{age:4}]
    };
  },
  getters:{
    getArray:(state:any)=>{
      return state.todo.filter((item:any)=>item.age>=3);
    }
  }

});

export default store;

4.1 Use in components

Directly store.state.getArray can get the filtered data

5、modules

If there is too much content in the store, we can divide it into multiple modules according to functional modules, each of which has the same state, mutations and other data as the large store. If the namespace is not enabled and the small module and the large store have the same function name, then when other components call it, the same function name will be called, and the calling method is the same as before. If the function is very complex and there is a lot of data, it is recommended to enable the namespace.

5.1、namespaced

It must be noted that it is namespaced, with d at the end. I have been missing the letter d before, and always reported an error that type cannot be found. I have been looking for the reason for a long time!!! To implement a
user module, the following code structure is:


The index file under the store contains large modules, the modules folder contains small modules, and the state folder contains the module state type.

index.ts below store:

import { createStore } from "vuex";
import OtherType from "./states/index";
import user from "./modules/user";

interface CommonState {
  name: string;
  age: number;
  count: number;
}
type states = CommonState & OtherType;

// 创建一个新的 store 实例
const store = createStore<states>({
  state() {
    return {
      count: 0,
      name: "张三",
      age: 10,
    };
  },
  mutations: {
    increment(state) {
      state.count++;
    },
  },
  actions: {
    increment({ commit }: any, value: number) {
      commit("increment", value);
    },
  },
  modules: {
    user,
  },
});

export default store;

user.ts under modules:

import UserState from "../states/userType";

const user = {
  namespaced: true,
  state: (): UserState => ({
    name1: "李四",
    age: 10,
    todo: [{ age: 1 }, { age: 3 }, { age: 4 }],
  }),
  mutations: {
    changeName(state: any, value: string): void {
      state.name1 = value;
      console.log(state.name1);
    },
  },
  actions: {
    changeName({ commit }: any, value: string): void {
      commit("changeName", value);
    },
  },
  getters: {
    getArray: (state: any) => {
      return state.todo.filter((itme: any) => itme.age >= 3);
    },
  },
};

export default user;

userType.ts under state:

interface TodoType {
  age: number;
}
export default interface UserState {
  name1: string;
  age: number;
  todo?: TodoType[];
  aa?: boolean;
}

index.ts:

import UserState from "./userType";

export default interface OtherType {
  user?: UserState;
}

After the submodule opens the namespace, to use the submodule method, you only need to add the module name in front of the method. The module name above is user. If I use the changeName function, it is store.commit("user/changeName",'123') store.dispatch("user/changeName",'123'). To access data in the submodule state, store.state.user.name1
also has many parameters for submodules and main modules. For details, see the official website.

6. Combined API

The store can be accessed in the setup hook function by calling the useStore function.

<script lang="ts" setup>
import { useStore } from 'vuex'
   const store = useStore()
</script>

In order to access state and getters, computed references need to be created to preserve responsiveness, which is equivalent to creating computed properties in an optional API.
To use mutation and action, you only need to call the commit and dispatch functions in the setup hook function.

7、InjectionKey

When useStore is used normally, the data taken out is of type any. If the data you want to take out is typed, you can use InjectionKey. For specific usage methods, see the official website, vuex chapter useStore combined function type declaration. But if you use the method I mentioned above to directly import the store.index file, in this case it is a typed import store from '../store/index'

 

Guess you like

Origin blog.csdn.net/a2367994141/article/details/130623492