一、Vuex
Vues是一个转为Vue.js应用程序开发的状态管理模式
官网:https://next.vuex.vuejs.org/zh/
主要功能:
1、Vuex可以实现vue不同组件之间的状态共享(解决了不同组件之间的数据共享)
2、可以实现组件里面数据的持久化
1.0 Vuex的几个核心概念
- State : 定义数据
- Getters : 计算属性
- Mutations : 定义方法
- Actions : 异步
- Modules :合并多个创建的store
1.1 安装
npm install vuex@next --save
yard add vuex@next --save
1.2 State Mutations
使用步骤
-
在src下创建vuex文件夹,并在里面创建store.js文件
-
在main.ts 里进行挂载
-
在各组件里面进行调用
创建store.js
import {createStore} from 'vuex';
const store = createStore({
// 定义数据 调用数据:this.$store.state.count; 标签里直接使用$store.state.count
state() {
return {
count: 1
}
},
// 定义方法 调用方法:this.$store.commit("incCount")
mutations: {
incCount(state) {
// 使state里的数据count++
state.count++
},
// 接收参数
setCount(state, num) {
state.count = num
}
}
});
export default store;
main.ts挂载
import {createApp} from 'vue'
import App from './App.vue'
// 引入配置好的路由
import router from "@/routes";
import store from "./vuex/store.js"
// 老写法
// createApp(App).mount('#app');
const app = createApp(App);
// 挂载路由
app.use(router);
// 挂载vuex
app.use(store);
app.mount('#app');
组件里使用
<template>
<h1>Home组件 --{{num}} --- {{$store.state.count}}</h1>
<button @click="incCount">执行vuex里的方法incCount</button>
<br>
<button @click="setCount">执行vuex里的方法setCount,并进行传值</button>
</template>
<script>
import {defineComponent} from 'vue';
export default defineComponent({
name: "Home",
methods: {
incCount() {
// 调store里的incCount方法
this.$store.commit("incCount")
},
setCount() {
// 调store里的setCount方法,并进行传参
this.$store.commit("setCount", 20);
}
},
computed: {
num() {
// 获取store里的stage的count值
return this.$store.state.count;
}
}
})
</script>
<style lang="scss" scoped>
</style>
1.3 使用mapState
映射state里的数据,方便组件使用
store.js
import {createStore} from 'vuex';
const store = createStore({
// 定义数据
state() {
return {
count: 1,
list: ["马总", "刘总", "李总"]
}
},
});
export default store;
组件中使用
<template>
<ul>
<!--此时这里可以使用mapState映射好的数据-->
<li v-for="(item, index) in list" :key="index">{{item}}</li>
</ul>
</template>
<script>
import {defineComponent} from 'vue';
import {mapState} from 'vuex'
export default defineComponent({
name: "Home",
computed: {
num() {
// 获取store里的stage的count值
return this.$store.state.count;
},
// 第一种方法(更直接,注意,名字和stage里的名字要保持一直)
// ...mapState([
// "count",
// "list"
// ])
// 第二种方法,起别名
...mapState({
count: (state) => state.count,
list: (state) => state.list,
})
}
})
</script>
<style lang="scss" scoped>
</style>
1.4 Getters
store.js
import {createStore} from 'vuex';
const store = createStore({
// 定义数据 调用数据:this.$store.state.count;
state() {
return {
count: 1,
msg: "你好Vue"
}
},
// 类似于computed属性,计算属性 调用:this.$store.getters.reverseMsg
getters: {
reverseMsg(state) {
return state.msg.split("").reverse().join("")
},
num(state) {
return state.count + 10;
}
}
});
export default store;
组件中使用
<template>
<h1>User组件</h1>
{{reverseMsg}} <br>
{{num}}
</template>
<script>
import {defineComponent} from 'vue';
export default defineComponent({
name: "User",
computed: {
reverseMsg() {
// 调用vuex里的getters
return this.$store.getters.reverseMsg
},
num(){
return this.$store.getters.num
}
}
})
</script>
<style lang="scss" scoped>
</style>
1.5 使用mapGetters
组件中使用
<template>
<h1>User组件</h1>
{{reverseMsg}} <br>
{{num}}
</template>
<script>
import {defineComponent} from 'vue';
import {mapGetters} from 'vuex';
export default defineComponent({
name: "User",
computed: {
// 第一种方法
// ...mapGetters([
// "reverseMsg",
// "num"
// ])
// 第二种方法
...mapGetters({
reverseMsg: "reverseMsg",
num: "num"
})
}
})
</script>
<style lang="scss" scoped>
</style>
1.6 Actions
store.js
import {createStore} from 'vuex';
const store = createStore({
// 定义数据 调用数据:this.$store.state.count;
state() {
return {
count: 1,
list: ["马总", "刘总", "李总"],
msg: "你好Vue"
}
},
// 定义方法 调用方法:this.$store.commit("incCount")
mutations: {
incCount(state) {
// 使state里的数据count++
state.count++
},
// 接收参数
setCount(state, num) {
state.count = num
},
setMsg(state, msg) {
state.msg = msg;
}
},
// 执行mutations里的方法 异步操作放在actions里,调用: this.$store.dispatch("incCount")
actions: {
incCount(context) {
context.commit("incCount"); // 执行mutations里的incCount方法
},
setMsg({commit}, msg) {
setTimeout(() => {
commit("setMsg", msg); // 执行mutations里的setMsg方法
}, 1000)
}
}
});
export default store;
组件中使用
<template>
<h1>News组件</h1>
<button @click="incCunt">调用Actions incCount</button>
<br>
<button @click="setMsg">调用Actions setMsg</button>
</template>
<!-- 设置语言为ts -->
<script>
import {defineComponent} from 'vue'
export default defineComponent({
name: "News",
methods: {
incCunt() {
this.$store.dispatch("incCount")
},
setMsg() {
this.$store.dispatch("setMsg", "修改后的Msg")
}
}
})
</script>
<style scoped>
</style>
1.7 modules
store.js
import {createStore} from 'vuex';
import newsStore from './newsStore';
import userStore from "@/vuex/userStore";
const store = createStore({
modules: {
// 调用state里的值:this.$store.state.user.count
"user": userStore,
"news": newsStore
}
});
export default store;
userStore.js
let userStore = {
// 定义数据 调用数据:this.$store.state.count;
state() {
return {
count: 1,
list: ["马总", "刘总", "李总"],
msg: "你好Vue"
}
},
// 定义方法 调用方法:this.$store.commit("incCount")
mutations: {
incCount(state) {
// 使state里的数据count++
state.count++
},
// 接收参数
setCount(state, num) {
state.count = num
},
setMsg(state, msg) {
state.msg = msg;
}
},
// 类似于computed属性 调用:this.$store.getters.reverseMsg
getters: {
reverseMsg(state) {
return state.msg.split("").reverse().join("")
},
num(state) {
return state.count + 10;
}
},
// 执行mutations里的方法 异步操作放在actions里,调用: this.$store.dispatch("incCount")
actions: {
incCount(context) {
context.commit("incCount"); // 执行mutations里的incCount方法
},
setMsg({commit}, msg) {
setTimeout(() => {
commit("setMsg", msg); // 执行mutations里的setMsg方法
}, 1000)
}
}
};
export default userStore;
newsStore.js
let newsStore = {
// 定义数据 调用数据:this.$store.state.count;
state() {
return {
list: ["新闻1", "新闻2", "新闻3"],
count: 100
}
},
mutations: {
incCount(state) {
state.count++;
}
}
};
export default newsStore;
组件中使用
<template>
用户:<h1>Home组件 --- {{userCount}}</h1>
新闻:<h1>Home组件 --- {{newsCount}}</h1>
<button @click="incCount">调用module里incCount方法</button>
</template>
<script>
import {defineComponent} from 'vue';
export default defineComponent({
name: "Home",
methods: {
incCount() {
// 如果modules里的两个子module都有方法incCount,那么都会生效
this.$store.commit("incCount");
}
},
computed: {
userCount() {
// 获取stage中的user里的count值
return this.$store.state.user.count;
},
newsCount() {
// 获取stage中的news里的count值
return this.$store.state.news.count;
}
}
})
</script>
<style lang="scss" scoped>
</style>
二、Vuex结合composition API
store.js
import {createStore} from 'vuex';
const store = createStore({
// 定义数据 调用数据:this.$store.state.count;
state() {
return {
count: 1,
list: ["马总", "刘总", "李总"],
msg: "你好Vue"
}
},
// 定义方法 调用方法:this.$store.commit("incCount")
mutations: {
incCount(state) {
// 使state里的数据count++
state.count++
},
// 接收参数
setCount(state, num) {
state.count = num
},
setMsg(state, msg) {
state.msg = msg;
}
},
// 类似于computed属性 调用:this.$store.getters.reverseMsg
getters: {
reverseMsg(state) {
return state.msg.split("").reverse().join("")
},
num(state) {
return state.count + 10;
}
},
// 执行mutations里的方法 异步操作放在actions里,调用: this.$store.dispatch("incCount")
actions: {
incCount(context) {
context.commit("incCount"); // 执行mutations里的incCount方法
},
setMsg({commit}, msg) {
setTimeout(() => {
commit("setMsg", msg); // 执行mutations里的setMsg方法
}, 1000)
}
}
});
export default store;
组件中使用
<template>
<h1>Home组件 --- {{count}}</h1>
调用getters的reverseMsg属性:{{reverseMsg}} <br>
<button @click="incCount">调用mutations的incCount方法</button>
</template>
<script>
import {defineComponent, computed} from 'vue';
import {useStore} from 'vuex';
export default defineComponent({
name: "Home",
setup() {
// 获取store
const store = useStore();
// 获取stage里的值
let count = computed(() => {
return store.state.count;
});
// 定义方法
let incCount = () => {
// 调用mutations里的方法
store.commit("incCount")
};
let reverseMsg = computed(() => {
// 调用getters里的方法
return store.getters.reverseMsg
});
return {count, incCount, reverseMsg}
}
})
</script>
<style lang="scss" scoped>
</style>
三、Vues集成Typescript
store.js改为store.ts
import {ComponentCustomProperties} from 'vue';
import {Store, createStore} from 'vuex';
// 配置vue+ts的项目里面使用vuex
declare module '@vue/runtime-core' {
// declare your own store states
interface State { // 下面的state必须和该stage数据类型保持一致
count: number,
list: string[],
msg: string
}
// provide typings for `this.$store`
interface ComponentCustomProperties {
$store: Store<State>
}
}
const store = createStore({
state() {
return {
count: 1,
list: ["马总", "刘总", "李总"],
msg: "你好Vue"
}
},
// 定义方法 调用方法:this.$store.commit("incCount")
mutations: {
incCount(state: any) {
// 使state里的数据count++
state.count++
},
// 接收参数
setCount(state: any, num) {
state.count = num
},
setMsg(state, msg) {
state.msg = msg;
}
},
// 类似于computed属性 调用:this.$store.getters.reverseMsg
getters: {
reverseMsg(state: any) {
return state.msg.split("").reverse().join("")
},
num(state: any) {
return state.count + 10;
}
},
// 执行mutations里的方法 异步操作放在actions里,调用: this.$store.dispatch("incCount")
actions: {
incCount(context) {
context.commit("incCount"); // 执行mutations里的incCount方法
},
setMsg({commit}, msg) {
setTimeout(() => {
commit("setMsg", msg); // 执行mutations里的setMsg方法
}, 1000)
}
}
});
export default store;
组件中使用
// 和上面的用法一摸一样
<template>
<h1>User组件 --- {{msg}}</h1>
</template>
<script lang="ts">
import {defineComponent} from 'vue';
export default defineComponent({
name: "User",
computed: {
msg(): string {
return this.$store.state.msg;
}
}
})
</script>
<style lang="scss" scoped>
</style>